Search code examples
c#.netwindowswindows-7windows-explorer

Refresh Windows Explorer in Win7


My program sets "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" value "Hidden". Hovewer I'm not able to refresh the explorer to take into account this change. I've tried:

1)

    SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, IntPtr.Zero, IntPtr.Zero);` 

2)

    SHELLSTATE state = new SHELLSTATE(); 
    state.fShowAllObjects = (uint)1; 
    SHGetSetSettings(ref state, SSF.SSF_SHOWALLOBJECTS, true); 

3)

    SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, SPI_SETNONCLIENTMETRICS, 0, SMTO_ABORTIFHUNG, 5000, ref dwResult); 

4)

    SendMessage(HWND_BROADCAST, WM_COMMAND, 28931 /* Refresh */, 0); 

Nothing works. So what should I do? If I refresh Explorer myself with F5, then it works. Hovewer I would like some elegant solution, so it would refresh the display everywhere, even in OpenFile/SaveFile dialogs, which are currently open.

I'm using C# .NET, Win7.

Status Update #1

As Anders pointed out, there is a simple way to refresh explorer windows using COM:

Guid CLSID_ShellApplication = new Guid("13709620-C279-11CE-A49E-444553540000");
Type shellApplicationType = Type.GetTypeFromCLSID(CLSID_ShellApplication, true);
dynamic shellApplication = Activator.CreateInstance(shellApplicationType);
dynamic windows = shellApplication.Windows();
for (int i = 0; i < windows.Count; i++)
    windows.Item(i).Refresh();

So this part is done. Hovewer I still need to refresh the OpenFile/SaveFile dialogs, and the code above doesn't do that. Does anybody know how to refresh those dialogs?

An important point is that if I change the "Show Hidden Files" in Folder Options in Control panel, those OpenFile/SaveFile dialogs are not refreshed by the system, I must refresh them manually using F5. I'm just looking for a method how to refresh all those dialogs using C#, so I don't need to press F5 anymore...

Status Update #2

Ok, so new problem with the code above - it refresh not only windows explorers, but also internet explorers... Any idea how to refresh windows explorers ONLY?


Solution

  • I figured out a way to check if the windows was a Windows Explorer window, and don't have enough of a rep to add a comment so thought I'd submit it as an answer to help you out because this question helped me out.

            // based on http://stackoverflow.com/questions/2488727/refresh-windows-explorer-in-win7
            Guid CLSID_ShellApplication = new Guid("13709620-C279-11CE-A49E-444553540000");
            Type shellApplicationType = Type.GetTypeFromCLSID(CLSID_ShellApplication, true);
    
            object shellApplication = Activator.CreateInstance(shellApplicationType);
            object windows = shellApplicationType.InvokeMember("Windows", System.Reflection.BindingFlags.InvokeMethod, null, shellApplication, new object[] { });
    
            Type windowsType = windows.GetType();
            object count = windowsType.InvokeMember("Count", System.Reflection.BindingFlags.GetProperty, null, windows, null);
            for (int i = 0; i < (int)count; i++)
            {
                object item = windowsType.InvokeMember("Item", System.Reflection.BindingFlags.InvokeMethod, null, windows, new object[] { i });
                Type itemType = item.GetType();
    
                // only refresh windows explorers
                string itemName = (string)itemType.InvokeMember("Name", System.Reflection.BindingFlags.GetProperty, null, item, null);
                if (itemName == "Windows Explorer")
                {
                    itemType.InvokeMember("Refresh", System.Reflection.BindingFlags.InvokeMethod, null, item, null);
                }
            }