首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在Python中以单独的线程启动win32应用程序

如何在Python中以单独的线程启动win32应用程序
EN

Stack Overflow用户
提问于 2014-01-15 15:18:04
回答 3查看 6.3K关注 0票数 2

因此,下面的代码片段试图通过win32api启动:

代码语言:javascript
运行
复制
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为什么会这样做。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-03-24 19:41:08

恐怕你的问题不能用一两句话来概括,因为COM和线程的复杂性,以及它们为什么会以这样的方式工作。但首先,这里有一些很好的信息,说明了为什么COM在线程下的行为方式:

代码语言:javascript
运行
复制
http://msdn.microsoft.com/en-us/library/ms809971.aspx

此外,您应该考虑阅读Python编程on Win32一书。它包含了更多关于COM线程的有用信息。(尽管它已经问世,但它仍然是有用的。)

最后,如果从您提供的引用中看不清楚,每当您的程序使用线程和COM时,您必须在代码中指示您将在线程中使用COM:

代码语言:javascript
运行
复制
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线程被称为多线程公寓线程:

代码语言:javascript
运行
复制
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()

希望这能有所帮助。

票数 6
EN

Stack Overflow用户

发布于 2014-01-15 15:42:11

好的,所以我想我找到了一个答案,但我还不知道为什么会起作用。

如果我从页面顶部剪切并粘贴这一行import win32com.client,就在我发送microsoft的try块中,应用程序就会成功运行。

不过,我还是找不出原因。

票数 0
EN

Stack Overflow用户

发布于 2018-02-04 14:41:28

至少还有两种方法可以解决这个问题:

  1. 使用run()方法而不是start(),即test.run()
  2. myObject = win32com.client.Dispatch("Powerpoint.Application")之前插入以下行:import pythoncom; CoInitialize()

注意,使用run()而不是start()已经在其他脚本中进行了测试,它对我总是有效的!

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21141217

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档