如何在Python中实现COM接口IFileSysBindData适配IFileOperation
问题:Python中通过pywin32实现IFileSystemBindData并传递给IBindCtx的问题
我用Python编写代码,尝试通过win32的IFileOperation执行Shell文件操作。具体场景是:将文件或目录移动/复制到不存在的位置时,需要获取指向目标目录的IShellItem(或IShellItem2)对象,但目标不存在时SHCreateItemFromParsingName会执行失败。参考相关方案后,我已经完成WIN32_FIND_DATAW结构的创建,并通过pywin32的pythoncom.CreateBindCtx()创建了IBindCtx对象,但卡在Python中实现IFileSysBindData类这一步。
现有代码
class FileSysBindData: _public_methods_ = ['SetFindData', 'GetFindData'] _reg_clsid_ = '{01E18D10-4D8B-11d2-855D-006008059367}' def SetFindData(self, win32_find_data): self.win32_find_data = win32_find_data return 0 def GetFindData(self, p_win32_find_data): p_win32_find_data.contents = self.win32_find_data return 0 bind_data = FileSysBindData() ibindctx = pythoncom.CreateBindCtx() # TODO: set the bind data ibindctx.RegisterObjectParam('File System Bind Data', bind_data)
报错信息
ValueError: argument is not a COM object (got type=FileSysBindData)
解决方案
要让自定义类成为pywin32兼容的COM对象,需要继承pythoncom.COMObject并指定对应接口的IID,修正后的代码如下:
import pythoncom # IFileSystemBindData的标准IID IID_IFileSystemBindData = '{000214F2-0000-0000-C000-000000000046}' class FileSysBindData(pythoncom.COMObject): _com_interfaces_ = [IID_IFileSystemBindData] _public_methods_ = ['SetFindData', 'GetFindData'] def __init__(self): super().__init__() self.win32_find_data = None def SetFindData(self, win32_find_data): self.win32_find_data = win32_find_data return 0 # 返回S_OK表示成功 def GetFindData(self, p_win32_find_data): if self.win32_find_data is not None: p_win32_find_data.contents = self.win32_find_data return 0 # 返回S_OK表示成功 # 创建COM兼容的绑定数据对象 bind_data = FileSysBindData() ibindctx = pythoncom.CreateBindCtx() ibindctx.RegisterObjectParam('File System Bind Data', bind_data)
关键说明
- 继承COMObject基类:
pythoncom.COMObject是pywin32中创建进程内COM对象的核心基类,只有继承它,类实例才能被识别为合法的COM对象。 - 声明接口IID:通过
_com_interfaces_属性指定实现的COM接口标识,这里必须使用IFileSystemBindData的标准IID。 - 符合COM方法规范:所有COM方法需要返回HRESULT值,成功时返回
0(对应系统定义的S_OK常量)。 - 无需注册系统COM服务器:该对象是进程内自定义实现,不需要注册到系统注册表,直接作为客户端对象使用即可。
内容的提问来源于stack exchange,提问作者Lojack
相关产品推荐
相关产品推荐

