沉迷于win32api + COM和SO的答案

从我这里的另一个问题,我问如何从Windows媒体播放器和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)实例化“WMPlayer.OCX”COM对象(在我的情况下,通过CoCreateInstance)

3)通过QueryInterface从对象中检索一个IOleObject接口指针

4) Instanciate在1)中看到的类(我使用CComObject <> :: CreateInstance模板)

5)使用从3)得到的接口的SetClientSite方法,将一个指针传递给你的OleClientSite实现。

6)在SetClientSite调用期间,WMP会callback你:fisrt询问一个IServiceProvider接口指针,然后调用QueryService方法,询问一个IWMPRemoteMediaServices接口指针。 返回你的IWMPRemoteMediaServices的实现,第三,你将通过GetServiceType再次被调用。 您必须然后返回“远程”。 您现在连接到WMP运行实例

7)查询COM对象的IWMPMedia接口指针

8)如果7)没有给NULL,请阅读IWMPMedia :: name属性。

9)完成

以上所有内容都是使用VS2010 / Windows Seven进行testing,并且运行WMP(如果没有运行媒体播放器进程,则什么也不做)。

我不知道是否可以/想要在Python中实现COM接口和对象。 如果您对我的C ++代码感兴趣,请告诉我。 您可以在C ++ DLL中使用该代码,然后从Python中调用它。

我知道一点关于win32api。

在第一步,我真的不知道该怎么做,使用IOleClientSite在msdn文档中search结果,这是一个接口。 但是,这就是我已经陷入困境的地方。 我无法find任何东西(可能只是我可怕的search技巧)在Python中使用这些东西。

第二步:

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

好的,这是可行的。

到第三步。 QueryInterface –

“不pipe你拥有什么对象,你总是可以调用它的QueryInterface()方法来获得一个新的接口,比如IStream。

资源

但是,不是为了我。 据我了解他的解释,我认为这意味着每一个COM对象都从IUnknown中“inheritance”三种方法,其中一种是QueryInterface,但是由于在我的WMP对象上调用QueryInterface失败,似乎并不是这样。 (Object has no attribute 'QueryInterface')

我可以漫不经心,但我相信你明白了,我不知道如何处理这个问题。 任何人都可以帮我解决这个问题吗? 最好用代码示例,但资源/文档也是可以的。

Solutions Collecting From Web of "沉迷于win32api + COM和SO的答案"

几乎最终answser,但不能完成。 我似乎pythoncom不能用于实现自定义接口没有C + +模块的帮助。 这是Mark Hammon(Mon,2003年1月13日)的答案 : 如何用IID_IDTExtensibility2接口创建COM服务器

对不起 – 你是SOL。 为了支持任意接口,需要以扩展模块的形式提供C ++支持。 有一个新的“Univgw”,可以帮助你,但我不太了解这一点

我无法找到有关“Univgw”的事情

comtypes python模块是为了解决这个问题,我发现它的链接,但我不能让它与我的新的Python 3.3的工作。 这是Python 2.x代码。 看起来过时,没有维护。

步骤1确定IOleClientSite和IServiceProvider,KO for IWMPRemoteMediaServices

步骤2,3,4和5确定

如果没有IWMPRemoteMediaServices,则无法实施步骤6,7和8 🙁

免责声明:在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)