Сильно запутано win32api + COM и ответ от SO

Из моего другого вопроса здесь, на SO, я спросил, как извлечь текущую песню из Windows Media Player и Zune, я получил ответ от разработчика c ++, который дал мне объяснение, как я буду делать это для WMP.

Однако я не являюсь разработчиком C ++, и я не очень разбираюсь в библиотеке pywin32. И в довершении всего, документация обо всем этом (особенно в отношении WMP) ужасна .

Поэтому мне нужна ваша помощь, чтобы понять, как я буду делать следующее на Python.

Источник

У меня есть рабочий код на C ++ для печати имени носителя, который в настоящее время воспроизводится в WMP. Это простое консольное приложение (78 строк кода).

шаги:

1) реализует базовый COM-объект, реализующий IUnknown, IOleClientSite, IServiceProvider и IWMPRemoteMediaServices. Это просто (вроде, ваш пробег может меняться) с использованием шаблона ATL CComObjectRootEx. Единственными методами, требующими (простого) кода, являются IServiceProvider :: QueryService и IWMPRemoteMediaServices :: GetServiceType. Все остальные методы могут возвращать E_NOTIMPL

2) Создайте экземпляр COM-объекта «WMPlayer.OCX» (в моем случае через CoCreateInstance)

3) Извлечь из объекта указатель интерфейса IOleObject через QueryInterface

4) Исключить объект из класса, указанного в 1) (я использую шаблон CComObject <> :: CreateInstance)

5) Используйте метод SetClientSite из интерфейса, который вы получили в 3), передавая указатель на реализацию OleClientSite.

6) Во время вызова SetClientSite WMP вызывает обратный вызов: fisrt запрашивает указатель интерфейса IServiceProvider, второй вызывает метод QueryService, запрашивая указатель интерфейса IWMPRemoteMediaServices. Верните свою реализацию IWMPRemoteMediaServices и, в-третьих, вы снова будете вызваны через GetServiceType. Затем вы должны вернуть «Удаленный». Теперь вы подключены к запущенному экземпляру WMP

7) Запросить COM-объект для указателя интерфейса IWMPMedia

8) Если 7) не дал NULL, прочитайте свойство IWMPMedia :: name.

9) СОВЕРШЕННО

Все вышеперечисленное было протестировано с помощью VS2010 / Windows Seven и с запущенным WMP (если нет процесса Media Player, просто ничего не делайте).

Я не знаю, может ли yoy / хотеть реализовать COM-интерфейс и объект в Python. Если вас интересует мой код на C ++, дайте мне знать. Вы можете использовать этот код в C ++ DLL, а затем вызвать его из python.

Я немного знаю о win32api.

На первом этапе я действительно не знаю, что делать, результаты поиска по протоколу IOleClientSite в документации msdn, это интерфейс. Тем не менее, я уже застрял. Я не могу найти что-либо (может быть, просто мои ужасные навыки работы с Google), работая с этими вещами на Python.

Второй шаг:

WMP = win32com.client.Dispatch("WMPlayer.OCX") 

Хорошо, это выполнимо.

На третий шаг. QueryInterface –

«независимо от объекта, который вы имеете, вы всегда можете вызвать его метод QueryInterface () для получения нового интерфейса, такого как IStream».

источник

Однако не для меня. Насколько я понимаю его объяснение, я думаю, что это означает, что каждый com-объект вроде «наследует» три метода из IUnknown, одним из которых является QueryInterface, однако это не выглядит так, поскольку вызов QueryInterface на моем объекте WMP терпит неудачу. (Object has no attribute 'QueryInterface')

Я мог бы наброситься, но я считаю, что вы поняли, я понятия не имею, как с этим работать. Может ли кто-нибудь помочь мне с этим? Предпочтительно с примерами кода, но ресурсы и документация также приветствуются.

One Solution collect form web for “Сильно запутано win32api + COM и ответ от SO”

Почти окончательный answser, но НЕ МОЖЕТ закончить. Кажется, что pythoncom нельзя использовать для реализации пользовательского интерфейса без помощи модуля C ++. Вот отклик от Марка Хэммона (Mon, 13 января 2003): Как создать COM-серверы с интерфейсом IID_IDTExtensibility2

Извините, вы SOL. Для поддержки суровых интерфейсов вам необходима поддержка C ++ в виде модуля расширения. Существует новый «Univgw», который может помочь вам, но я не знаю много об этом

Я ничего не могу найти об этой вещи «Univgw» …

Модуль python comtypes предназначен для решения проблемы, и я нашел ссылки, говорящие об этом, но я не могу заставить его работать с моим новым новым Python 3.3. Это код Python 2.x. comtypes кажется устаревшим и неподдерживаемым.

Шаг 1 OK для IOleClientSite и IServiceProvider, KO для IWMPRemoteMediaServices

Шаг 2, 3, 4 и 5 OK

Шаг 6, 7 и 8 не могут быть реализованы без IWMPRemoteMediaServices 🙁

отказ от ответственности: полный новичок в Python, пожалуйста, не кричите

 import pythoncom import win32com.client as wc from win32com.axcontrol import axcontrol import win32com.server as ws from win32com.server import util from win32com.server.exception import COMException import winerror import pywintypes # Windows Media Player Custom Interface IWMPRemoteMediaServices IWMPRemoteMediaServices = pywintypes.IID("{CBB92747-741F-44FE-AB5B-F1A48F3B2A59}") class OleClientSite: _public_methods_ = [ 'SaveObject', 'GetMoniker', 'GetContainer', 'ShowObject', 'OnShowWindow', 'RequestNewObjectLayout', 'QueryService' ] _com_interfaces_ = [ axcontrol.IID_IOleClientSite, pythoncom.IID_IServiceProvider ] def SaveObject(self): print("SaveObject") raise COMException(hresult=winerror.E_NOTIMPL) def GetMoniker(self, dwAssign, dwWhichMoniker): print("GetMoniker ") raise COMException(hresult=winerror.E_NOTIMPL) def GetContainer(self): print("GetContainer") raise COMException(hresult=winerror.E_NOTIMPL) def ShowObject(self): print("ShowObject") raise COMException(hresult=winerror.E_NOTIMPL) def OnShowWindow(self, fShow): print("ShowObject" + str(fShow)) raise COMException(hresult=winerror.E_NOTIMPL) def RequestNewObjectLayout(self): print("RequestNewObjectLayout") raise COMException(hresult=winerror.E_NOTIMPL) def QueryService(self, guidService, riid): print("QueryService",guidService,riid) if riid == IWMPRemoteMediaServices: print("Known Requested IID, but can't implement!") raise COMException(hresult=winerror.E_NOINTERFACE) else: print("Requested IID is not IWMPRemoteMediaServices" ) raise COMException(hresult=winerror.E_NOINTERFACE) if __name__=='__main__': wmp = wc.Dispatch("WMPlayer.OCX") IOO = wmp._oleobj_.QueryInterface(axcontrol.IID_IOleObject) pyOCS = OleClientSite() comOCS = ws.util.wrap(pyOCS, axcontrol.IID_IOleClientSite) IOO.SetClientSite(comOCS) 
  • pip установить pycuda на окна
  • Выполнение Python с Gvim
  • Проблема установки Python matplotlib в Windows 7 для freetype, пакетов png
  • Python Pip install Ошибка: невозможно найти vcvarsall.bat. Пробовал все решения
  • Как установить libxml2 2.9.0 для lxml для Python 3.4.3 на win 7 64?
  • Библиотека PIL и JPEG в Windows
  • установлена ​​подушка, но «нет модуля с подушкой» - python2.7 - Windows 7 - подушка для установки python -m
  • Python 2.7: выход utf-8 в консоли Windows
  • Python - лучший язык программирования в мире.