You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无SAP GUI DLL时,C#实现SAP GUI自动化的替代方案

在无SAP GUI DLL引用的情况下用C#实现SAP GUI自动化

我已经用Python和Visual Basic成功实现了SAP GUI自动化,但在C#中一直找不到可行方案。我知道C#的实现逻辑应该和VB类似,但开发机上没有SAP GUI DLL,无法直接添加引用。

以下是可正常运行的代码:

Python实现

#-Begin-----------------------------------------------------------------

#-Includes--------------------------------------------------------------
import sys, win32com.client

#-Sub Main--------------------------------------------------------------
def Main():

    SapGuiAuto = win32com.client.GetObject("SAPGUI")
    if not type(SapGuiAuto) == win32com.client.CDispatch:
      return

    application = SapGuiAuto.GetScriptingEngine
    if not type(application) == win32com.client.CDispatch:
      SapGuiAuto = None
      return

    connection = application.Children(0)
    if not type(connection) == win32com.client.CDispatch:
      application = None
      SapGuiAuto = None
      return

    session = connection.Children(1)
    if not type(session) == win32com.client.CDispatch:
      connection = None
      application = None
      SapGuiAuto = None
      return

    #session.findById("wnd[0]").resizeWorkingPane 173, 36, 0
    session.findById("wnd[0]").resizeWorkingPane(173, 36, 0)

Visual Basic实现

方式一:连接已有SAP会话

Sub Main

  Set SapGuiAuto = GetObject("SAPGUI")
  Set Application = SapGuiAuto.GetScriptingEngine
  Set Connection = Application.openConnection("EQ2")
  Set Session = Connection.Children(0)
  Session.ActiveWindow.Iconify()
  Session.findById("wnd[0]/usr/txtRSYST-MANDT").Text = "410"
  Session.findById("wnd[0]/usr/txtRSYST-BNAME").Text = "XYZ"
  Session.findById("wnd[0]/usr/pwdRSYST-BCODE").Text = "Pwd1"
  Session.findById("wnd[0]/usr/txtRSYST-LANGU").Text = "EN" 
  Session.findById("wnd[0]").SendVKey 0 

End Sub

方式二:启动SAP并建立连接

Sub SAP_OpenSessionFromLogon()

  Dim SapGui
  Dim Applic
  Dim connection
  Dim session

  Shell ("C:\Program Files (x86)\SAP\FrontEnd\SAPgui\sapfewcp.exe")

  Set SapGui = GetObject("SAPGUI") 
  Set Applic = SapGui.GetScriptingEngine 
  Set connection = Applic.OpenConnection("QLA - ECC Project One Quality System", True) '<=== 这里需要填写你的连接描述

End Sub

请问:如何在不添加SAP GUI COM DLL引用的情况下,用C#实现上述相同功能?甚至是否可以直接打开相关exe、将窗口置于前台并进行GUI自动化?


解决方案

一、使用COM Late Binding(无需添加DLL引用)

C#中可以通过dynamic类型实现COM对象的延迟绑定,和VB的GetObject逻辑一致,无需提前引用SAP的DLL。

1. 连接已有SAP会话的代码

using System;
using System.Runtime.InteropServices;

class SapGuiAutomation
{
    static void Main()
    {
        try
        {
            // 获取已运行的SAPGUI对象
            dynamic sapGuiAuto = Marshal.GetActiveObject("SAPGUI");
            if (sapGuiAuto == null) return;

            // 获取脚本引擎
            dynamic application = sapGuiAuto.GetScriptingEngine();
            if (application == null)
            {
                Marshal.ReleaseComObject(sapGuiAuto);
                return;
            }

            // 获取第一个连接(可根据实际情况调整索引)
            dynamic connection = application.Children(0);
            if (connection == null)
            {
                Marshal.ReleaseComObject(application);
                Marshal.ReleaseComObject(sapGuiAuto);
                return;
            }

            // 获取会话(索引根据实际情况调整)
            dynamic session = connection.Children(1);
            if (session == null)
            {
                Marshal.ReleaseComObject(connection);
                Marshal.ReleaseComObject(application);
                Marshal.ReleaseComObject(sapGuiAuto);
                return;
            }

            // 执行自动化操作,例如调整工作区大小
            session.findById("wnd[0]").resizeWorkingPane(173, 36, 0);

            // 释放COM对象(避免内存泄漏)
            Marshal.ReleaseComObject(session);
            Marshal.ReleaseComObject(connection);
            Marshal.ReleaseComObject(application);
            Marshal.ReleaseComObject(sapGuiAuto);
        }
        catch (Exception ex)
        {
            Console.WriteLine($"操作失败:{ex.Message}");
        }
    }
}

2. 启动SAP并建立新连接的代码

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;

class SapGuiAutomation
{
    static void Main()
    {
        try
        {
            // 启动SAP GUI客户端
            Process.Start(@"C:\Program Files (x86)\SAP\FrontEnd\SAPgui\sapfewcp.exe");
            // 等待SAP启动完成(时间根据实际情况调整)
            Thread.Sleep(5000);

            // 获取SAPGUI对象
            dynamic sapGuiAuto = Marshal.GetActiveObject("SAPGUI");
            if (sapGuiAuto == null) return;

            dynamic application = sapGuiAuto.GetScriptingEngine();
            if (application == null)
            {
                Marshal.ReleaseComObject(sapGuiAuto);
                return;
            }

            // 打开指定连接(第二个参数True表示显示登录窗口)
            dynamic connection = application.OpenConnection("QLA - ECC Project One Quality System", true);
            if (connection == null)
            {
                Marshal.ReleaseComObject(application);
                Marshal.ReleaseComObject(sapGuiAuto);
                return;
            }

            // 获取会话并执行登录操作
            dynamic session = connection.Children(0);
            if (session != null)
            {
                session.findById("wnd[0]/usr/txtRSYST-MANDT").Text = "410";
                session.findById("wnd[0]/usr/txtRSYST-BNAME").Text = "XYZ";
                session.findById("wnd[0]/usr/pwdRSYST-BCODE").Text = "Pwd1";
                session.findById("wnd[0]/usr/txtRSYST-LANGU").Text = "EN";
                session.findById("wnd[0]").SendVKey(0); // 发送回车登录

                Marshal.ReleaseComObject(session);
            }

            // 释放COM对象
            Marshal.ReleaseComObject(connection);
            Marshal.ReleaseComObject(application);
            Marshal.ReleaseComObject(sapGuiAuto);
        }
        catch (Exception ex)
        {
            Console.WriteLine($"操作失败:{ex.Message}");
        }
    }
}

二、直接操作窗口的GUI自动化方案

如果不想依赖SAP的COM接口,也可以用Windows API或自动化库实现窗口激活、模拟键鼠操作,但这种方式稳定性较差,容易受窗口布局变化影响:

1. 激活SAP窗口的示例(用Windows API)

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;

class WindowAutomation
{
    [DllImport("user32.dll")]
    private static extern bool SetForegroundWindow(IntPtr hWnd);

    [DllImport("user32.dll")]
    private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

    private const int SW_RESTORE = 9;

    static void Main()
    {
        // 查找SAP窗口进程
        Process[] sapProcesses = Process.GetProcessesByName("saplogon");
        if (sapProcesses.Length > 0)
        {
            IntPtr hWnd = sapProcesses[0].MainWindowHandle;
            // 如果窗口最小化,先还原
            ShowWindow(hWnd, SW_RESTORE);
            // 激活窗口
            SetForegroundWindow(hWnd);
        }
    }
}

注意事项

  • 使用COM延迟绑定时,要确保SAP GUI的脚本功能已开启(在SAP GUI选项中启用脚本支持)。
  • Marshal.ReleaseComObject要正确调用,避免COM对象内存泄漏。
  • 直接模拟键鼠的方式仅适用于简单场景,复杂操作建议优先使用SAP的COM脚本接口。

内容的提问来源于stack exchange,提问作者10101

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 07:05:21