在Win7中刷新Windows资源管理器

问题描述 投票:0回答:6

我的程序设置

"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); 

4)

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

没有任何作用。所以我该怎么做?如果我自己用 F5 刷新资源管理器,那么它就可以了。不过,我想要一些优雅的解决方案,这样它就会刷新各处的显示,即使是在当前打开的

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 资源管理器吗?

c# .net windows windows-7 windows-explorer
6个回答
19
投票

我找到了一种方法来检查窗口是否是 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);
            }
        }

2
投票

我不知道“打开/保存”对话框,但您可以使用 COM 自动化获取打开的资源管理器窗口的列表,Shell.Application对象有一个窗口集合,或者直接 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 窗口的示例

1
投票

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

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

0
投票

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


0
投票

添加@Adam答案https://stackoverflow.com/a/2863647/5514131,“Windows资源管理器”和“文件资源管理器”在非英语Windows版本上不起作用,我们需要获取本地化名称通过读取 explorer.exe MUI 资源文件来打开资源管理器窗口。

我们将使用

SHLoadIndirectString
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


0
投票

@Adam 的解决方案效果很好,谢谢。 但是,我们失去了资源管理器中的选择。有没有办法让我的文件夹在刷新后保持选中状态?

© www.soinside.com 2019 - 2024. All rights reserved.