如何启动 COM 服务器?代码在 Python
How do I start a COM server? Code is in Python
我想 运行 Python 代码作为 COM 服务器。最终我想 运行 一个可用的 RTD 服务器 here. But first I want to know what exactly you have to do to getting any COM server running. So let's focus on this example。
class HelloWorld:
_reg_clsid_ = "{7CC9F362-486D-11D1-BB48-0000E838A65F}"
_reg_desc_ = "Python Test COM Server"
_reg_progid_ = "Python.TestServer"
_public_methods_ = ['Hello']
_public_attrs_ = ['softspace', 'noCalls']
_readonly_attrs_ = ['noCalls']
def __init__(self):
self.softspace = 1
self.noCalls = 0
def Hello(self, who):
self.noCalls = self.noCalls + 1
# insert "softspace" number of spaces
return "Hello" + " " * self.softspace + who
if __name__=='__main__':
import win32com.server.register
win32com.server.register.UseCommandLine(HelloWorld)
好的,它的工作方式是没有错误并且服务器已注册,因此它在 HKEY_CLASSES_ROOT 注册表中可用。但是我能用它做什么呢?有人说您必须编译一个实例并拥有一个 .dll 或 .exe 文件。我还需要做什么?
嗯,我运行你的榜样。服务器的注册表项位于:
HKEY_CLASSES_ROOT\WOW6432Node\CLSID\{7CC9F362-486D-11D1-BB48-0000E838A65F}
它有两个子项...一个用于 LocalServer32,一个用于 InProcServer32
我在 Excel 中创建了一个简单的 VBA 宏:
Sub d()
Set obj = CreateObject("Python.TestServer")
MsgBox obj.Hello("joe")
End Sub
宏运行就好了。我的 Excel 版本是 64 位。我 运行 宏,然后在显示消息框时启动任务管理器。我可以在后台看到 pythonw.exe 运行。
我的 python 脚本和你的脚本之间的唯一区别可能是名称,而且我添加了一行要打印以确保我正在执行函数:
if __name__=='__main__':
import win32com.server.register
print("Going to register...")
win32com.server.register.UseCommandLine(HelloWorld)
当我 运行 64 位 csript.exe 测试时,它工作......正如预期的那样......当我 运行 32 位版本时它失败了。
我知道为什么……有点……
InProcServer32
的注册表项是 pythoncom36.dll
那可不行。这是一条不完整的道路。我尝试修改我的 shell 上的路径变量,以将其添加到系统中存在 DLL 的 3 个位置之一,但它没有用。此外,尝试对 InProcServer32 中的路径进行编码。那没用..一直说找不到文件。
我 运行 procmon,然后我观察到它无法加载 vcruntime140.dll。在 python 下找到这些文件所在的目录,并将其添加到我的路径中。它走得更远。如果我足够关心,我可能会尝试更多。最终使用 procmon,我可以找到所有问题。但你可以做到。
我的简单解决方案是将 CLSID 的键 InProcServer32
重命名为 _InProcServer32。这是如何运作的?好吧,系统找不到 InProcServer32
所以它总是使用 LocalServer32
——对于 32 位和 64 位进程。如果您需要进程中的速度,那么您需要通过使用 procmon 来解决问题并坚持不懈,直到您解决所有未找到文件错误等。但是,如果您不需要处理速度,那么使用 LocalServer32 可能会解决问题。
注意事项我使用的是我的雇主限制访问的 Anaconda 发行版,我只能从员工商店安装它。 YMMV.
我想 运行 Python 代码作为 COM 服务器。最终我想 运行 一个可用的 RTD 服务器 here. But first I want to know what exactly you have to do to getting any COM server running. So let's focus on this example。
class HelloWorld:
_reg_clsid_ = "{7CC9F362-486D-11D1-BB48-0000E838A65F}"
_reg_desc_ = "Python Test COM Server"
_reg_progid_ = "Python.TestServer"
_public_methods_ = ['Hello']
_public_attrs_ = ['softspace', 'noCalls']
_readonly_attrs_ = ['noCalls']
def __init__(self):
self.softspace = 1
self.noCalls = 0
def Hello(self, who):
self.noCalls = self.noCalls + 1
# insert "softspace" number of spaces
return "Hello" + " " * self.softspace + who
if __name__=='__main__':
import win32com.server.register
win32com.server.register.UseCommandLine(HelloWorld)
好的,它的工作方式是没有错误并且服务器已注册,因此它在 HKEY_CLASSES_ROOT 注册表中可用。但是我能用它做什么呢?有人说您必须编译一个实例并拥有一个 .dll 或 .exe 文件。我还需要做什么?
嗯,我运行你的榜样。服务器的注册表项位于:
HKEY_CLASSES_ROOT\WOW6432Node\CLSID\{7CC9F362-486D-11D1-BB48-0000E838A65F}
它有两个子项...一个用于 LocalServer32,一个用于 InProcServer32
我在 Excel 中创建了一个简单的 VBA 宏:
Sub d()
Set obj = CreateObject("Python.TestServer")
MsgBox obj.Hello("joe")
End Sub
宏运行就好了。我的 Excel 版本是 64 位。我 运行 宏,然后在显示消息框时启动任务管理器。我可以在后台看到 pythonw.exe 运行。
我的 python 脚本和你的脚本之间的唯一区别可能是名称,而且我添加了一行要打印以确保我正在执行函数:
if __name__=='__main__':
import win32com.server.register
print("Going to register...")
win32com.server.register.UseCommandLine(HelloWorld)
当我 运行 64 位 csript.exe 测试时,它工作......正如预期的那样......当我 运行 32 位版本时它失败了。
我知道为什么……有点……
InProcServer32
的注册表项是 pythoncom36.dll
那可不行。这是一条不完整的道路。我尝试修改我的 shell 上的路径变量,以将其添加到系统中存在 DLL 的 3 个位置之一,但它没有用。此外,尝试对 InProcServer32 中的路径进行编码。那没用..一直说找不到文件。
我 运行 procmon,然后我观察到它无法加载 vcruntime140.dll。在 python 下找到这些文件所在的目录,并将其添加到我的路径中。它走得更远。如果我足够关心,我可能会尝试更多。最终使用 procmon,我可以找到所有问题。但你可以做到。
我的简单解决方案是将 CLSID 的键 InProcServer32
重命名为 _InProcServer32。这是如何运作的?好吧,系统找不到 InProcServer32
所以它总是使用 LocalServer32
——对于 32 位和 64 位进程。如果您需要进程中的速度,那么您需要通过使用 procmon 来解决问题并坚持不懈,直到您解决所有未找到文件错误等。但是,如果您不需要处理速度,那么使用 LocalServer32 可能会解决问题。
注意事项我使用的是我的雇主限制访问的 Anaconda 发行版,我只能从员工商店安装它。 YMMV.