在 explorer.exe 中重新加载先前未能加载的命名空间扩展
Reload a namespace extension in explorer.exe that failed to load previously
背景
我的电脑下有一个 Shell Namespace Extension that is located (using a virtual folder as its junction point)。可以为我的命名空间扩展创建一个快捷方式。这里我用桌面上的快捷方式显示我的命名空间扩展。
如果我的命名空间扩展没有安装,我在安装它时创建的快捷方式将无法正常解析。
当我的应用程序启动时,它会将我的名称空间扩展安装到注册表中。当它退出时,它会从注册表中删除名称空间扩展。这对我的应用程序来说是必需的,因为加载的 dll 代表我的命名空间扩展可能在每个 运行 上都不同,具体取决于配置。
问题
当我的应用程序 not 运行ning 并且 explorer.exe 遇到我的(当前未安装的)命名空间扩展的快捷方式时,它会尝试查找COM 组件的注册表(快捷方式包含我的名称空间扩展的 COM 标识符)——我通过 Process Monitor 观察到了这一点。后来,当我的应用程序启动时,我的名称空间扩展按预期添加到 "My Computer" 下,但它不起作用——也就是说,尝试浏览它(双击)不能正常工作(什么都不做).我通过 Process Monitor 的观察显示 explorer.exe 没有重新尝试加载我的名称空间扩展。似乎 explorer.exe 记得它未能为我的命名空间扩展加载 COM 组件,因此它不会重试。处于这种状态时的症状是:
快捷方式显示为未解决
命名空间扩展显示在“我的电脑”下,但双击它不起作用。
- 命名空间扩展没有显示在左侧导航面板中
一旦我处于这种状态,我发现解决问题的唯一方法是重新启动 explorer.exe。
问题
有没有办法让 explorer.exe 在它已经加载失败一次后(由于未解析的快捷方式)重试加载我的命名空间扩展而不必重新启动 explorer.exe ?
一个例子
以下是如何从头开始创建和观察问题的演练。这涉及使用称为 Shell Instance Object 的 "built in" Microsoft 名称空间扩展(而不是我真正的名称空间扩展)。我使用它是为了简单起见,也是为了表明它与我的特定命名空间扩展无关。这个命名空间扩展示例所做的只是在 "My Computer" 下创建一个图标,该图标将浏览到您的 %TEMP% 目录。
安装命名空间扩展并在 "My Computer" 下注册。为此,请在注册表中输入以下内容:
HKEY_CURRENT_USER\Software\Classes\CLSID
{0672A6D1-A6E0-40FE-AB16-F25BADC6D9E4}=REG_SZ_EXPAND:"My Namespace Extension"
DescriptionID=REG_DWORD:0x00000008
System.IsPinnedToNameSpaceTree=REG_DWORD:0x00000001
DefaultIcon=REG_EXPAND_SZ:"%SystemRoot%\system32\main.cpl,9"
InProcServer32=REG_EXPAND_SZ:"%SystemRoot%\system32\shdocvw.dll"
ThreadingModel=REG_SZ:"Apartment"
ShellFolder
Attributes=REG_DWORD:0x60000000
Instance
CLSID=REG_SZ:"{0AFACED1-E828-11D1-9187-B532F1E9575D}"
InitPropertyBag
Attributes=REG_DWORD:0x00000011
Target=REG_SZ_EXPAND:"%TEMP%"
这是一个 .reg 文件,可以为您自动完成:
Windows Registry Editor Version 5.00
[HKEY_CURRENT_USER\Software\Classes\CLSID\{0672A6D1-A6E0-40FE-AB16-F25BADC6D9E4}]
@="My Namespace Extension"
"System.IsPinnedToNameSpaceTree"=dword:00000001
"DescriptionID"=dword:00000008
[HKEY_CURRENT_USER\Software\Classes\CLSID\{0672A6D1-A6E0-40FE-AB16-F25BADC6D9E4}\DefaultIcon]
@=hex(2):25,00,53,00,79,00,73,00,74,00,65,00,6d,00,52,00,6f,00,6f,00,74,00,25,\
00,5c,00,73,00,79,00,73,00,74,00,65,00,6d,00,33,00,32,00,5c,00,6d,00,61,00,\
69,00,6e,00,2e,00,63,00,70,00,6c,00,2c,00,39,00,00,00
[HKEY_CURRENT_USER\Software\Classes\CLSID\{0672A6D1-A6E0-40FE-AB16-F25BADC6D9E4}\InProcServer32]
@=hex(2):25,00,53,00,79,00,73,00,74,00,65,00,6d,00,52,00,6f,00,6f,00,74,00,25,\
00,5c,00,73,00,79,00,73,00,74,00,65,00,6d,00,33,00,32,00,5c,00,73,00,68,00,\
64,00,6f,00,63,00,76,00,77,00,2e,00,64,00,6c,00,6c,00,00,00
"ThreadingModel"="Apartment"
[HKEY_CURRENT_USER\Software\Classes\CLSID\{0672A6D1-A6E0-40FE-AB16-F25BADC6D9E4}\Instance]
"CLSID"="{0AFACED1-E828-11D1-9187-B532F1E9575D}"
[HKEY_CURRENT_USER\Software\Classes\CLSID\{0672A6D1-A6E0-40FE-AB16-F25BADC6D9E4}\Instance\InitPropertyBag]
"Attributes"=dword:00000011
"Target"=hex(2):25,00,54,00,45,00,4d,00,50,00,25,00,00,00
[HKEY_CURRENT_USER\Software\Classes\CLSID\{0672A6D1-A6E0-40FE-AB16-F25BADC6D9E4}\ShellFolder]
"Attributes"=dword:60000000
[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\MyComputer\Namespace\{0672A6D1-A6E0-40FE-AB16-F25BADC6D9E4}]
@="My Namespace Extension"
此时,当您打开资源管理器 Window 并浏览 "My Computer" 时,您应该会看到 "My Namespace Extension"。浏览它应该会显示您的 %TEMP% 目录 folders/files.
通过将 "My Namespace Extension" 拖动到桌面,在您的桌面上创建指向 "My Namespace Extension" 的快捷方式。
从注册表中完全删除名称空间扩展注册。您可以通过手动删除上述键或通过 运行 下列 .reg 文件来做到这一点:
Windows Registry Editor Version 5.00
[-HKEY_CURRENT_USER\Software\Classes\CLSID\{0672A6D1-A6E0-40FE-AB16-F25BADC6D9E4}]
[-HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\MyComputer\Namespace\{0672A6D1-A6E0-40FE-AB16-F25BADC6D9E4}]
此时重新启动 explore.exe(或重新启动)。当 explorer.exe 启动时,它会尝试解析您桌面上的快捷方式。这样做时,它会尝试在 HKEY_CURRENT_USER\Software\Classes\CLSID\{0672A6D1-A6E0-40FE-AB16-F25BADC6D9E4}
定位 COM 组件,但无法定位。打开资源管理器 window 到 "My Computer" 并观察 "My Namespace Extension" 不存在。另请注意,快捷方式显示为未解析。
通过重新应用步骤 1 中的注册表更改来重新安装命名空间扩展。
刷新你的"My Computer"window。此时您将处于有问题的状态,您可以在 "My Computer" 下看到名称空间扩展,但尝试浏览它不起作用。
如果此时重新启动 explorer.exe,问题就会消失。这是因为当 explorer.exe 尝试解析快捷方式时,它能够加载命名空间扩展 COM 组件,因为它当前已在注册表中注册。
补充说明
我真正的命名空间扩展是用C++写的。
我正在使用 SHChangeNotify 将命名空间扩展到 "My Computer" 下的 appear/disappear 而无需手动刷新,但这不会导致命名空间扩展尝试重新加载。
也许令人惊讶的是,使用 desktop.ini approach with .ShellClassInfo and CLSID 注册的命名空间扩展似乎没有遇到此问题。不幸的是,我不能使用这种方法,因为我需要在 "My Computer".
下进行命名空间扩展
您必须大量翻阅 Shell 文档(总是一件苦差事)才能找到 SHFlushSFCache()
。
SHFlushSFCache is called when the path to a special folder is changed. This ensures that the updated path stored in the registry is used rather than the cached value.
不幸的是,这个例程被标记为 "depreciated",但它似乎仍然适用于 Windows 10.
在(重新)注册您的命名空间后调用 SHFlushSFCache()
;那应该强制 explorer.exe 重新加载它。
背景
我的电脑下有一个 Shell Namespace Extension that is located (using a virtual folder as its junction point)。可以为我的命名空间扩展创建一个快捷方式。这里我用桌面上的快捷方式显示我的命名空间扩展。
如果我的命名空间扩展没有安装,我在安装它时创建的快捷方式将无法正常解析。
当我的应用程序启动时,它会将我的名称空间扩展安装到注册表中。当它退出时,它会从注册表中删除名称空间扩展。这对我的应用程序来说是必需的,因为加载的 dll 代表我的命名空间扩展可能在每个 运行 上都不同,具体取决于配置。
问题
当我的应用程序 not 运行ning 并且 explorer.exe 遇到我的(当前未安装的)命名空间扩展的快捷方式时,它会尝试查找COM 组件的注册表(快捷方式包含我的名称空间扩展的 COM 标识符)——我通过 Process Monitor 观察到了这一点。后来,当我的应用程序启动时,我的名称空间扩展按预期添加到 "My Computer" 下,但它不起作用——也就是说,尝试浏览它(双击)不能正常工作(什么都不做).我通过 Process Monitor 的观察显示 explorer.exe 没有重新尝试加载我的名称空间扩展。似乎 explorer.exe 记得它未能为我的命名空间扩展加载 COM 组件,因此它不会重试。处于这种状态时的症状是:
快捷方式显示为未解决
命名空间扩展显示在“我的电脑”下,但双击它不起作用。
- 命名空间扩展没有显示在左侧导航面板中
一旦我处于这种状态,我发现解决问题的唯一方法是重新启动 explorer.exe。
问题
有没有办法让 explorer.exe 在它已经加载失败一次后(由于未解析的快捷方式)重试加载我的命名空间扩展而不必重新启动 explorer.exe ?
一个例子
以下是如何从头开始创建和观察问题的演练。这涉及使用称为 Shell Instance Object 的 "built in" Microsoft 名称空间扩展(而不是我真正的名称空间扩展)。我使用它是为了简单起见,也是为了表明它与我的特定命名空间扩展无关。这个命名空间扩展示例所做的只是在 "My Computer" 下创建一个图标,该图标将浏览到您的 %TEMP% 目录。
安装命名空间扩展并在 "My Computer" 下注册。为此,请在注册表中输入以下内容:
HKEY_CURRENT_USER\Software\Classes\CLSID {0672A6D1-A6E0-40FE-AB16-F25BADC6D9E4}=REG_SZ_EXPAND:"My Namespace Extension" DescriptionID=REG_DWORD:0x00000008 System.IsPinnedToNameSpaceTree=REG_DWORD:0x00000001 DefaultIcon=REG_EXPAND_SZ:"%SystemRoot%\system32\main.cpl,9" InProcServer32=REG_EXPAND_SZ:"%SystemRoot%\system32\shdocvw.dll" ThreadingModel=REG_SZ:"Apartment" ShellFolder Attributes=REG_DWORD:0x60000000 Instance CLSID=REG_SZ:"{0AFACED1-E828-11D1-9187-B532F1E9575D}" InitPropertyBag Attributes=REG_DWORD:0x00000011 Target=REG_SZ_EXPAND:"%TEMP%"
这是一个 .reg 文件,可以为您自动完成:
Windows Registry Editor Version 5.00 [HKEY_CURRENT_USER\Software\Classes\CLSID\{0672A6D1-A6E0-40FE-AB16-F25BADC6D9E4}] @="My Namespace Extension" "System.IsPinnedToNameSpaceTree"=dword:00000001 "DescriptionID"=dword:00000008 [HKEY_CURRENT_USER\Software\Classes\CLSID\{0672A6D1-A6E0-40FE-AB16-F25BADC6D9E4}\DefaultIcon] @=hex(2):25,00,53,00,79,00,73,00,74,00,65,00,6d,00,52,00,6f,00,6f,00,74,00,25,\ 00,5c,00,73,00,79,00,73,00,74,00,65,00,6d,00,33,00,32,00,5c,00,6d,00,61,00,\ 69,00,6e,00,2e,00,63,00,70,00,6c,00,2c,00,39,00,00,00 [HKEY_CURRENT_USER\Software\Classes\CLSID\{0672A6D1-A6E0-40FE-AB16-F25BADC6D9E4}\InProcServer32] @=hex(2):25,00,53,00,79,00,73,00,74,00,65,00,6d,00,52,00,6f,00,6f,00,74,00,25,\ 00,5c,00,73,00,79,00,73,00,74,00,65,00,6d,00,33,00,32,00,5c,00,73,00,68,00,\ 64,00,6f,00,63,00,76,00,77,00,2e,00,64,00,6c,00,6c,00,00,00 "ThreadingModel"="Apartment" [HKEY_CURRENT_USER\Software\Classes\CLSID\{0672A6D1-A6E0-40FE-AB16-F25BADC6D9E4}\Instance] "CLSID"="{0AFACED1-E828-11D1-9187-B532F1E9575D}" [HKEY_CURRENT_USER\Software\Classes\CLSID\{0672A6D1-A6E0-40FE-AB16-F25BADC6D9E4}\Instance\InitPropertyBag] "Attributes"=dword:00000011 "Target"=hex(2):25,00,54,00,45,00,4d,00,50,00,25,00,00,00 [HKEY_CURRENT_USER\Software\Classes\CLSID\{0672A6D1-A6E0-40FE-AB16-F25BADC6D9E4}\ShellFolder] "Attributes"=dword:60000000 [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\MyComputer\Namespace\{0672A6D1-A6E0-40FE-AB16-F25BADC6D9E4}] @="My Namespace Extension"
此时,当您打开资源管理器 Window 并浏览 "My Computer" 时,您应该会看到 "My Namespace Extension"。浏览它应该会显示您的 %TEMP% 目录 folders/files.
通过将 "My Namespace Extension" 拖动到桌面,在您的桌面上创建指向 "My Namespace Extension" 的快捷方式。
从注册表中完全删除名称空间扩展注册。您可以通过手动删除上述键或通过 运行 下列 .reg 文件来做到这一点:
Windows Registry Editor Version 5.00 [-HKEY_CURRENT_USER\Software\Classes\CLSID\{0672A6D1-A6E0-40FE-AB16-F25BADC6D9E4}] [-HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\MyComputer\Namespace\{0672A6D1-A6E0-40FE-AB16-F25BADC6D9E4}]
此时重新启动 explore.exe(或重新启动)。当 explorer.exe 启动时,它会尝试解析您桌面上的快捷方式。这样做时,它会尝试在
HKEY_CURRENT_USER\Software\Classes\CLSID\{0672A6D1-A6E0-40FE-AB16-F25BADC6D9E4}
定位 COM 组件,但无法定位。打开资源管理器 window 到 "My Computer" 并观察 "My Namespace Extension" 不存在。另请注意,快捷方式显示为未解析。通过重新应用步骤 1 中的注册表更改来重新安装命名空间扩展。
刷新你的"My Computer"window。此时您将处于有问题的状态,您可以在 "My Computer" 下看到名称空间扩展,但尝试浏览它不起作用。
如果此时重新启动 explorer.exe,问题就会消失。这是因为当 explorer.exe 尝试解析快捷方式时,它能够加载命名空间扩展 COM 组件,因为它当前已在注册表中注册。
补充说明
我真正的命名空间扩展是用C++写的。
我正在使用 SHChangeNotify 将命名空间扩展到 "My Computer" 下的 appear/disappear 而无需手动刷新,但这不会导致命名空间扩展尝试重新加载。
也许令人惊讶的是,使用 desktop.ini approach with .ShellClassInfo and CLSID 注册的命名空间扩展似乎没有遇到此问题。不幸的是,我不能使用这种方法,因为我需要在 "My Computer".
下进行命名空间扩展
您必须大量翻阅 Shell 文档(总是一件苦差事)才能找到 SHFlushSFCache()
。
SHFlushSFCache is called when the path to a special folder is changed. This ensures that the updated path stored in the registry is used rather than the cached value.
不幸的是,这个例程被标记为 "depreciated",但它似乎仍然适用于 Windows 10.
在(重新)注册您的命名空间后调用 SHFlushSFCache()
;那应该强制 explorer.exe 重新加载它。