如何在 Python 中的单独线程中启动 win32 应用程序 [英] How to launch win32 applications in separate threads in Python

查看:48
本文介绍了如何在 Python 中的单独线程中启动 win32 应用程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以,我有以下代码片段,它试图通过 win32api 启动 Microsoft Powerpoint:

So, I am having this following snippet which attempts to start Microsoft Powerpoint through the win32api:

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() 会失败?

The problem is that it fails and I have no clue why. However, if I change the last line to test.run() it will launch successfully. So again why is this failing with test.start()?

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

Why is this happening and how should I solve it considering I need Powerpoint to run on a seperate thread asynchronously?

提前致谢.

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

Apparently my question is somehow related to this: http://python.6.x6.nabble.com/Dispatch-error-CoInitialize-has-not-been-called-td1951088.html

然而,除了提出的正确解决方案之外,似乎没有人回答为什么 COM 会这样行事.

However apart from the proposed proper solution no one seems to answer why exactly COM is behaving this way.

推荐答案

由于 COM 和线程的复杂性以及它们为什么会这样工作,恐怕您的问题可能无法用一两句话来概括.但是对于初学者来说,这里有一些很好的信息,说明 COM 在线程下的行为方式:

I'm afraid your question likely can't be summed up in one or two sentences due to complexities in COM and threading and why they work the way they do. But for starters, here's some good information why COM behaves the way it does under threading:

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

此外,您应该考虑阅读Python Programming on Win32一书.它包含有用的信息,可以更深入地了解 COM 线程.(尽管年代久远,它仍然很有用.)

Additionally, you should consider reviewing the book Python Programming on Win32. It contains useful information that sheds more light on COM threading. (Despite its age it is still useful.)

最后,如果您提供的参考资料不清楚,无论何时您的程序使用线程和 COM,您都必须在代码中指明您将在线程内使用 COM:

Finally, in case it wasn't clear from the reference you provided, whenever your program uses threads and COM, you must indicate in code that you're going to use COM within a thread:

import pythoncom
import win32com.client

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

这种类型的调用使用所谓的单单元线程.它发生在线程代码本身实例化 COM 对象时.

This type of call uses what's called single-apartment threading. It occurs when the threaded code itself instantiates COM objects.

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

If you find yourself instantiating a single COM object outside the threaded code (and using the instantiated object in the threaded code e.g. passing access to the COM object between threads), then this type of COM threading is called multithreaded-apartment threading:

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()

希望这会有所帮助.

这篇关于如何在 Python 中的单独线程中启动 win32 应用程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆