IGlobalInterfaceTable::RegisterInterfaceInGlobal返回E_NOTIMPL原因求解
问题原因
你遇到的两次E_NOTIMPL报错本质是同一个问题:待注册到全局接口表(GIT)、或创建敏捷引用的COM对象不支持跨线程列集。
具体触发逻辑
- 当调用
IGlobalInterfaceTable::RegisterInterfaceInGlobal时,COM运行时会自动检测待注册对象是否可跨单元访问:如果该对象是单元线程对象,且其实现类未提供IMarshal接口的自定义列集逻辑,COM默认列集器无法处理该对象的跨线程传递,就会返回E_NOTIMPL。 RoGetAgileReference创建敏捷引用的底层逻辑和GIT注册完全一致,同样要求对象支持跨单元列集,因此也返回相同错误。- 这是Windows 8.1版本外壳对象的典型兼容问题:该版本下系统内置的
IShellItemArray、部分IShellItem实例都是单单元线程实现,没有提供跨单元列集支持,无法直接注册到GIT或者创建敏捷引用。
解决方案
如果你需要在资源管理器扩展的跨线程场景下使用IShellItemArray,不要直接持有指针或通过GIT注册传递:
- 先将
IShellItemArray中每个IShellItem转换为绝对PIDL(ITEMIDLIST)存储 - 跨线程后使用
SHCreateItemFromIDList逐个重建IShellItem,再组装为IShellItemArray使用
所有外壳对象的跨线程传递优先使用PIDL、解析路径这类序列化方案,不要依赖COM自动列集。
内容的提问来源于stack exchange,提问作者user15284017
相关产品推荐
相关产品推荐

