【问题标题】:Why can't I create a COM object in a new thread in Python?为什么我不能在 Python 的新线程中创建 COM 对象?
【发布时间】:2011-03-15 20:41:25
【问题描述】:

我正在尝试在 Python 的新线程中从 dll 创建一个 COM 对象 - 所以我可以在该线程中运行消息泵:

from comtypes.client import CreateObject
import threading

class MessageThread(threading.Thread):

    def __init__(self):
        threading.Thread.__init__(self)
        self.daemon = True

    def run(self):
        print "Thread starting"
        connection = CreateObject("IDMessaging.IDMMFileConnection")
        print "connection created"

a = CreateObject("IDMessaging.IDMMFileConnection")
print "aConnection created"
t = MessageThread()
t.start()

这是我得到的错误跟踪:

aConnection created
Thread starting
>>> Exception in thread Thread-1:
Traceback (most recent call last):
  File "c:\python26\lib\threading.py", line 532, in __bootstrap_inner
    self.run()
  File "fred.py", line 99, in run
    self.connection = CreateObject("IDMessaging.IDMMFileConnection")
  File "c:\python26\lib\site-packages\comtypes\client\__init__.py", line 235, in CreateObject
    obj = comtypes.CoCreateInstance(clsid, clsctx=clsctx, interface=interface)
  File "c:\python26\lib\site-packages\comtypes\__init__.py", line 1145, in CoCreateInstance
    _ole32.CoCreateInstance(byref(clsid), punkouter, clsctx, byref(iid), byref(p))
  File "_ctypes/callproc.c", line 925, in GetResult
WindowsError: [Error -2147221008] CoInitialize has not been called

有什么想法吗?

【问题讨论】:

    标签: python com comtypes python-multithreading


    【解决方案1】:

    您需要在线程上调用CoInitialize()(或CoInitializeEx())才能在该线程上创建 COM 对象。

    from win32com.client.pythoncom import CoInitialize
    CoInitialize()
    

    【讨论】:

      【解决方案2】:

      据我所知(很久以前我用 COM 组件编写了很多程序)你必须在每个线程上调用 CoInitialize如果你的 COM 对象使用 STA。

      http://msdn.microsoft.com/en-us/library/ms678543(VS.85).aspx

      但我不知道如何在 python 中调用该函数。

      这是 MSDN 文档

      http://msdn.microsoft.com/en-us/library/ms678543(VS.85).aspx

      【讨论】:

      • 无论对象使用什么,都需要 CoInitializeEx()。
      • 感谢你们俩...我刚刚完成了,现在我的 ole32.dll 似乎没有从 CoCreateInstance 返回。我正在尝试在启动消息泵之前创建对象 - 可以吗?
      • 知道了...哦...我的 COM DLL 是在 VB6 中实现的,我将它设置为 STA 而不是单元线程...现在一切正常...打开 COM 对象向 Excel 发送消息的单独线程;)
      【解决方案3】:

      只是为了更新当前使用 PyCharm 和 Python 2.7 的经验: 您需要导入:

      from pythoncom import CoInitializeEx
      from pythoncom import CoUninitialize
      

      然后用于运行线程:

      def run(self):
          res = CoInitializeEx(0)
          #<your code>
          CoUninitialize()
      

      PyCharm 与 STA 单元混淆,您需要启用真正的多线程。

      每个CoInitialize() 都以CoUninitialize() 结尾很重要,因此请确保您的代码也遵循此规则以防出错。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-04-07
        • 1970-01-01
        • 1970-01-01
        • 2015-06-21
        • 2022-06-12
        • 1970-01-01
        相关资源
        最近更新 更多