Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/274.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何刷新/重新加载桌面_C#_Wpf_Desktop - Fatal编程技术网

C# 如何刷新/重新加载桌面

C# 如何刷新/重新加载桌面,c#,wpf,desktop,C#,Wpf,Desktop,我有一个WPF C#项目,我正在其中实现Windows文件夹选项的设置。其中之一是“单击打开项目”(而不是双击)。当我为此更改注册表项时,我需要刷新我找到解决方案的Windows资源管理器。但桌面不会刷新,甚至手动刷新也不会应用更改。 我使用了IActiveDesktop::ApplyChanges方法,但不起作用(或者可能是我弄错了)。我也使用了此代码段,但它仍然没有应用我所做的更改: SHChangeNotify(0x8000000, 0x1000, IntPtr.Zero, IntPtr.

我有一个WPF C#项目,我正在其中实现Windows文件夹选项的设置。其中之一是“单击打开项目”(而不是双击)。当我为此更改注册表项时,我需要刷新我找到解决方案的Windows资源管理器。但桌面不会刷新,甚至手动刷新也不会应用更改。 我使用了
IActiveDesktop::ApplyChanges
方法,但不起作用(或者可能是我弄错了)。我也使用了此代码段,但它仍然没有应用我所做的更改:

SHChangeNotify(0x8000000, 0x1000, IntPtr.Zero, IntPtr.Zero);
下面是我用来刷新Windows资源管理器的完整代码段(来自此网站):

[System.Runtime.InteropServices.DllImport(“Shell32.dll”)]
私有静态外部int SHCHANGETNOTIFY(int事件ID、int标志、IntPtr项目1、IntPtr项目2);
公共静态无效刷新WindowsExplorer()
{
//刷新桌面
SHChangeNotify(0x8000000、0x1000、IntPtr.Zero、IntPtr.Zero);
//刷新任何打开的资源管理器窗口
//基于http://stackoverflow.com/questions/2488727/refresh-windows-explorer-in-win7
Guid CLSID_ShellApplication=新Guid(“13709620-C279-11CE-A49E-444553540000”);
类型shellApplicationType=Type.GetTypeFromCLSID(CLSID\u ShellApplication,true);
对象shellApplication=Activator.CreateInstance(shellApplicationType);
对象windows=shellApplicationType.InvokeMember(“windows”,System.Reflection.BindingFlags.InvokeMethod,null,shellApplication,新对象[]{});
类型windowsType=windows.GetType();
对象计数=windowsType.InvokeMember(“计数”,System.Reflection.BindingFlags.GetProperty,null,windows,null);
对于(int i=0;i<(int)计数;i++)
{
object item=windowsType.InvokeMember(“item”,System.Reflection.BindingFlags.InvokeMethod,null,windows,新对象[]{i});
Type itemType=item.GetType();
//仅刷新Windows资源管理器,不检查名称,这可能会刷新打开的IE窗口
string itemName=(string)itemType.InvokeMember(“Name”,System.Reflection.BindingFlags.GetProperty,null,item,null);
如果(itemName==“Windows资源管理器”)
{
InvokeMember(“刷新”,System.Reflection.BindingFlags.InvokeMethod,null,item,null);
}
}
}
这适用于Windows资源管理器,但不适用于桌面(这很奇怪,因为桌面也依赖于资源管理器)。
那么,我应该如何重新加载桌面以使我的更改生效呢?

如果您发布了更改该设置的代码,我会在回复之前根据以下建议对其进行测试

您是否尝试过:

1) 从上述代码中删除语句
if(itemName==“Windows资源管理器”)
,以便刷新每个窗口(包括桌面)

2) 通过发送消息WIN32 API广播WM_设置更改

private const int HWND_BROADCAST = 0xffff;
private const int WM_WININICHANGE = 0x001a, WM_SETTINGCHANGE = 0x001a, INI_INTL = 1;
[DllImport("user32.dll")]
private static extern int SendMessage(int hWnd, uint wMsg, uint wParam, uint lParam);

SendMessage(HWND_BROADCAST, WM_SETTINGCHANGE, 0, INI_INTL);

3) IActiveDesktop.ApplyChanges

[ComImport]
[Guid("F490EB00-1240-11D1-9888-006097DEACF9")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IActiveDesktop
{
     [PreserveSig]
     int ApplyChanges(AD_Apply dwFlags);
     // [...]
     // Note: There is a lot more to this interface,
     //        please see PInvoke.net link below.
}
private const int AD_APPLY_REFRESH = 4;

IActiveDesktop.ApplyChanges(AD_APPLY_REFRESH);

如果这些不起作用,请告诉我。如果归结起来,可以保存所有打开的资源管理器窗口及其位置,终止资源管理器,等待资源管理器重新启动,重新打开每个资源管理器窗口并重新定位它们。。。如果可以接受的话


希望这有帮助。

感谢您的回复和评论。我终于想出了解决这个问题的办法。我们可以隐藏所有桌面图标,然后再次显示它们。这将强制桌面重新加载

更新:在窗口8中,
SHELLDLL\u DefView
是其中一个
WorkerW
窗口的子窗口。(而不是
Progman
),下面是在Windows 8和8.1上运行的更新代码:

    [DllImport("user32.dll", SetLastError = true)]
    static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

    [DllImport("user32.dll", SetLastError = true)]
    static extern IntPtr GetWindow(IntPtr hWnd, GetWindow_Cmd uCmd);

    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);

    enum GetWindow_Cmd : uint
    {
        GW_HWNDFIRST = 0,
        GW_HWNDLAST = 1,
        GW_HWNDNEXT = 2,
        GW_HWNDPREV = 3,
        GW_OWNER = 4,
        GW_CHILD = 5,
        GW_ENABLEDPOPUP = 6
    }

    private const int WM_COMMAND = 0x111;

    [DllImport("user32.dll", SetLastError = true)]
    static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);

    private delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);

    [DllImport("user32.dll", CharSet = CharSet.Unicode)]
    private static extern int GetWindowText(IntPtr hWnd, StringBuilder strText, int maxCount);

    [DllImport("user32.dll", CharSet = CharSet.Unicode)]
    private static extern int GetWindowTextLength(IntPtr hWnd);

    [DllImport("user32.dll")]
    private static extern bool EnumWindows(EnumWindowsProc enumProc, IntPtr lParam);

    [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
    static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);


    public static string GetWindowText(IntPtr hWnd)
    {
        int size = GetWindowTextLength(hWnd);
        if (size++ > 0)
        {
            var builder = new StringBuilder(size);
            GetWindowText(hWnd, builder, builder.Capacity);
            return builder.ToString();
        }

        return String.Empty;
    }

    public static IEnumerable<IntPtr> FindWindowsWithClass(string className)
    {
        IntPtr found = IntPtr.Zero;
        List<IntPtr> windows = new List<IntPtr>();

        EnumWindows(delegate(IntPtr wnd, IntPtr param)
        {
            StringBuilder cl = new StringBuilder(256);
            GetClassName(wnd, cl, cl.Capacity);
            if (cl.ToString() == className && (GetWindowText(wnd) == "" || GetWindowText(wnd) == null))
            {
                windows.Add(wnd);
            }
            return true;
        },
                    IntPtr.Zero);

        return windows;
    }

    static void ToggleDesktopIcons()
    {
        var toggleDesktopCommand = new IntPtr(0x7402);
        IntPtr hWnd = IntPtr.Zero;
        if (Environment.OSVersion.Version.Major < 6 || Environment.OSVersion.Version.Minor < 2) //7 and -
            hWnd = GetWindow(FindWindow("Progman", "Program Manager"), GetWindow_Cmd.GW_CHILD);
        else
        {
            var ptrs = FindWindowsWithClass("WorkerW");
            int i = 0;
            while (hWnd == IntPtr.Zero && i < ptrs.Count())
            {
                hWnd = FindWindowEx(ptrs.ElementAt(i), IntPtr.Zero, "SHELLDLL_DefView", null);
                i++;
            }
        }
        SendMessage(hWnd, WM_COMMAND, toggleDesktopCommand, IntPtr.Zero);
    }

希望这对其他人有所帮助…

如果您尝试终止所有资源管理器实例并创建一个新实例会怎么样?@master131,这确实有效,但这不是一个选项,因为用户将丢失所有的资源管理器窗口。可能重复@ShengJiang蒋晟, 上面的问题是不同的,答案不能解决这个问题。这个问题的主要目标是刷新桌面(F5),它不会应用我的更改,或者重新加载图标,它也会这样做。我想在应用文件夹选项->单击项目中的更改后,完全按照Windows本身的操作,如下所示。有什么想法吗?可能重复:非常感谢,但不幸的是,没有一个对我有用。所以我想我可以隐藏桌面图标,然后显示它们。这正是我想要的,并重新加载桌面。@feedwall如果是这种情况,您可以获得桌面的句柄并手动发送{F5}键……如果它在切换时抛出错误,或在这两行之间遇到断点,并且它会永久关闭,会发生什么情况。
    [DllImport("user32.dll", SetLastError = true)]
    static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

    [DllImport("user32.dll", SetLastError = true)]
    static extern IntPtr GetWindow(IntPtr hWnd, GetWindow_Cmd uCmd);

    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);

    enum GetWindow_Cmd : uint
    {
        GW_HWNDFIRST = 0,
        GW_HWNDLAST = 1,
        GW_HWNDNEXT = 2,
        GW_HWNDPREV = 3,
        GW_OWNER = 4,
        GW_CHILD = 5,
        GW_ENABLEDPOPUP = 6
    }

    private const int WM_COMMAND = 0x111;

    [DllImport("user32.dll", SetLastError = true)]
    static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);

    private delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);

    [DllImport("user32.dll", CharSet = CharSet.Unicode)]
    private static extern int GetWindowText(IntPtr hWnd, StringBuilder strText, int maxCount);

    [DllImport("user32.dll", CharSet = CharSet.Unicode)]
    private static extern int GetWindowTextLength(IntPtr hWnd);

    [DllImport("user32.dll")]
    private static extern bool EnumWindows(EnumWindowsProc enumProc, IntPtr lParam);

    [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
    static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);


    public static string GetWindowText(IntPtr hWnd)
    {
        int size = GetWindowTextLength(hWnd);
        if (size++ > 0)
        {
            var builder = new StringBuilder(size);
            GetWindowText(hWnd, builder, builder.Capacity);
            return builder.ToString();
        }

        return String.Empty;
    }

    public static IEnumerable<IntPtr> FindWindowsWithClass(string className)
    {
        IntPtr found = IntPtr.Zero;
        List<IntPtr> windows = new List<IntPtr>();

        EnumWindows(delegate(IntPtr wnd, IntPtr param)
        {
            StringBuilder cl = new StringBuilder(256);
            GetClassName(wnd, cl, cl.Capacity);
            if (cl.ToString() == className && (GetWindowText(wnd) == "" || GetWindowText(wnd) == null))
            {
                windows.Add(wnd);
            }
            return true;
        },
                    IntPtr.Zero);

        return windows;
    }

    static void ToggleDesktopIcons()
    {
        var toggleDesktopCommand = new IntPtr(0x7402);
        IntPtr hWnd = IntPtr.Zero;
        if (Environment.OSVersion.Version.Major < 6 || Environment.OSVersion.Version.Minor < 2) //7 and -
            hWnd = GetWindow(FindWindow("Progman", "Program Manager"), GetWindow_Cmd.GW_CHILD);
        else
        {
            var ptrs = FindWindowsWithClass("WorkerW");
            int i = 0;
            while (hWnd == IntPtr.Zero && i < ptrs.Count())
            {
                hWnd = FindWindowEx(ptrs.ElementAt(i), IntPtr.Zero, "SHELLDLL_DefView", null);
                i++;
            }
        }
        SendMessage(hWnd, WM_COMMAND, toggleDesktopCommand, IntPtr.Zero);
    }
        ToggleDesktopIcons();
        ToggleDesktopIcons();