因此,我有以下代码片段,它试图通过win32api启动Microsoft 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
然而,除了提出的正确的解决方案之外,似乎没有人能够回答COM为什么会这样。在
由于COM和线程的复杂性以及它们为什么会这样工作,恐怕你的问题不能用一两句话来概括。但对于初学者来说,以下是一些很好的信息,说明COM在线程环境下的行为方式:
此外,您应该考虑阅读《在Win32上进行Python编程》一书。它包含了一些有用的信息,可以帮助我们更好地理解COM线程。(尽管年代久远,它仍然有用。)
最后,如果从您提供的引用中看不清楚,每当您的程序使用线程和COM时,您必须在代码中指明您将在线程中使用COM:
^{pr2}$这种类型的调用使用所谓的单单元线程。当线程代码本身实例化COM对象时,就会发生这种情况。在
如果您发现自己在线程代码之外实例化了一个COM对象(并在线程代码中使用实例化的对象,例如在线程之间传递对COM对象的访问),那么这种类型的COM线程被称为多线程单元线程:
希望这有帮助。在
好吧,我想我找到了一个答案,但我还不确定它为什么有用。。在
如果我从页面顶部剪切并粘贴这一行
import win32com.client
就在我分发microsoft powerpoint的try块内,则应用程序成功运行。在但是,我还是不知道为什么。在
至少还有两种方法可以解决这个问题:
使用
run()
方法代替start()
,即test.run()
在
myObject = win32com.client.Dispatch("Powerpoint.Application")
之前插入以下行:import pythoncom; CoInitialize()
请注意,使用run()代替start()已经在其他脚本中进行了测试,而且它始终对我有效!在
相关问题 更多 >
编程相关推荐