启动和关闭 explorer.exe 的实例

start and close instance of explorer.exe

当我尝试像这样从 c# 启动 explorer.exe 时,我有一个奇怪的行为:

ProcessStartInfo info = new ProcessStartInfo("explorer.exe", "E:");
info.WindowStyle = ProcessWindowStyle.Hidden;
Process process = new Process();
process.StartInfo = info;
process.Start();
Thread.Sleep(2000);
bool res = process.CloseMainWindow(); // InvalidOperationException -> already exited
process.Close();
process.WaitForExit(5000);

问题是:

异常似乎是正确的,因为此时 HasExited returns 已经 true。尽管如此,在任务管理器中创建的资源管理器实例仍然存在。

所以我不明白我的电话是做什么的。我原以为它会直接启动一个资源管理器的实例,但似乎不是,或者资源管理器以某种不同的方式工作。

我的第二个问题:如何以编程方式启动和停止一个新的特定资源管理器实例?

编辑 回答一些问题:

编辑: 这里是 taskmanager 在 ~12 次调试运行后的截图

这可能是因为有问题的 explorer.exe 进程已经退出。 Windows 使用多个资源管理器 windows 会做一些奇怪的事情,这取决于您设置的选项。默认情况下,如果我没记错的话,所有 windows 最终都会 运行 在一个进程中。

我要做的是输出您刚刚生成的进程的进程标识:

Console.WriteLine($"{process.Id} has exited {process.HasExited}");

然后看看任务管理器,看能不能找到对应的进程。我想 HasExited 是真的,所以你不会找到进程,但 window 会打开。

您可能必须将 process.EnableRaisingEvents 设置为 true 才能从 process.HasExited 获得有效答案,我想不起来了。

同时通过文件夹选项检查资源管理器中的设置,看看您是否在视图选项卡上启用了 Launch Folder Windows in a separate process

如果您确实找到了您的进程,您可以随时终止该进程并查看您的 windows 是否关闭。如果是,则可能是 explorer.exe 没有创建主 window 句柄,您可以使用 Spy++

检查它

编辑了更多信息

此外,@Hans Passant 上面提到 shell windows 工作不同。所以实际发生的是,explorer.exe (1234) 联系根 explorer.exe (321),然后根 explorer.exe (321) 创建一个新的 window(如果 Launch separate 为 false)或产生一个子进程 explorer.exe (3445)。您的进程 explorer.exe (1234) 已完成其工作,然后退出。您的进程从未创建 window,因此 CloseMainWindow() 将找不到要关闭的 window 和错误。

如何关闭特定的资源管理器window

为此,您需要利用 ShellWindows,请参阅 Is there a way to close a particular instance of explorer with C#?

作为参考,那里使用的代码是:

ShellWindows _shellWindows = new SHDocVw.ShellWindows();
string processType;

foreach (InternetExplorer ie in _shellWindows)
{
    //this parses the name of the process
    processType = Path.GetFileNameWithoutExtension(ie.FullName).ToLower();

    //this could also be used for IE windows with processType of "iexplore"
    if (processType.Equals("explorer") && ie.LocationURL.Contains(@"C:/Users/Bob"))
        {
            ie.Quit();
        }    
}

请注意,您需要注意不要关闭用户一开始想要打开的 window。是否有理由关闭 window?

问题出在 has UI Interface 的概念上,根据定义:

Closes a process that has a user interface by sending a close message to its main window.

然而 explorer.exe 比使用 UI 的简单过程要复杂得多。 例如,如果您使用另一个更简单的应用程序(例如记事本),则不会引发异常:

 ProcessStartInfo info = new ProcessStartInfo("notepad.exe");
            info.WindowStyle = ProcessWindowStyle.Maximized;
            Process process = new Process();
            process.StartInfo = info;
            process.Start();
            Thread.Sleep(2000);
            bool res = process.CloseMainWindow(); // InvalidOperationException -> already exited
            process.Close();