启动和关闭explorer.exe的实例

时间:2017-11-30 13:22:37

标签: c# windows-10 windows-explorer

当我尝试从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已经返回true。然而,在任务管理器中,创建的资源管理器实例仍然存在。

所以我不明白我的电话是做什么的。我以为它会直接启动一个探险家的实例,但似乎没有,或者探险家以不同的方式工作。

我的第二个问题:我怎样才能开始,之后不久就以编程方式停止一个新的特定的资源管理器实例?

修改 回答一些问题:

  • 资源管理器选项Launch Folder Windows in a separate process设置为true
  • 创建的process.Id在taskmanager中不存在。例如:taskmanager中显示的新资源管理器实例具有PID 4968,而调试器显示10752作为已创建(和退出)进程的ID。

编辑这里是〜12次调试后来自taskmanager的截图 enter image description here

2 个答案:

答案 0 :(得分:2)

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

我要做的是输出您刚刚生成的流程的processid:

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

然后查看任务管理器,看看是否可以找到相应的进程。我会想象HasExited是真的,所以你不会找到这个过程,但窗口会打开。

您可能需要将process.EnableRaisingEvents设置为true才能从process.HasExited获得有效答案,我无法回想起我的头脑。

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

如果找到了您的流程,您可以随时终止该流程并查看您的窗口是否关闭。如果是,那么可能是explorer.exe没有创建一个主窗口句柄,您可以使用Spy ++检查

使用更多信息进行编辑

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

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

为此,您需要使用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();
        }    
}

注意,您需要注意的是,您首先不要关闭用户想要打开的窗口。是否有理由关闭窗户?

答案 1 :(得分:0)

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

  

通过发送关闭消息来关闭具有用户界面的进程   到它的主窗口。

然而,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();