从我在SO上的另一个问题,我问如何从Windows Media Player和Zune中检索当前播放的歌曲,我得到了一个c ++开发人员的回答,他给了我一个如何为WMP做这个的解释。 / p>
但是,我不是C ++ dev,我对pywin32库也没有经验。最重要的是,所有这些(特别是关于WMP)的文档都是可怕的。
因此,我需要您的帮助,了解我将如何在Python中执行以下操作。
我在C ++中使用代码来打印当前媒体的名称 在WMP中玩。这是一个简单的控制台应用程序(78行代码)。
步骤:
1)实现了一个实现IUnknown,IOleClientSite,IServiceProvider和IWMPRemoteMediaServices的基本COM对象。这是 使用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将回调您:fisrt要求提供IServiceProvider接口指针,第二次调用 QueryService方法,要求IWMPRemoteMediaServices接口 指针。返回IWMPRemoteMediaServices的实现, 第三,您将通过GetServiceType再次调用。那你必须 返回“远程”。您现在已连接到WMP运行实例
7)查询COM对象以获取IWMPMedia接口指针
8)如果7)没有给出NULL,请阅读IWMPMedia :: name属性。
9)完成
以上所有测试均使用VS2010 / Windows Seven和WMP进行测试 正在运行(如果没有运行Media Player进程,那就行了 没有)。
我不知道yoy是否可以/想要实现COM接口和对象 蟒蛇。如果您对我的C ++代码感兴趣,请告诉我。你可以 在C ++ DLL中使用该代码,然后从python中调用它。
我对win32api有点了解。
在第一步,我真的不知道该怎么做,谷歌搜索IOleClientSite导致msdn文档,它是一个接口。然而,那就是我已经陷入困境的地方。我在Python中使用这些东西找不到任何东西(可能只是我可怕的谷歌搜索技巧)。
第二步:
WMP = win32com.client.Dispatch("WMPlayer.OCX")
好的,那是可行的。
到第三步。 QueryInterface -
“无论您拥有什么对象,您都可以调用其QueryInterface()方法来获取新的接口,例如IStream。”
然而,不适合我。据我了解他的解释,我认为这意味着每个com对象都是“继承”IUnknown中的三个方法,其中一个是QueryInterface,但是这似乎不是这样,因为在我的WMP
对象上调用QueryInterface失败了。 (Object has no attribute 'QueryInterface')
我可以漫步,但我相信你明白了,我不知道如何使用它。任何人都可以帮我解决这个问题吗?最好使用代码示例,但也欢迎资源/文档。
答案 0 :(得分:2)
几乎是最终的答案但是无法完成。 我似乎没有C ++模块的帮助,pythoncom不能用于实现自定义接口。 以下是Mark Hammon的回答(2003年1月13日,星期一):How to create COM Servers with IID_IDTExtensibility2 interface
抱歉 - 你是SOL。要支持仲裁接口,您需要C ++ 支持,以扩展模块的形式。有一个新的“Univgw” 这可能会帮助你,但我不太了解这个
我无法找到任何有关“Univgw”的事情......
comtypes python模块旨在解决问题,我发现链接说它确实存在,但我不能使它适用于我新的Python 3.3。这是Python 2.x代码。 comtypes似乎过时且没有维护。
步骤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)