3

win32com.client.GetActiveObject使用然后import pywintypesAttributeError每次调用原始 COM 对象时创建/获取COM 对象。

重现代码

import win32com.client
catia_com = win32com.client.GetActiveObject('CATIA.Application')

# then later when needed, do some pywinauto stuff
import pywinauto.application

# back to working directly on catia com object
print(catia.caption)  # raises Attribute error from within win32com.client

为什么会发生这种情况,如何解决?

4

1 回答 1

3

我能够找到一个我想分享的解决方案,但我也想听听关于我的理解的反馈,以及应该解决什么是适当的依赖关系,以防止其他人遇到同样的问题。

解决方案

import comtypes调用前添加win32com.client

例子

import comtypes
import win32com.client
catia_com = win32com.client.GetActiveObject('CATIA.Application')

# then later when needed, do some pywinauto stuff
import pywinauto.application

# back to working directly on catia com object
print(catia.caption)  # it works!

原因和解释(尽我所能确定)

TLDR

import comtypesCoInitializeEx带有标志的调用COINIT_MULTITHREADED恰好覆盖了 . 设置的模式win32com.client.GetActiveObject

完整解释

我得出这个结论是因为在注释掉pythoncom.CoUninitialize()(我担心它会杀死从返回的 COM 对象win32com.client.GetActiveObjectpywinauto.__init__并重新运行代码时,会引发以下错误comtypes.__init__

OSError: [WinError -2147417850] Cannot change thread mode after it is set

我知道comtypes.__init__Handels 选择默认标志CoInitializeEx并且无法推断win32comlib 是如何但认为它也可能正在检查现有标志,所以我添加了import comtypes.

我仍然模糊的地方

  1. 您如何确定 win32com 的并发模型标志是什么?
  2. 调用 win32com.client.GetActiveObject 时如何指定并发模型标志?
  3. 为什么该解决方案确实有效...pythoncom.CoInitializeEx(0x0)在调用 win32com.client.GetActiveObject 之前直接调用不起作用!

如果我能得到上述答案,我可以向 win32com 推荐设置sys.coinit_flags(这comtypes.__init__是检查的地方)。

资源

于 2018-09-13T01:35:42.263 回答