Reputation: 5222
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.
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...
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?
Upvotes: 17
Views: 12589
Reputation: 438
Adding to @Adam answer https://stackoverflow.com/a/2863647/5514131, "Windows Explorer" and "File Explorer" won't work on non-English Windows versions, we need to get the localized name of the Explorer window by reading the explorer.exe MUI resource file.
We will use SHLoadIndirectString
API to read the text resource from explorer.exe.mui file.
[DllImport("shlwapi.dll", CharSet = CharSet.Unicode, ExactSpelling = true)]
public static extern int SHLoadIndirectString(string pszSource, StringBuilder pszOutBuf, int cchOutBuf, IntPtr ppvReserved);
static void Main(string[] args)
{
var resourcePath = @"@%SystemRoot%\en-US\explorer.exe.mui,-6020"; //en-US should be replaced with the current Windows language code
resourcePath = Environment.ExpandEnvironmentVariables(resourcePath);
StringBuilder outBuff = new StringBuilder(1024);
var result = SHLoadIndirectString(resourcePath, outBuff, outBuff.Capacity, IntPtr.Zero);
if (result == 0)
{
Console.WriteLine(outBuff.ToString());
}
else
{
Console.WriteLine("SHLoadIndirectString method failed, error code: {0}", result);
}
Console.ReadLine();
}
On Windows 10, this will output: File Explorer
Upvotes: 0
Reputation: 51
With Windows 10 having changed the name of the Explorer window:
if ((itemName == "Windows Explorer") || (itemName == "File Explorer")) {
itemType.InvokeMember("Refresh", System.Reflection.BindingFlags.InvokeMethod, null, item, null);
}
Upvotes: 1
Reputation: 629
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);
}
}
Upvotes: 19
Reputation: 545
When you install an application that registers a file type, Explorer windows often refresh to indicate the new association - could you spy on the API calls that an installer is making to see how it refreshes the window?
Upvotes: 0
Reputation: 101756
I don't know about Open/Save dialogs, but you can get a list of open explorer windows with COM automation, the Shell.Application object has a collection of windows, or CoCreate IID_IShellWindows directly, each window in the list has a refresh method.
WSH/JScript:
for(var sw=new ActiveXObject("Shell.Application").Windows(),i=0;i<sw.Count; ++i)
sw.Item(i).Refresh();
I don't know about C#, but here are examples dealing with shell windows in WSH/JScript and c++
Upvotes: 2