我尝试过搜索,但没有什么能满足我的要求。
我不希望 explorer.exe被终止或重新启动。 我只想关闭任何打开的资源管理器窗口。
答案 0 :(得分:3)
以下替代方法使用Shell object的COM API来检索和识别文件资源管理器窗口。它需要添加COM引用:
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
}
}
}
}
答案 1 :(得分:1)
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;
}
答案 2 :(得分:1)
[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
消息,请窗口关闭...
答案 3 :(得分:0)
默认情况下,资源管理器作为单个进程运行,任何打开的窗口都只是该进程的一个线程。
通常,要关闭程序,您需要向进程发送一条关闭消息。在这种情况下,关闭explorer.exe将关闭所有资源管理器窗口。
要关闭单个窗口,您需要通过自己的过程打开每个窗口。 这可以通过注册表设置或在“视图”->“选项”->“视图”->“高级设置”下启用:“启动...单独的过程”
a)在您要关闭的窗口中找到PID(进程ID)。
通过taskmanager:
1.在进程列表中,单击“ Windows资源管理器”左侧的箭头
2.检查窗口名称是否与您要关闭的窗口匹配
3.右键单击“ Windows资源管理器”,单击“转到详细信息”
4.记录pid
通过CMD:
tasklist /V /FI "IMAGENAME eq explorer.exe"
如果在自己的进程中打开了每个浏览器窗口,则上述命令将在最后一列显示窗口标题。
否则将显示“ N / A”。
所有资源管理器窗口的pid将相同。 Explorer.exe进程具有自己的pid,标题为“ N / A”
如果已启用“单独过程”,例如通过“文件夹视图”选项,然后可以通过taskkill的进程ID和过滤器选项关闭每个窗口。
要关闭,必须先激活所需的窗口,否则使用pid关闭将关闭最后一个活动窗口,或者使用窗口标题过滤器关闭将给出错误:
信息:没有按指定条件运行的任务。
b)taskkill /pid <pid>
将关闭最后一个活动窗口。
重复此命令将进入下一个窗口。
或taskkill /im explorer.exe /fi "windowtitle eq <window name>"
或taskkill /fi "IMAGENAME eq explorer.exe" /fi "windowtitle eq <window name>"
<窗口名称>不区分大小写
如果在“文件夹”视图中启用了标题栏中的完整路径,请添加完整路径或通配符。
要关闭所有资源管理器窗口,请执行以下操作:
taskkill /im explorer.exe
在Win 10上测试