2014-01-15 3 views
1

Итак, я имею этот следующий фрагмент кода, который пытается запустить Microsoft Powerpoint через WIN32API:Как запустить 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 для асинхронного запуска отдельной ветви?

Заранее спасибо.

EDIT: Видимо, мой вопрос каким-то образом связана с этим: 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 

Кроме того, следует рассмотреть вопрос о пересмотре книги Python Программирование на Win32. Он содержит полезную информацию, которая проливает больше света на потоки 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

ОК, так что я думаю, я нашел ответ, но я не знаю, почему это работает ..

Если вырезать и вставить эту строку import win32com.client из верхней части страницы прямо внутри блока Ьги где я разослать Microsoft Powerpoint, приложение работает успешно.

Однако я все еще не могу понять, почему.

+0

Возможно, вы сбиты с толку, потому что вы * должны * использовать 'sys.coinit_flags = 0' * перед * импортом' pythoncom'. Модуль pythoncom вызывает 'CoInitialize()' во время импорта. Он ищет 'sys.coinit_flags', чтобы узнать, хочет ли разработчик что-то другое. –

0

Есть еще по крайней мере два пути решения вопроса:

  1. Используйте run() метод вместо start(), т.е.test.run()

  2. Перед myObject = win32com.client.Dispatch("Powerpoint.Application") вставьте следующие строки: import pythoncom; CoInitialize()

Обратите внимание, что при использовании прогон() вместо запуска() была протестирована в других сценариях и он всегда работал для меня!

Смежные вопросы