2

I am trying to write a C# program that will automate a user's input into the SAP GUI (currently on version 7400.3.11.3364) using SAP GUI Scripting API. I've done similar things in the past using VBA, but I'm struggling to get it working exactly how I want it to in C#.

My end goal is to have a method that opens SAP GUI (if it isn't already running), returns the GuiApplication object of SAP GUI, and leaves SAP GUI open after my program ends. I currently have it working in VBA, and I believe I had it working correctly in C# on a previous project when we were on SAP GUI version 7.3, but I'm not 100% sure.

Here is the VBA function I use:

Public Function GetSapApp() as GuiApplication
  
  Dim Start as Date

  If GetObject("SAPGUI") Is Nothing Then
    Start = Now()
    Shell "C:\Program Files (x86)\SAP\FrontEnd\SAPgui\saplogon.exe"
    Do Until Not GetObject("SAPGUI") Is Nothing Or Now > (Start + TimeValue("00:01:00"))
      DoEvents
    Loop
  If GetObject("SAPGUI") Is Nothing Then
    MsgBox "Unable to detect SAP Scripting API. Please contact the developer."
  End If
  Set GetSapApp = GetObject("SAPGUI").GetScriptingEngine
End Function

And here are the different C# methods I've found while googling:

  • Below is what I'm currently using (the idea was inspired by this: https://www.codeproject.com/Questions/829500/How-do-I-connect-Csharp-to-SAP-GUI), but there are a couple issues with it. It doesn't seem to detect SAP GUI if it is already open. Also, after my program runs, this SAP GUI isn't detectable by any of our VBA macros.

     private static GuiApplication GetSapApp()
     {
       try
       {
         object SapGuilRot = new CSapROTWrapper().GetROTEntry("SAPGUI");
         return SapGuilRot.GetType().InvokeMember("GetScriptingEngine", System.Reflection.BindingFlags.InvokeMethod, null, SapGuilRot, null) as GuiApplication;
       }
       catch (Exception e)
       {
         try
         {
           string SapPath = "C:\\Program Files (x86)\\SAP\\FrontEnd\\SAPgui\\saplogon.exe";
       if (File.Exists(SapPath))
           {
             System.Diagnostics.Process.Start(SapPath);
             DateTime StartTime = DateTime.Now;
             object SapGuilRot = new CSapROTWrapper().GetROTEntry("SAPGUI");
             while (SapGuilRot == null && 30 >= (DateTime.Now - StartTime).TotalSeconds)
             {
               SapGuilRot = new CSapROTWrapper().GetROTEntry("SAPGUI");
             }
             return SapGuilRot.GetType().InvokeMember("GetScriptingEngine", System.Reflection.BindingFlags.InvokeMethod, null, SapGuilRot, null) as GuiApplication;
           }
           else
           {
             return null;
           }
         }
         catch
         {
           return null;
         }
       }
     }
    
  • Here is another option I've tried (per this answer on another SO post: https://stackoverflow.com/a/14205520/5134861), but it has the same first issue as above (doesn't detect if SAP is currently running), the SAP GUI session that gets opened when you call the OpenConnection method looks different and then closes when my program is done running.

     private static GuiApplication GetSapApp()
     {
       return (GuiApplication)System.Activator.CreateInstance(Type.GetTypeFromProgID("SapGui.ScriptingCtrl.1"));
     }
    
  • And here is the last option I've tried, but I get an ActiveX component can't create object error, despite having verified sapfewse.ocx is registered.

     private static GuiApplication GetSapApp()
     {
       object sap = Microsoft.VisualBasic.Interaction.GetObject("SAPGUI", "");
       return sap.GetType().InvokeMember("GetScriptingEngine", System.Reflection.BindingFlags.InvokeMethod, null, sap, null) as GuiApplication;
     }
    

Any help and/or suggestions would be greatly appreciated.

Thanks in advance!

Sandra Rossi
  • 11,934
  • 5
  • 22
  • 48
Kyle
  • 29
  • 1
  • 7

2 Answers2

0

I've used:

Microsoft.VisualBasic.Interaction.GetObject("SAPGUISERVER", "");
Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
  • Thanks for the suggestion, but when I try this, I get the "Cannot create ActiveX component" error. When I look in my HKCR registry, I'm not seeing that class, so I think I need to register it, but I don't know what file to register. Any ideas? – Kyle May 29 '18 at 12:40
0
SapROTWr.CSapROTWrapper sapROTWrapper1 = new SapROTWr.CSapROTWrapper();
object SapGuilRot1 = sapROTWrapper1.GetROTEntry("SAPGUI");
object engine1 = SapGuilRot1.GetType().InvokeMember("GetScriptingEngine", System.Reflection.BindingFlags.InvokeMethod, null, SapGuilRot1, null);
Suraj Rao
  • 29,388
  • 11
  • 94
  • 103
  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Apr 15 '23 at 14:27