winapi - 如何在 python 中的单独线程中启动 WIN32 应用程序

  显示原文与译文双语对照的内容

因此,我有以下代码Fragment试图通过win32api启动微软 Powerpoint:


import threading
import win32com.client
import sys

class myDemo(threading.Thread):

 def __init__(self):
 threading.Thread.__init__(self)

 def run(self):
 try:
 myObject = win32com.client.Dispatch("Powerpoint.Application")
 print"OK"
 except:
 print"Failed to start Powerpoint!"
 sys.exit(1) 
 print"Now attempting to shutdown..."
 try:
 myObject.quit()
 except:
 print"Error"


if __name__ =="__main__":
 test = myDemo()
 test.start()

问题是它失败了,我没有任何线索。 但是,如果我将最后一行改为 test.run(),它将成功启动。 那么为什么 test.start() 会失败?

为什么这种情况发生,我应该如何解决它,考虑我需要Powerpoint在异步的线程上运行?

先谢谢了。

编辑:显然我的问题与这里有关: http://python.6.x6.nabble.com/Dispatch-error-CoInitialize-has-not-been-called-td1951088.html

然而除了提议的适当解决方案没有人回答为什么is正在这样做。

时间: 作者:

恐怕你的问题可以能无法归纳在一个或者两个句子中,因为和线程的复杂性以及他们的工作方式。 对于初学者来说,下面是为什么com在线程处理方面的行为的一些好的信息:


http://msdn.microsoft.com/en-us/library/ms809971.aspx

此外,你应该考虑在 WIN32 上对图书进行 python 编程。 它包含了有用的信息,可以更轻松地。 ( 尽管它的年龄仍然很有用。)

如果你提供的引用不明确,则在程序使用线程和COM时,必须在代码中指示要在线程中使用 COM:


import pythoncom
import win32com.client

###.. . inside the thread function.. .
x = win32com.client.Dispatch("someCOMobject")
win32com.CoInitialize()
# com calls here
win32com.CoUninitialize()

这种类型的调用使用了所谓的单单元线程。 当线程代码本身实例化了com对象时它会发生。

如果你发现自己在线程代码( 在线程代码 比如 中使用实例化的对象在线程之间传递对com对象的访问) 之外实例化一个com对象,那么这种类型的com线程被称为多线程单元线程:


import sys
sys.coinit_flags = 0

import pythoncom
import win32com.client

#.. . outside the thread function.. .
x = win32com.client.Dispatch("someCOMobject")

#.. . inside the thread function.. .
pythoncom.CoInitialize(pythoncom.COINIT_MULTITHREADED)
# com calls here for x
pythoncom.CoUninitialize()

希望这有帮助

好吧,我想我找到了一个答案,但我还是不确定它为什么工作。

如果我把这行 import win32com.client 从页面的顶部剪贴到,块的顶部,那么应用程序就成功地工作了。

但是我还是找不到。

作者:
...