0

I am looking to assign an open, running desktop client of SAP and put it into an instance of SAPFEWSELib.GuiApplication.

All signs point to this:

Marshal.GetActiveObject("SAPGUI");

But it does not work -- 'Invalid class string'

The closest I have come is:

Marshal.GetActiveObject("Sapgui.ScriptingCtrl.1");

Which at least gives me a different error message:

System.Runtime.InteropServices.COMException (0x800401E3): Operation unavailable (Exception from HRESULT: 0x800401E3 (MK_E_UNAVAILABLE))

To be clear, this is the guy I'm trying to capture:

enter image description here

Which when open looks like this:

enter image description here

SAP Client is 32-bit, and my app is also 32-bit.

I would be most grateful for any guidance. I am brand new to SAP.

Hambone
  • 15,600
  • 8
  • 46
  • 69

1 Answers1

0

Please check this out: How do I automate SAP GUI with c#

This is my version:

using SAPFEWSELib;
using SapROTWr;

// Part of the connection detection method
SapROTWrapper = new CSapROTWrapper();
SapGuiROT = SapROTWrapper.GetROTEntry("SAPGUI");
SapApplication = (GuiApplication)SapGuiROT.GetType()
    .InvokeMember("GetScriptingEngine", System.Reflection.BindingFlags.InvokeMethod, null, SapGuiROT, null);
    
if (SapApplication == null)
    throw new ArgumentException($"Could not find SAP GuiApplication from Windows ROT.");

if (SapApplication.Connections.Count == 0)
{
    string connectString = Properties.Settings.Default.SapKirjautuminenYhteys; // Login info from WinForms app
    SapConnection = SapApplication.OpenConnection(connectString, Sync: true);
    SapSession = (GuiSession)SapConnection.Sessions.Item(0);
}
else
{
    // Find SAP connection. If there are multiple, close all but the first one.
    GuiComponentCollection conns = SapApplication.Connections;
    for (int i = 0; i < conns.Count; i++)
    {
        if (i == 0)
        {
            SapConnection = (GuiConnection)conns.ElementAt(0);
        }
        else
        {
            GuiConnection c = (GuiConnection)conns.ElementAt(i);
            c.CloseConnection();
        }
    }
    
    // Check if there are too many sessions/windows open. As there is max limit, we need to make room.
    int cnt = SapConnection.Sessions.Count;
    if (cnt > 3)
    {
        for (int i = 3; i < cnt; i++)
        {
            GuiSession s = (GuiSession)SapConnection.Sessions.ElementAt(3);
            s.SendCommand("/i");
        }
    }
    SapSession = (GuiSession)SapConnection.Sessions.ElementAt(SapConnection.Sessions.Count - 1);
}
Miika
  • 1
  • 1
  • 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 May 01 '23 at 16:31