在Win7中刷新Windows资源管理器

ejk8hzay  于 2023-04-13  发布在  Windows
关注(0)|答案(5)|浏览(216)

我的程序设置了"HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced""Hidden"。但是我无法刷新资源管理器来考虑这个变化。我试过:
(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);

(四)

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

什么都不起作用。那么我该怎么办?如果我用F5刷新Explorer,那么它就起作用了。但是我想要一些优雅的解决方案,这样它就可以在任何地方刷新显示,即使是在当前打开的OpenFile/SaveFile对话框中。
我使用C# .NET,Win7。

状态更新#1

正如Anders所指出的,有一种使用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();

这部分已经完成了。但是我还需要刷新OpenFile/SaveFile对话框,上面的代码没有做到这一点。有人知道如何刷新这些对话框吗?
重要的一点是,如果我改变了“显示隐藏文件”在文件夹选项在控制面板,那些OpenFile/SaveFile对话框不刷新系统,我必须手动刷新它们使用F5.我只是在寻找一种方法,如何刷新所有这些对话框使用C#,所以我不需要按F5了...

状态更新#2

好的,上面的代码有个新问题--它不仅刷新windows资源管理器,还刷新internet资源管理器......你知道如何只刷新windows资源管理器吗?

ukxgm1gy

ukxgm1gy1#

我想出了一个方法来检查窗口是否是Windows资源管理器窗口,并且没有足够的代表添加评论,所以我认为我会提交它作为答案来帮助你,因为这个问题帮助了我。

// 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);
            }
        }
zf9nrax1

zf9nrax12#

我不知道打开/保存对话框,但你可以通过COM自动化获得一个打开的资源管理器窗口列表,Shell.Application对象有一个collection of windows,或者直接CoCreate IID_IShellWindows,列表中的每个窗口都有一个刷新方法。
WSH/JScript:

for(var sw=new ActiveXObject("Shell.Application").Windows(),i=0;i<sw.Count; ++i)
   sw.Item(i).Refresh();

我不了解C#,但这里有一些在WSH/JScriptc++中处理shell窗口的示例

e1xvtsh3

e1xvtsh33#

Windows 10更改了资源管理器窗口的名称:

if ((itemName == "Windows Explorer") || (itemName == "File Explorer")) {
    itemType.InvokeMember("Refresh", System.Reflection.BindingFlags.InvokeMethod, null, item, null);
}
wgmfuz8q

wgmfuz8q4#

当你安装一个注册文件类型的应用程序时,资源管理器窗口经常刷新以指示新的关联-你能监视安装程序正在进行的API调用以查看它是如何刷新窗口的吗?

lyr7nygr

lyr7nygr5#

添加到@Adam answer https://stackoverflow.com/a/2863647/5514131,“Windows资源管理器”和“文件资源管理器”在非英语Windows版本上不起作用,我们需要通过阅读explorer.exe MUI资源文件来获取资源管理器窗口的本地化名称。
我们将使用x1e1 f1 API从explorer.exe.mui文件中读取文本资源。

[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();

    }

在Windows 10上,这将输出:File Explorer

相关问题