2014-01-15 19 views
1

所以,我有这个下面的代码片段,它试图通过WIN32API启动微软Powerpoint:如何启动在单独的线程Win32应用程序在Python

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是表现这种方式。

+0

“开始”是什么意思?你的对象只有一个方法,“运行” –

+0

start()异步执行对象的运行方法。 – kstratis

回答

1

由于COM和线程的复杂性以及他们为什么如此工作,恐怕你的问题可能无法用一两句话来概括。但是对于初学者来说,这里就是为什么COM行为下穿线方式是这样一些好的信息:

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

另外,你应该考虑审查在Win32书Python编程。它包含有助于了解COM线程的更多信息。 (尽管它的年龄还是有用的)。

最后,如果你没有从你提供的参考清楚你的程序使用线程和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() 

希望这会有所帮助。

0

OK,所以我想我找到了答案,但我还不知道为什么它的工作原理..

如果我切,并从页面顶部右侧粘贴try块,我派里面这条线import win32com.client微软的Powerpoint,该应用程序成功运行。

但是,我仍然无法找出原因。

+0

您可能会感到困惑,因为您必须在导入pythoncom之前使用sys.coinit_flags = 0 *。 pythoncom模块在导入时调用'CoInitialize()'。它寻找'sys.coinit_flags'来查看开发者是否想要不同的东西。 –

0

至少有两个方法来解决这个问题:

  1. 使用run()方法,而不是start(),即test.run()

  2. myObject = win32com.client.Dispatch("Powerpoint.Application")之前插入以下行:import pythoncom; CoInitialize()

注意,使用的run(),而不是开始()已在其他脚本进行了测试,它总是为我工作!

相关问题