Reload a namespace extension in explorer.exe that failed to load previously

自古美人都是妖i 提交于 2019-12-11 00:19:33

问题


Background

I have a Shell Namespace Extension that is located (using a virtual folder as its junction point) under MyComputer. It is possible to create a shortcut to my namespace extension. Here I show my namespace extension with a shortcut on the desktop.

If my namespace extension is not installed, the shortcut that I created when it was installed will be unresolved as expected.

When my application starts up, it installs my namespace extension into the registry. When it exits, it removes the namespace extension from the registry. This is necessary for my application because the dll loaded to represent my namespace extension may be different on each run depending on configuration.

The Issue

When my application is not running and explorer.exe encounters the shortcut to my (not currently installed) namespace extension, it attempts to look in the registry for the COM component (the shortcut contains the COM identifier for my namespace extension)--I observed this via Process Monitor. Later, when my application starts up, my namespace extension is added under "My Computer" as expected, but it is non-functional--that is, trying to browse into it (double click) does not work as normal (does nothing). My observation via Process Monitor shows that explorer.exe did not re-attempt to load my namespace extension. It seems that explorer.exe is remembering that it failed to load the COM component for my namespace extension, and thus it will not retry. The symptoms when in this state are:

  • The shortcut shows up as unresolved

  • The namespace extension shows up under My Computer, but double clicking on it does not work.

  • The namespace extension does not show up in the left navigation panel

The only way I've found to resolve the issue once I'm in this state is to restart explorer.exe.

Question

Is there a way to get explorer.exe to retry to load my namespace extension once it has already failed to load it once (due to the unresolved short-cut) without having to restart explorer.exe?

An Example

Here is a walk through of how to create and observe the issue from scratch. This involves using a "built in" Microsoft namespace extension called a Shell Instance Object (rather than my real namespace extension). I used this for simplicity as well as to show that it is not related to my specific namespace extension. All this sample namespace extension does is creates an icon under "My Computer" that will browse into your %TEMP% directory.

  1. Install the namespace extension and register it under "My Computer". To do this, enter the following into the registry:

    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%"
    

    Here is a .reg file that will automate that for you:

    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. At this point, when you open an explorer Window and navigate through "My Computer", you should see the "My Namespace Extension". Browsing into it should reveal your %TEMP% directory folders/files.

  3. Create a shortcut on your desktop to the "My Namespace Extension" by dragging the "My Namespace Extension" to the desktop.

  4. Completely remove the namespace extension registration from the registry. You can do that by manually removing the above keys or by running the following .reg file:

    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. Restart explore.exe at this point (or do a reboot). When explorer.exe starts up, it will try to resolve the shortcut on your desktop. In doing so, it will attempt to locate the COM component at HKEY_CURRENT_USER\Software\Classes\CLSID\{0672A6D1-A6E0-40FE-AB16-F25BADC6D9E4}, but it will be unable to. Open an explorer window to "My Computer" and observe that the "My Namespace Extension" does not exist. Also notice that the shortcut shows as unresolved.

  6. Re-install the namespace extension by re-applying the registry changes from step 1.

  7. Refresh your "My Computer" window. At this point you will be in the problematic state where you can see the namespace extension under "My Computer", but trying to browse into it does not work.

  8. If you restart explorer.exe at this point, the issue will go away. This is because when explorer.exe tries to resolve the shortcut it is able to load the namespace extension COM component because it is currently registered in the registry.

Additional notes

  • My real namespace extension is written in C++.

  • I'm using SHChangeNotify to get the namespace extension to appear/disappear under "My Computer" without requiring a manual refresh, but that does not cause the namespace extension to attempt to reload.

  • Perhaps surprisingly, namespace extensions that are registered using the desktop.ini approach with .ShellClassInfo and CLSID does not appear to suffer from this problem. Unfortunately, I cannot use this approach as I need to have my namespace extension under "My Computer".


回答1:


You've got to rummage through the Shell documentation quite a bit (always a chore) to find 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.

Unfortunately, this routine is marked as "depreciated", but it still seems to work on Windows 10.

Call SHFlushSFCache() after (re-)registering your namespace; that should force explorer.exe to reload it.



来源:https://stackoverflow.com/questions/43596688/reload-a-namespace-extension-in-explorer-exe-that-failed-to-load-previously

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!