Application Development Blog Posts
Learn and share on deeper, cross technology development topics such as integration and connectivity, automation, cloud extensibility, developing at scale, and security.
cancel
Showing results for 
Search instead for 
Did you mean: 
stefan_schnell
Active Contributor
Almost two years ago I presented here a variant how to use Visual Basic inside ABAP. The same example, but with actualized versions, I presented here. This was the reason to check and enhance the possibilties to use .NET languages inside ABAP.

What are the differences:

  1. Beside the Visual Basic code example I implement also an equivalent C# code example.

  2. The different code parts are now splittet into separate includes. So you can copy and paste your C# or Visual Basic code direct from your local IDE into the ABAP include, without any modifications.

  3. The function to read an include as string is now a method of a local class.

  4. The initialization of the PowerShell frame, via SAPIENS ActiveXPoshV3 library, is now also a method of a local class.

  5. The calls of the .net language methods from ABAP are now very easy and flexible possible from any point of your ABAP code.


At first a small visual impression:



Here now the code, the first code is the include ZCODEINCLUDE which contains the C# code.
//-Begin----------------------------------------------------------------

//-Using--------------------------------------------------------------
using System;
using System.Windows.Forms;

//-Namespaces---------------------------------------------------------
namespace Code {

public class Test {

public static string Hello1() {
return "Hello World!"
}

public string Hello2(string Name) {
return "Hello " + Name + "!"
}

public void Hello3(string Name) {
MessageBox.Show("Hello " + Name)
}

}
}

//-End------------------------------------------------------------------

As you can see, it is exact the same example as the Visual Basic code from the posts ealier.

Now the PowerShell code, to load the class, from the include ZPSINCLUDE:
#-Begin-----------------------------------------------------------------

If (-Not ("Code.Test" -as [type])) {
#Add-Type -TypeDefinition $Code -Language VisualBasic
Add-Type -TypeDefinition $Code -Language CSharp
}
$Code = New-Object Code.Test

#-End-------------------------------------------------------------------

Last but not least the ABAP code:
"-Begin-----------------------------------------------------------------
Program zUseDotNet.

"-TypePools---------------------------------------------------------
Type-Pools OLE2.

"-Constants---------------------------------------------------------
Constants OUTPUT_CONSOLE Type i Value 0.
Constants OUTPUT_WINDOW Type i Value 1.
Constants OUTPUT_BUFFER Type i Value 2.
Constants CrLf(2) Type c Value cl_abap_char_utilities=>cr_lf.

"-Classes-----------------------------------------------------------
Class lcl_PoSh Definition.

Public Section.

Class-Methods Init
Importing i_OutputMode Type i
Returning Value(r_oPS) Type OLE2_OBJECT.

Class-Methods ReadInclAsString
Importing i_InclName Type SOBJ_NAME
Returning Value(r_strIncl) Type String.

EndClass.

Class lcl_PoSh Implementation.

Method Init.

"-Variables---------------------------------------------------
Data lv_Result Type i.

Create Object r_oPS 'SAPIEN.ActiveXPoSHV3'.
If sy-subrc = 0 And r_oPS-Handle > 0 And r_oPS-Type = 'OLE2'.
Call Method Of r_oPS 'Init' = lv_Result Exporting #1 = 0.
If lv_Result = 0.
Call Method Of r_oPS 'IsPowerShellInstalled' = lv_Result.
If lv_Result <> 0.
Set Property Of r_oPS 'OutputMode' = i_OutputMode.
Set Property Of r_oPS 'OutputWidth' = 128.
EndIf.
Else.
Free Object r_oPS.
EndIf.
Else.
Free Object r_oPS.
EndIf.

EndMethod.

Method ReadInclAsstring.

"-Variables---------------------------------------------------
Data lt_TADIR Type TADIR.
Data lt_Incl Type Table Of String.
Data lv_InclLine Type String.
Data lv_retIncl Type String.

"-Main--------------------------------------------------------
Select Single * From TADIR Into lt_TADIR
Where OBJ_NAME = i_InclName.
If sy-subrc = 0.
Read Report i_InclName Into lt_Incl.
If sy-subrc = 0.
Loop At lt_Incl Into lv_InclLine.
lv_retIncl = lv_retIncl && lv_InclLine &&
cl_abap_char_utilities=>cr_lf.
lv_InclLine = ''.
EndLoop.
EndIf.
EndIf.
r_strIncl = lv_retIncl.

EndMethod.

EndClass.

"-Variables---------------------------------------------------------
Data lo_PS Type OLE2_OBJECT.
Data lv_Result Type String.
Data lt_Result Type Table Of String.
Data lv_Code Type String.
Data lv_PSCode Type String.
Data lv_PSCodeExec Type String.
Data lv_strBuf Type String.

"-Main--------------------------------------------------------------
Start-Of-Selection.
lo_PS = lcl_PoSh=>Init( OUTPUT_BUFFER ).
If lo_PS-Handle > 0.

"-Read the dotNET language code from include--------------------
lv_Code = '$Code = @"' && CrLf &&
lcl_PoSh=>ReadInclAsString( 'ZCODEINCLUDE' ) &&
'"@;' && CrLf.

"-Read PowerShell code from include-----------------------------
lv_PSCode = lv_Code && lcl_PoSh=>ReadInclAsString( 'ZPSINCLUDE' ).

"-Call instance method and view message box---------------------
lv_PSCodeExec = lv_PSCode && '$Code.Hello3("Stefan")'.
Call Method Of lo_PS 'Execute' Exporting #1 = lv_PSCodeExec.

"-Call static method and write Hello World into output buffer---
lv_PSCodeExec = lv_PSCode && '[Code.Test]::Hello1()'.
Call Method Of lo_PS 'Execute' Exporting #1 = lv_PSCodeExec.

"-Call instance method and write Hello Stefan into output buffer
lv_PSCodeExec = lv_PSCode && '$Code.Hello2("Stefan")'.
Call Method Of lo_PS 'Execute' Exporting #1 = lv_PSCodeExec.

"-Catch output buffer into a variable and clear output buffer---
Call Method Of lo_PS 'OutputString' = lv_Result.
Call Method Of lo_PS 'ClearOutput'.

"-Write the content of the output buffer------------------------
Split lv_Result At CrLf Into Table lt_Result.
Loop At lt_Result Into lv_strBuf.
Write: / lv_strBuf.
EndLoop.

Free Object lo_PS.

EndIf.

"-End-------------------------------------------------------------------

Let us start an Main comment. At first we initialize the with the method Init the PowerShell environment and set the output buffer as target. The Init method creates an OLE object of SAPIEN.ActiveXPoSHV3, makes some settings and delivers the OLE object. Now we read the .net language code, via the ReadInclAsString method, from the include ZCODEINCLUDE, which contains the C# code. At next we read the PowerShell code from the include ZPSINCLUDE and concatenate it with the .net language code into the variable lv_PSCode. This were the preparations to call now any method from the C# class inside ABAP.

Now we can concatenate lv_PSCode with any possible method call and execute it - here I use the variable lv_PSCodeExec.

Last but not least we read the output buffer into a variable and clear the output buffer. If you need a result from a method call, you must use this procedure direct after the method call.

As you can see, it is very easy to use .NET languages, with all its possibilities of the .net framework, inside ABAP. And if you store the library via BinFile2ABAP on your application server, you can create phantastic solutions without any special requirements to the frontend server - with the exception of the usual standards: Windows, .net framework and PowerShell.
1 Comment