Windows Shell Extension 绿色版手动注册实践 —— 以 TortoiseGit/TortoiseSVN 为例 背景在 Windows 11 上以「绿色解压」方式安装了 TortoiseGit 和 TortoiseSVN非 MSI 安装器导致资源管理器右键菜单中缺少这两个工具的选项。问题本质Windows Shell Extension外壳扩展需要通过注册表向系统注册才能被资源管理器加载。MSI 安装器会自动完成注册但绿色版只解压了文件没有写注册表。诊断过程1. 确认 DLL 是否存在# 两者的 Shell Extension DLL 分别是D:\dev\tools\git\install\TortoiseGit\bin\TortoiseGit.dll# 64位 PE32D:\dev\tools\git\install\TortoiseSVN\bin\TortoiseSVN.dll# 64位 PE322. 检查注册表是否已有注册# 查看右键菜单处理器 — 结果为空reg queryHKCR\Directory\shellex\ContextMenuHandlers/s# 查看 Approved Shell Extensions — 无 Tortoise 条目reg queryHKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Shell Extensions\Approved/fTortoise3. 尝试 regsvr32 自注册 — 失败regsvr32D:\dev\tools\git\install\TortoiseGit\bin\TortoiseGit.dll# 无效果 — 这两个 DLL 都没有导出 DllRegisterServer 函数判断方法用 PowerShell 检查 DLL 是否包含DllRegisterServer字符串$bytes[System.IO.File]::ReadAllBytes(path\to\dll)$text[System.Text.Encoding]::ASCII.GetString($bytes)$text-matchDllRegisterServer# False 不支持自注册4. 找到正确的注册模板在 TortoiseGit 源码仓库中找到了官方的注册表模板文件https://github.com/TortoiseGit/TortoiseGit/blob/master/src/TortoiseShell/register.registryTortoiseSVN 的 CLSID 则由用户提供来自其源码Guids.h。Shell Extension 注册原理一个完整的 Shell Extension 注册涉及以下注册表位置右键菜单ContextMenuHandlerHKCR\*\shellex\ContextMenuHandlers\{名称} → 文件右键 HKCR\Directory\shellex\ContextMenuHandlers\{名称} → 文件夹右键 HKCR\Directory\Background\shellex\ContextMenuHandlers\{名称} → 空白处右键 HKCR\Folder\shellex\ContextMenuHandlers\{名称} → 文件夹右键 HKCR\Drive\shellex\ContextMenuHandlers\{名称} → 驱动器右键 HKCR\lnkfile\shellex\ContextMenuHandlers\{名称} → 快捷方式右键拖放处理DragDropHandlerHKCR\Directory\shellex\DragDropHandlers\{名称} HKCR\Drive\shellex\DragDropHandlers\{名称} HKCR\Folder\shellex\DragDropHandlers\{名称}属性页PropertySheetHandlerHKCR\*\shellex\PropertySheetHandlers\{名称} HKCR\Directory\shellex\PropertySheetHandlers\{名称}CLSID 注册COM 组件HKLM\SOFTWARE\Classes\CLSID\{CLSID-GUID} (默认) 显示名称 InProcServer32 (默认) DLL完整路径 ThreadingModel ApartmentShell Extensions 审批HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Shell Extensions\Approved {CLSID-GUID} 显示名称图标覆盖层Icon OverlayHKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\ShellIconOverlayIdentifiers\名称 (默认) {CLSID-GUID} HKLM\SOFTWARE\TortoiseOverlays\Normal Git {对应CLSID} HKLM\SOFTWARE\TortoiseOverlays\Modified Git {对应CLSID} ...关键 CLSID 对照表TortoiseGit来自src/TortoiseShell/Guids.h用途CLSID正常状态 Overlay{451C7E59-058F-450a-8C42-FE9A12A302FC}已修改 Overlay{8DA7CDCB-DC0B-4246-80BD-812E942734AF}冲突 Overlay{475A024D-6157-4e03-8C61-D1FA9806415C}未控制 Overlay{10A0FDD2-B0C0-4cd4-A7AE-E594CE3B91C8}拖放处理{6A4800FA-13B4-4cb4-9A37-97E7FAEDA731}只读 Overlay{5F380D0B-EE64-479b-B2AD-EF437BF4B0A6}已删除 Overlay{D69716CD-6993-4d0d-898F-5EBBC25C5D4D}锁定 Overlay{4E453CBA-2AAB-465c-A01E-627A7BE9ED73}已添加 Overlay{A38915E4-A460-4143-8D6B-0B45564C6A00}忽略 Overlay{1B94B098-57C6-4c39-9DC5-8EB00E423D3E}未版本化 Overlay{18BF1135-6EA2-405f-A71E-16EEE7F71F8B}InprocServer32 DLLTortoiseGitStub.dllTortoiseSVN来自用户提供的register.registry用途CLSID正常状态 Overlay{30351346-7B7D-4FCC-81B4-1E394CA267EB}已修改 Overlay{30351347-7B7D-4FCC-81B4-1E394CA267EB}冲突 Overlay{30351348-7B7D-4FCC-81B4-1E394CA267EB}右键菜单/属性页{30351349-7B7D-4FCC-81B4-1E394CA267EB}拖放处理{3035134A-7B7D-4FCC-81B4-1E394CA267EB}只读 Overlay{3035134B-7B7D-4FCC-81B4-1E394CA267EB}已删除 Overlay{3035134C-7B7D-4FCC-81B4-1E394CA267EB}锁定 Overlay{3035134D-7B7D-4FCC-81B4-1E394CA267EB}已添加 Overlay{3035134E-7B7D-4FCC-81B4-1E394CA267EB}忽略 Overlay{3035134F-7B7D-4FCC-81B4-1E394CA267EB}未版本化 Overlay{30351350-7B7D-4FCC-81B4-1E394CA267EB}InprocServer32 DLLTortoiseStub.dll最终目录结构D:\dev\tools\git\install\ ├── TortoiseGit\ │ ├── bin\ │ │ ├── TortoiseGit.dll # 主 Shell Extension DLL │ │ ├── TortoiseGitStub.dll # COM 注册用 Stub DLL │ │ ├── TortoiseGitProc.exe # 主程序 │ │ ├── TortoiseGitMerge.exe # 合并工具 │ │ └── TGitCache.exe # 缓存服务 │ ├── Languages\ │ └── register.reg # 注册表文件 │ └── TortoiseSVN\ ├── bin\ │ ├── TortoiseSVN.dll # 主 Shell Extension DLL │ ├── TortoiseStub.dll # COM 注册用 Stub DLL │ ├── TortoiseProc.exe # 主程序 │ ├── TortoiseMerge.exe # 合并工具 │ └── TSVNCache.exe # 缓存服务 ├── Languages\ └── register.reg # 注册表文件操作步骤总结# 1. 准备 .reg 文件路径替换为实际安装路径# 2. 以管理员权限导入注册表Start-Processreg-ArgumentListimport path\to\register.reg-Verb RunAs-Wait# 3. 重启资源管理器Stop-Process-Name explorer-ForceStart-Processexplorer踩坑记录regsvr32无效— 不是所有 DLL 都支持自注册需检查是否导出DllRegisterServerCLSID 不能从 DLL 二进制猜测— 从 DLL 中提取的 GUID 可能不是实际的 Shell Extension CLSID应从源码Guids.h或register.registry获取InprocServer32 指向 Stub DLL— TortoiseGit/SVN 的 COM 注册指向TortoiseStub.dll不是主 DLL需要管理员权限—regsvr32、reg import、reg add写 HKLM 都需要提权目录被锁定— 结束TSVNCache.exe/TGitCache.exe后才能移动文件资源管理器也可能锁目录参考资源TortoiseGit 源码:https://github.com/TortoiseGit/TortoiseGitShell Extension 注册表模板:src/TortoiseShell/register.registryGUID 定义:src/TortoiseShell/Guids.hWindows Shell Extension 文档:https://learn.microsoft.com/windows/win32/shell/shell-ext