第 ⑫ 章 · 调试、部署与现代化迁移

收尾章——如何调试跑在 explorer/dllhost/prevhost 里的扩展、per-user 与 per-machine 注册、MSIX/稀疏包部署,以及一张“旧接口 → 新接口”的迁移对照表。

作者 David更新于

前面每章一个扩展点。这一章把散落的工程问题收一下口:怎么调试、怎么干净地注册、怎么部署,以及——本指南从头到尾的主线——把 20 年前的老写法迁移到 Win10/11 的新接口。

一、调试:你的 DLL 跑在别人的进程里

Shell 扩展是进程内 COM 组件,被宿主进程加载。调试的第一步是搞清楚“宿主是谁”:

扩展类型宿主进程怎么调
右键菜单 / 图标 / InfoTip / 属性页explorer.exe附加到 explorer;改完 DLL 前先 taskkill /f /im explorer.exe 再重启
缩略图 / 属性处理器dllhost.exe(COM Surrogate)附加到对应的 dllhost 实例
预览处理器prevhost.exe独立进程,直接附加最省心

最常见的坑:explorer 把你的 DLL 锁住了,cmake --build 覆盖不了旧文件。解决办法是每次重建前重启 explorer,或者开发期给 CLSID 挂 AppID + DllSurrogate,让扩展跑进独立的 dllhost 里——崩了也不拖垮桌面(这正是缩略图、预览默认隔离的原因)。

调试期开隔离,给 CLSID 加一个空的 AppID 值即可让系统用 dllhost 托管:

HKCR\CLSID\{你的CLSID}\  AppID = {你的CLSID}
HKCR\AppID\{你的CLSID}\  DllSurrogate = ""   (空字符串 = 用默认代理 dllhost)

二、注册:per-user 还是 per-machine

regsvr32 默认写 HKEY_CLASSES_ROOT,需要管理员。现代推荐 per-user 注册——写 HKCU\Software\Classes,免管理员、卸载干净、不影响其他用户:

HKCU\Software\Classes\CLSID\{CLSID}\...           ← 组件本体
HKCU\Software\Classes\.ext\shellex\...            ← 关联

本指南的示例为求简洁写的是 HKCR(= 管理员 per-machine)。真实产品优先 per-user,除非扩展确实要对所有用户生效。

在非默认(non-per-user)场景,企业环境可能启用“仅允许已批准的扩展”策略(HKLM\...\Shell Extensions\Approved)。个人机通常不受影响,但企业分发时要留意。

三、部署:从 regsvr32 到 MSIX

regsvr32 + 写注册表是经典做法,但 Win10/11 的现代分发是 MSIX / 稀疏包(sparse package):

  • 声明式:扩展点写在 AppxManifest.xml 里(见 Win11 菜单章),系统按清单注册,不用手写注册表。
  • 干净卸载:卸载包 = 所有注册项一起消失,不留垃圾。
  • Win11 主菜单硬性要求:前面讲过,要进 Win11 那个新版右键主菜单,必须打包 + 用 IExplorerCommand,regsvr32 的老菜单只会被折叠进“显示更多选项”。

所以现代扩展的典型形态是:IExplorerCommand 实现 + MSIX/稀疏包声明。老的 IContextMenu + regsvr32 仍然能用,但只活在“更多选项”的二级菜单里。

四、现代化迁移对照表

这是把老代码搬到 Win10/11 时最该记住的一张表——左边是本指南参考的 2004 年老文里的写法,右边是现在该用的:

目的旧接口(已过时/受限)新接口(Win10/11 推荐)
初始化——拿到目标文件IShellExtInit / IPersistFileIInitializeWithStream → WithItem → WithFile
缩略图IExtractImageIThumbnailProvider
列表额外栏目IColumnProvider(已移除)属性处理器 + IPropertyStore
右键命令IContextMenu(进“更多选项”)IExplorerCommand + 打包
数据关联直接读文件句柄优先 Stream,以便沙箱/云文件/隔离宿主

一条总原则:能用 Stream 就别用 File。IInitializeWithStream 让扩展跑在受限沙箱、云占位文件(OneDrive Files On-Demand)、隔离宿主里都不出问题;直接抓文件路径的老写法在这些场景会失效。这也是微软反复强调的方向。

结语

到这里,Windows Shell 扩展的主要扩展点就走完了一遍:从右键菜单、Win11 新菜单,到缩略图、图标,再到属性、提示、属性页、预览、拖放、图标叠加。每一章的完整可编译代码都在 shell-extension-demos 仓库里。

核心心法就三条:扩展跑在别人进程里,所以要快、要稳、要隔离;能用 Stream 初始化就别碰文件路径;面向 Win11 就上 IExplorerCommand + MSIX。

参考

本页目录