重新加载之前无法加载的explorer.exe中的命名空间扩展

时间:2017-04-24 19:57:44

标签: windows explorer shell-extensions shell-namespace-extension

背景

我在MyComputer下找到了Shell Namespace Extensionusing a virtual folder as its junction point)。可以创建我的命名空间扩展的快捷方式。在这里,我用桌面上的快捷方式显示我的命名空间扩展。

Image showing a Namespace extension under "My Computer" in explorer with a shortcut

如果我的命名空间扩展名未安装,则我在安装时创建的快捷方式将无法解析。

Image showing the Namespace extension not installed and the unresolved shortcut

当我的应用程序启动时,它会将我的命名空间扩展安装到注册表中。退出时,它会从注册表中删除命名空间扩展。这对我的应用程序来说是必要的,因为根据配置的不同,每次运行时加载来表示我的命名空间扩展名的dll可能会有所不同。

问题

当我的应用程序正在运行并且explorer.exe遇到我的(当前未安装的)命名空间扩展的快捷方式时,它会尝试在注册表中查找COM组件(该快捷方式包含COM我的命名空间扩展的标识符) - 我通过Process Monitor观察到了这一点。稍后,当我的应用程序启动时,我的命名空间扩展名被添加到"我的电脑"正如所料,但它是无功能的 - 也就是说,尝试浏览它(双击)不能正常工作(什么也不做)。我通过Process Monitor观察到,explorer.exe没有重新尝试加载我的命名空间扩展。似乎explorer.exe记住它无法为我的命名空间扩展加载COM组件,因此它不会重试。在这种状态下的症状是:

  • 快捷方式显示为未解决的

  • 命名空间扩展名显示在“我的电脑”下,但双击它不起作用。

  • 命名空间扩展显示在左侧导航面板

Image showing what it looks like when the namespace extension is not working

我在此状态下找到解决问题的唯一方法是重新启动explorer.exe。

问题

有没有办法让explorer.exe重新加载我的命名空间扩展,因为它已经无法加载一次(由于未解决的快捷方式)而不必重新启动explorer.exe?

示例

以下是如何从头开始创建和观察问题的演练。这涉及使用"内置" Microsoft命名空间扩展称为Shell Instance Object(而不是我真正的命名空间扩展)。我使用它是为了简单,并表明它与我的特定命名空间扩展无关。所有这个示例命名空间扩展都会在"我的电脑"下创建一个图标。这将浏览到您的%TEMP%目录。

  1. 安装命名空间扩展并在"我的电脑"下注册。为此,请在注册表中输入以下内容:

    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"
    
  2. 此时,当您打开资源管理器窗口并浏览"我的电脑"时,您应该看到"我的命名空间扩展"。浏览它应该显示您的%TEMP%目录文件夹/文件。

  3. 在桌面上创建一个快捷方式的“我的命名空间扩展”"通过拖动"我的命名空间扩展"到桌面。

  4. 从注册表中完全删除命名空间扩展注册。您可以通过手动删除上述键或运行以下.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}]
    
  5. 此时重启explore.exe(或重启)。当explorer.exe启动时,它将尝试解析桌面上的快捷方式。在这样做时,它将尝试在HKEY_CURRENT_USER\Software\Classes\CLSID\{0672A6D1-A6E0-40FE-AB16-F25BADC6D9E4}找到COM组件,但它将无法找到。打开一个资源管理器窗口,访问"我的电脑"并观察"我的命名空间扩展"不存在。另请注意,快捷方式显示为未解析。

  6. 通过重新应用步骤1中的注册表更改来重新安装命名空间扩展。

  7. 刷新您的计算机"窗口。此时,您将处于有问题的状态,您可以在"我的电脑"下看到命名空间扩展名,但尝试浏览它不起作用。

  8. 如果此时重新启动explorer.exe,问题就会消失。这是因为当explorer.exe尝试解析快捷方式时,它能够加载命名空间扩展COM组件,因为它当前已在注册表中注册。

  9. 附加说明

    • 我真正的命名空间扩展是用C ++编写的。

    • 我使用SHChangeNotify让命名空间扩展名出现/消失在"我的电脑"无需手动刷新,但不会导致命名空间扩展尝试重新加载。

    • 也许令人惊讶的是,使用desktop.ini approach with .ShellClassInfo and CLSID注册的命名空间扩展似乎没有遇到此问题。不幸的是,我不能使用这种方法,因为我需要在"我的电脑"。

    • 下使用我的命名空间扩展名。

1 个答案:

答案 0 :(得分:1)

你必须翻阅Shell文档(总是一件苦差事)才能找到SHFlushSFCache()

  

更改特殊文件夹的路径时,将调用SHFlushSFCache。这可确保使用存储在注册表中的更新路径而不是缓存值。

不幸的是,这个例程被标记为“折旧”,但它似乎仍然可以在Windows 10上运行。

在(重新)注册命名空间后调用SHFlushSFCache();这应该强制 explorer.exe 重新加载它。