I am using SHChangeNotify
with SHCNE_RMDIR
to notify the shell of a folder that has been removed from within my shell namespace extension. My expectation is that this will cause any explorer (or other shell) windows which have their folder view navigated into the removed folder (or any of its sub folders) to be navigated to the parent folder of the removed folder. This expected behavior is occurring on Windows 10. However, on Windows 7 those windows are being navigated to the removed folder.
Is this behavior on Windows 7 a bug, and/or is there something I can do (without having special code for Windows 7) to get the same behavior for both OSes?
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.
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"
The following .reg file will allow you to easily remove the above registry entries:
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}]
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.
Create a directory in your %TEMP%
folder called FolderToRemove
. Within FolderToRemove
create a sub folder called subFolder
.
Open 3 explorer windows and browse to the following locations:
On Windows 7, Execute the following C++ code:
// This path represents My Computer\My Namespace Extension\FolderToRemove
const wchar_t * pPath = L"::{20d04fe0-3aea-1069-a2d8-08002b30309d}\\::{0672A6D1-A6E0-40FE-AB16-F25BADC6D9E4}\\FolderToRemove";
SHChangeNotify(SHCNE_RMDIR, SHCNF_PATH, pPath, NULL);
After having executed the above code, you'll notice that the only explorer window that changed was the one that was originally navigated into My Computer\My Namespace Extension\FolderToRemove\subFolder
. Notice that it is now pointing to My Computer\My Namespace Extension\FolderToRemove
:
The expectation is for two of the explorer windows to have changed, such that they are all navigated to My Computer\My Namespace Extension
(the parent folder of the the removed folder). Here is an image of the expected behavior (which is what happens on Windows 10):
I found that I can get the behavior I want for Windows 7 by specifying the parent folder of the removed folder in the SHChangeNotify
. E.g.:
// This path represents My Computer\My Namespace Extension
const wchar_t * pPath = L"::{20d04fe0-3aea-1069-a2d8-08002b30309d}\\::{0672A6D1-A6E0-40FE-AB16-F25BADC6D9E4}";
SHChangeNotify(SHCNE_RMDIR, SHCNF_PATH, pPath, NULL);
But when I execute this code on Windows 10 it, of course, causes the windows to be navigated back to My Computer
which is undesired. If I went with this workaround I would need different code for different OSes.
As part of a Microsoft Support case, I was given the following information, which describes how Explorer reacts in this workflow. It, however, doesn't give any reasoning as to why Windows 10 behaves differently:
For any browser window navigated to the folder specified in the SHCNE_RMDIR notification or one of its descendants, Explorer will navigate the browser window to a valid (ancestor) folder. The process for determining the new folder to open in an Explorer browser window, starting with the absolute ITEMIDLIST of folder specified in the SCHNE_RMDIR notification, is:
In the repro steps you posted to StackOverflow, we have Explorer browser windows opened to the following folders:
::{CLSID_MyComputer}::{CLSID_My Namespace Extension}
::{CLSID_MyComputer}::{CLSID_My Namespace Extension}\FolderToRemove
::{CLSID_MyComputer}::{CLSID_My Namespace Extension}\FolderToRemove\subFolder
Here is how the SHCNE_RMDIR notification for the
::{CLSID_MyComputer}\::{CLSID_My Namespace Extension}\FolderToRemove
folder is processed by the browser windows:
Browser window navigated to ::{CLSID_MyComputer}\::{CLSID_My Namespace Extension}
:
Browser window navigated to ::{CLSID_MyComputer}\::{CLSID_My Namespace Extension}\FolderToRemove
Browser window navigated to ::{CLSID_MyComputer}\::{CLSID_My Namespace Extension}\FolderToRemove\subFolder
User contributions licensed under CC BY-SA 3.0