реализовать библиотеку типов COM-интерфейса на python

#python #com

#python #com

Вопрос:

У меня есть плагин, который я пытаюсь создать в качестве образца для приложения от компании, в которой я работаю. Я пытаюсь написать этот плагин на Python.

Способ работы архитектуры плагина заключается в том, что плагину необходимо реализовать интерфейс, определенный в предоставленной библиотеке типов COM. Таким образом, это COM-клиент для этой библиотеки типов и, в конце концов, регистрируется в качестве COM-сервера в реестре и приложении, предоставляя ему ClassID для COM с поздней привязкой приложением.

Я использую pythoncom и win32com и использовал makepy.py сгенерировать необходимый код python из библиотеки типов, но, похоже, я не могу найти способ создать класс, который реализует интерфейс из библиотеки типов.

Любые указания на это были бы весьма признательны.

Спасибо

Когда я пытаюсь запустить Dispatch для получения COM-объекта, я получаю следующее исключение:

>>> interface = win32com.client.Dispatch('{68AC7909-804F-4D6D-861C-8382DAA7B029}')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:Python26libsite-packageswin32comclient__init__.py", line 95, in Dispatch
dispatch, userName = dynamic._GetGoodDispatchAndUserName(dispatch,userName,clsctx)
File "C:Python26Libsite-packageswin32comclientdynamic.py", line 108, in _GetGoodDispatchAndUserName
return (_GetGoodDispatch(IDispatch, clsctx), userName)
File "C:Python26Libsite-packageswin32comclientdynamic.py", line 85, in _GetGoodDispatch
IDispatch = pythoncom.CoCreateInstance(IDispatch, None, clsctx, pythoncom.IID_IDispatch)
pywintypes.com_error: (-2147221164, 'Class not registered', None, None)

Ответ №1:

Вы можете просто использовать win32com.client.Dispatch() :

object = win32com.client.Dispatch("Class.Name")

Это пример из руководства по быстрому запуску ActiveState:

 >>> import win32com.client
>>> w=win32com.client.Dispatch("Word.Application")
>>> w.Visible=1
>>> w
<win32com.gen_py.Microsoft Word 8.0 Object Library._Application>
  

Если это не сработает, вы можете использовать win32com.client.gencache.EnsureModule() , чтобы убедиться, что вы
сгенерировал правильный модуль кэша.

 from win32com.client import Dispatch
from win32com.client import gencache

# This comes from running: makepy.py -i "Microsoft Excel 14.0 Object Library"
gencache.EnsureModule('{00020813-0000-0000-C000-000000000046}', 0, 1, 7)
obj = Dispatch("Excel.Application.14")

# gives <win32com.gen_py.Microsoft Excel 14.0 Object Library._Application instance ...>
print repr(obj)
  

То же самое с comtypes (более простой и поддерживает пользовательские интерфейсы)

 from comtypes.client import CreateObject
obj = CreateObject("Excel.Application")
  

Комментарии:

1. Да, я попробовал это, и я получаю: pywintypes.com_error: (-2147221164, ‘Класс не зарегистрирован’, Нет, None)

2. @Caleb: И вы получили <ComObject *> вместо <win32com.gen_py.*>? В этом случае вам следует использовать win32com.gencache.EnsureModule() . makepy сообщает вам, какую именно строку вы должны написать. Смотрите мою правку для примера.

3. Кстати, действительно ли ваш com-интерфейс поддерживает отправку (т. Е. Доступен ли он из VB6 / VBScript / etc.)? В противном случае вы не сможете использовать win32com — вы должны использовать comtypes. Или, может быть, вы все равно захотите использовать comtypes , поскольку его API немного лучше, чем win32com.

4. Я не уверен. Если IDispatch не отображается в . Означает ли это, что IDL не поддерживает IDispatch? Извините, у меня нет доступа к коду, из которого генерируется библиотека типов.

5. @Caleb: Да, интерфейсы, определенные в IDL, должны наследоваться от IDispatch. Если они этого не сделают, вы не сможете использовать их из win32com.