【发布时间】:2013-11-05 23:35:33
【问题描述】:
从我关于 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) 实例化“WMPlayer.OCX”COM 对象(在我的例子中,通过 CoCreateInstance)
3) 通过 QueryInterface 从对象中检索一个 IOleObject 接口指针
4) 从 1) 中看到的类中实例化一个对象(我使用 CComObject::CreateInstance 模板)
5)使用您在 3) 中获得的接口中的 SetClientSite 方法,将指针传递给您的 OleClientSite 实现。
6) 在 SetClientSite 调用期间,WMP 会回调您:首先要求 IServiceProvider 接口指针,其次调用 QueryService 方法,请求 IWMPRemoteMediaServices 接口 指针。返回您的 IWMPRemoteMediaServices 实现,并且, 第三,您将再次通过 GetServiceType 调用。那么你必须 返回“远程”。您现在已连接到 WMP 运行实例
7)在COM对象中查询IWMPMedia接口指针
8) 如果 7) 没有给出 NULL,则读取 IWMPMedia::name 属性。
9)完成
以上所有内容均使用 VS2010 / Windows 7 和 WMP 进行了测试 正在运行(如果没有媒体播放器进程正在运行,只需执行 什么都没有)。
我不知道你是否可以/想要实现 COM 接口和对象 Python。如果您对我的 C++ 代码感兴趣,请告诉我。你可以 在 C++ DLL 中使用该代码,然后从 python 调用它。
我对win32api有点了解。
第一步,我真的不知道该怎么做,谷歌搜索 IOleClientSite 结果在 msdn 文档中,它是一个接口。但是,这就是我已经陷入困境的地方。我找不到任何东西(可能只是我可怕的谷歌搜索技能)在 Python 中使用这些东西。
第二步:
WMP = win32com.client.Dispatch("WMPlayer.OCX")
好的,这是可行的。
进入第三步。查询接口 -
“不管你有什么对象,你都可以随时调用它的QueryInterface()方法来获取一个新的接口,比如IStream。”
但是,不适合我。据我了解他的解释,我认为这意味着每个 com 对象都从 IUnknown“继承”了三个方法,其中之一是 QueryInterface,但是这似乎并非如此,因为在我的 WMP 对象上调用 QueryInterface 惨遭失败。 (Object has no attribute 'QueryInterface')
我可以继续说下去,但我相信你明白了,我不知道如何处理这个问题。谁能帮我解决这个问题?最好带有代码示例,但也欢迎提供资源/文档。
【问题讨论】:
-
在 Windows 生态系统中,各种工具/语言通过 COM 与组件对话。所以基本可以在vbscript中搜索类似的解决方案,翻译成python+pywin32
-
肯定有一种方法可以调用QueryInterface。我通过 google 发现对“oleobj”和/或“CastTo”的引用。我还读到可以在 Python 中实现 COM 接口(接口只不过是一个 VTBL,带有一些简单的代码)。唉,我不使用 Python,也帮不上什么忙。如果您需要我发布 C++ 代码,请回复。
-
PythonCOM here 上有一个很好的教程。它讨论了如何基于 IUnknown 实现您自己的 COM 对象(以及 IOleClientSite 和 IServiceProvider 的实现)。您不需要注册您的类,因为您不需要其他应用程序来创建您的对象的实例。
标签: python windows com pywin32