从这里的另一个问题中,我问到如何从和Zune检索当前播放的歌曲,我从一个c++开发人员那里得到了一个答案,他解释了我将如何为WMP做这件事。
但是,我不是C++开发人员,也不是非常熟悉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再次调用您。然后必须返回"Remote“。您现在已连接到正在运行的WMP实例。 7)查询COM对象以获得IWMPMedia接口指针 8) (如果7)没有给空,请阅读IWMPMedia::属性。 9)完成 所有这些都是在VS2010 /Windows7和WMP运行时进行的(如果没有媒体播放器进程运行,就什么也不做)。 我不知道yoy是否能够/想在Python中实现COM接口和对象。如果您对我的C++代码感兴趣,请告诉我。您可以在C++ DLL中使用该代码,然后从python中调用它。
我对win32api有一点了解。
在第一步,我真的不知道该做什么,谷歌IOleClientSite结果在msdn文档中,它是一个接口。不过,我已经被困在那里了。在Python中使用这些东西时,我找不到任何东西(可能只是我可怕的googling技巧)。
第二步:
WMP = win32com.client.Dispatch("WMPlayer.OCX")
好吧,这是可行的。
进入第三步。QueryInterface -
“无论您拥有哪个对象,您都可以调用它的QueryInterface()方法来获得一个新的接口,比如IStream。”
不过,对我来说不是。正如我理解他的解释,我认为这意味着每个com对象都从IUnknown“继承”了三种方法,其中之一是QueryInterface,然而,由于在QueryInterface对象上调用QueryInterface失败了,所以情况似乎并非如此。(Object has no attribute 'QueryInterface')
我可以继续说下去,但我相信你明白了,我不知道该如何处理这个问题。有人能帮我解决这个问题吗?最好有代码示例,但也欢迎资源/文档。
发布于 2013-10-28 12:01:03
几乎是最后的答案,但不能完成。没有C++模块的帮助,我似乎无法使用pythoncom来实现自定义接口。下面是Mark的回答(Mon,2003年1月13日):IDTExtensibility2接口
抱歉-你是索尔。为了支持任意接口,您需要以扩展模块的形式提供C++支持。有一种新的"Univgw“可以帮助你,但我对此知之甚少
我找不到任何关于"Univgw“的东西.
comtypes模块旨在解决这个问题,我找到了一些链接,说明它确实存在,但是我无法让它与我的新的Python3.3一起工作。它是Python2.x代码。comtypes似乎过时了,而且没有维护。
步骤1 IOleClientSite和IServiceProvider的OK,IWMPRemoteMediaServices的KO
步骤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)
https://stackoverflow.com/questions/19613750
复制相似问题