为什么 win32.com 相同的 GetObject 调用(同一行代码)仅在特定情况下才能在运行对象表中找到“SAPGUI”

Why does the same win32.com GetObject call (same line of code) only in certain circumstances find 'SAPGUI' in the Running Object Table

提问人:Jan_B 提问时间:9/14/2023 最后编辑:Jan_B 更新时间:9/14/2023 访问量:58

问:

在编写通用函数(用于 python 和 Excel vba)以返回可用的 SAP 会话(现有或新)以进行进一步脚本编写时,我在 ROT 中查找对象时遇到了 GetObject 调用的奇怪行为。SAPGUI

  • 打开会话后,函数将按预期运行并返回所需的会话对象
  • 在未打开 SAP 的情况下,函数会打开一个 USING 并返回会话对象sapshut.exe

到目前为止一切顺利,但转折点来了:

  • 通过呼叫创建会话后,不再识别“手动”打开的会话(这意味着:当 jou 打开登录板并从那里开始会话时)sapshcut.exewin32.com.GetObject('SAPGUI')
  • 如果会话未关闭,则在重新运行该函数时会再次识别该会话
  • 如果关闭会话,该函数将打开并识别一个新会话
  • 识别再次“手动”打开的会话的唯一方法是重新启动计算机

这是一个最小的代码片段,它为我重现了这个问题:

from os import system
from win32com.client import GetObject
from pywintypes import com_error
from time import sleep


def open_and_close_shortcut():
    # check if 'SAPGUI' is in Windows Running Object Table (and getting connection object)
    try:
        GetObject('SAPGUI').GetScriptingEngine.Children(0)
    # If not open then open with sapshcut.exe and single sign on (no Logon is opened)
    except com_error:
        system('start sapshcut.exe -system=<SID> -client=<CLI>')  # put in your system and client
        sleep(2)  # tweak the time a little if it is not sufficient
    # get 'SAPGUI' from Windows Running Object Table (and getting connection object)
    finally:
        con = GetObject('SAPGUI').GetScriptingEngine.Children(0)
        # get available session and open TAC MD04
        for session in con.Children:
            if not session.busy:
                session.StartTransaction("MD04")  # change to any TAC you can access
                return


if __name__ == '__main__':
    open_and_close_shortcut()

请注意:我在Excel VBA中尝试了相同的逻辑,并遇到了相同的行为!

对我来说,获得奇怪行为的最快方法是:

  1. 打开 SAP 会话并启动脚本(查看是否打开了 MD04 以确认成功运行)
  2. 关闭 SAP 并重新运行脚本(SAP 应该会弹出,如果事务未执行,则需要更长的值)sleep()
  3. 再次关闭SAP,然后再次手动打开(我使用登录板进行操作)

现在→,即使 SAP 处于打开状态,脚本也应输入 exept 语句,从而导致 SAP 错误/弹出窗口,指出系统已打开

谁能向我解释这种行为以及如何消除它?

附言我通过以编程方式打开登录板并从那里开始会话找到了一种解决方法,该会话确实按预期工作。那么 maby 会话与 logon 和 sapshcut 有区别?!这仍然是神秘的,因为两个会话在某个时候被同一行代码识别......

Python Excel VBA WinAPI SAP-GUI

评论

0赞 Simon Mourier 9/14/2023
GetObject 是 Windows 的 CoGetObject (learn.microsoft.com/en-us/windows/win32/api/objbase/...) 的包装器。除此之外,这完全取决于SAP如何实现其COM服务器,以响应您传递给它的绰号,它不再是Windows,也不是它的API。
0赞 Jan_B 9/14/2023
感谢您的澄清,我从问题中删除了 Windows API!
0赞 IInspectable 9/14/2023
这不是预期的结果。此处正确使用了 winapi 标记。Simon 评论的本质是,系统提供了基础设施,但并没有以其他方式决定所述基础设施的客户端做什么。如果 SAP 决定仅在某些(可能未记录)的情况下在 ROT 中注册对象,那么这是需要让 SAP 支持人员注意的问题。从问题中剥离 winapi 标记并不能使您更接近解决方案。
0赞 Jan_B 9/14/2023
我没有从帖子中删除标签,但确实将问题中的第一句话从...我遇到了 Windows API 的奇怪行为.........我遇到了 GetObject 调用的奇怪行为...
0赞 IInspectable 9/14/2023
哦等等,我误解了编辑加评论。从字面上看,编辑只是将“Windows API”替换为GetObject”。这本身并没有错,但仍然将矛头指向错误的一方。这不是 ROT(或其实现)表现得很有趣。这是 SAP 对 ROT 的使用。

答: 暂无答案