pythoncom.CoCreateInstance 无法创建 IZoneIdentifier;尽管在 MSDN 中有记录,但该接口也从注册表中丢失

pythoncom.CoCreateInstance can't create IZoneIdentifier; the interface is missing from registry too despite being documented in MSDN

我正在尝试在 Python 中实现 Manipulating the zone identifier to specify where a file was download from – The Old New Thing - MSDN blogs

CoCreateInstance

pythoncom.CoCreateInstance(
        pywintypes.IID('{0968e258-16c7-4dba-aa86-462dd61e31a3}'),    #CLSID_PersistentZoneIdentifier
        None,pythoncom.CLSCTX_ALL,
        pywintypes.IID('{cd45f185-1b21-48e2-967b-ead743a8914e}'))    #IID_IZoneIdentifier

我收到一个错误:

TypeError: There is no interface object registered that supports this IID

(没有堆栈跟踪,因为这是一个扩展函数)

如果我将 IZoneIdentifier IID 替换为 pythoncom.IID_IUnknownpythoncom.IID_IPersistFile,它可以工作,但是具有正确 IID 的 QueryInterface 会失败并出现相同的错误。

确实,在 HKCR\Interface 中,我没有看到 IZoneIdentifier,但确实看到 IPersistFile


反汇编urlmon.dll后,我看到它确实实现了接口,但没有在其DllRegisterServer中注册它。进一步搜索,我发现 IPersistFile 正在由 ole32.dll 注册 - 但不是 IZoneIdentifier.

MSDN 记录此接口自 IE6 起可用。但它不存在于 IE7 或 IE8 中。由于这是 XP(据称有所有更新),我没有别的可以尝试了。

同样,该接口存在于 MSDN 文章中提到的 urlmon.h 文件中的 Windows SDK 7.0 中。

问题是:

IZoneIdentifier没问题。原来的 C++ 程序运行得很好。由于 ,并非对象实现的每个接口都会在注册表中注册,只有那些支持编组的接口才会被注册。

错误来自 pythoncom 本身(提示是 TypeError,而不是 pythoncom.com_error,并且错误消息总是英文而不是系统的 UI 语言).

原因是 pythoncom 确实需要 IDispatch 接口支持 - 否则它无法推断出如何使用接口的函数和值 accept/return .

唯一的例外是许多基于 IUnknown 的接口支持,编译在其中(IPersistFile 是其中之一;完整列表显然在 pythoncom.InterfaceNames 中)。

可以使用“pythoncom 扩展”模块添加对其他基于 IUnknown 的接口的支持。可以在 Python and COM - Implementation Details 文章的 pywin32 文档中找到关于它们的一些(非常稀缺的)文档。