关闭打开资源管理器窗口而不终止explorer.exe

我试过搜索,但没有什么能满足我的要求。

我不希望 explorer.exe被终止或重新启动。 我只想关闭任何打开的资源管理器窗口。

[DllImport("user32.dll")] private static extern bool EnumWindows(EnumWindowsDelegate lpEnumFunc, IntPtr lParam); [DllImport("user32.dll")] private static extern IntPtr GetWindowThreadProcessId(IntPtr hWnd, out IntPtr lpdwProcessId); [DllImport("user32.dll")] private static extern uint RealGetWindowClass(IntPtr hwnd, StringBuilder pszType, uint cchType); [DllImport("user32.dll")] static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam); static uint WM_CLOSE = 0x10; private delegate bool EnumWindowsDelegate(IntPtr hwnd, IntPtr lParam); private static bool EnumWindowsCallback(IntPtr hwnd, IntPtr lParam) { IntPtr pid = new IntPtr(); GetWindowThreadProcessId(hwnd, out pid); var wndProcess = System.Diagnostics.Process.GetProcessById(pid.ToInt32()); var wndClass = new StringBuilder(255); RealGetWindowClass(hwnd, wndClass, 255); if (wndProcess.ProcessName == "explorer" && wndClass.ToString() == "CabinetWClass") { //hello file explorer window... SendMessage(hwnd, WM_CLOSE, IntPtr.Zero, IntPtr.Zero); // ... bye file explorer window } return (true); } static void Main() { EnumWindowsDelegate childProc = new EnumWindowsDelegate(EnumWindowsCallback); EnumWindows(childProc, IntPtr.Zero); Console.ReadKey(); } 

编辑:
所以我想唯一有趣的事情就是每个枚举窗口都会被windows调用的回调(hwnd中所述窗口的句柄)

GetWindowThreadProcessId为我们提供了给定窗口句柄的processid

然后, GetProcessById为我们提供了一个进程对象,用于读取进程名称等内容

RealGetWindowClass为我们提供了给定窗口句柄的注册类名

最后,我们可以查看当前窗口的进程是否为资源管理器,窗口类是否为“CabinetWClass”,这是普通文件资源管理器窗口的窗口类

最后但并非最不重要的是,如果我们的检查没问题,请发送WM_CLOSE消息,请求窗口关闭…

以下替代方法使用Shell对象的COM API来检索和标识文件资源管理器窗口。 它需要添加COM引用:

  • Microsoft Shell控件和自动化
  • Microsoft Internet Controls

Shell.Windows方法返回的对象是IEnumerable。 集合中的每个对象都是SHDocVw.InternetExplorer实例。 如果Document对象是Shell32.ShellFolderView,则资源管理器是文件资源管理器。

  private static void CloseExplorerWindows() { Shell32.Shell shell = new Shell32.Shell(); // ref: Shell.Windows method // https://msdn.microsoft.com/en-us/library/windows/desktop/bb774107(v=vs.85).aspx System.Collections.IEnumerable windows = shell.Windows() as System.Collections.IEnumerable; if (windows != null) { // ref: ShellWindows object // https://msdn.microsoft.com/en-us/library/windows/desktop/bb773974(v=vs.85).aspx foreach (SHDocVw.InternetExplorer window in windows) { object doc = window.Document; if (doc != null && doc is Shell32.ShellFolderView) { window.Quit(); // closes the window } } } } 
  public static void CloseExplorerWindows() => EnumWindows(new EnumWindowsProc(EnumTheWindows), IntPtr.Zero); 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")] private static extern bool IsWindowVisible(IntPtr hWnd); [DllImport("user32.dll", SetLastError = true)] static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId); [DllImport("user32.dll", CharSet = CharSet.Auto)] static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam); static uint WM_CLOSE = 0x10; private static bool EnumTheWindows(IntPtr hWnd, IntPtr lParam) { int size = GetWindowTextLength(hWnd); if (size++ > 0 && IsWindowVisible(hWnd)) { var sb = new StringBuilder(size); GetWindowText(hWnd, sb, size); var threadID = GetWindowThreadProcessId(hWnd, out var processID); var s = System.Diagnostics.Process.GetProcessById((int)processID).ProcessName; if (s == "explorer" && sb.ToString() != "Program Manager") SendMessage(hWnd, WM_CLOSE, IntPtr.Zero, IntPtr.Zero); } return true; }