启动和关闭 explorer.exe 实例 [英] start and close instance of explorer.exe

查看:75
本文介绍了启动和关闭 explorer.exe 实例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a strange behaviour when I try to start explorer.exe from c# like this:

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.尽管如此,在任务管理器中,创建的资源管理器实例仍然存在.

the exception seems correct, because at this point HasExited returns already true. Nevertheless in the taskmanager the created instance of explorer is still present.

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

So I dont understand what my call does. I had thought it would directly start an instance of explorer, but it seems not or the explorer works in some different way.

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

And my second question: how can I start and shortly after that stop a new specific instance of explorer programmatically?

编辑回答一些问题:

  • 资源管理器选项 在单独的进程中启动文件夹 Windows 设置为 true
  • 创建的 process.Id 不在任务管理器中.例如:任务管理器中显示的新资源管理器实例的 PID 为 4968,而调试器显示 10752 作为创建(和退出)进程的 ID.
  • explorer option Launch Folder Windows in a separate process is set to true
  • the created process.Id is not present in taskmanager. For example: the new explorer instance shown in taskmanager has PID 4968 while the debugger shows 10752 as ID of the created (and exited) process.

这里是任务管理器在 ~12 次调试运行后的屏幕截图

here a screenshot from taskmanager after ~12 debug runs

推荐答案

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

This may be down to the fact that the explorer.exe process in question HAS exited. Windows does some strange things with multiple explorer windows and it depends on the options you have set. By default, all windows end up running in a single process if I remember correctly.

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

What I would do is output the processid for the process you just generated:

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

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

Then look at task manager to see if you can find the corresponding process. I would imagine that the HasExited is true so you won't find the process, but the window will have opened.

您可能需要将 process.EnableRaisingEvents 设置为 true 才能从 process.HasExited 获得有效答案,我不记得了我的头顶.

You may have to set process.EnableRaisingEvents to true to get a valid answer from process.HasExited, I can't recall of the top of my head.

还要通过文件夹选项检查资源管理器中的设置,看看您是否在视图选项卡上启用了在单独的进程中启动文件夹窗口.

Also check the setting in Explorer via Folder Options to see if you have Launch Folder Windows in a separate process enabled or not on the view tab.

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

IF you do find your process, you can always kill off that process and see if your windows closes. If it does, then it may be that the explorer.exe is not creating a main window handle which you can check using Spy++

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

Further more, @Hans Passant mentioned above that shell windows work different. So what actually happens is this, explorer.exe (1234) contacts the root explorer.exe (321), which in turn then creates a new window (if Launch separate is false) or spawns a subprocess explorer.exe (3445). Your process explorer.exe (1234) having done its job, then exits. No window is ever created by your process so CloseMainWindow() will not find a window to close and errors.

为此,您需要使用 ShellWindows,请参阅 有没有办法用 C# 关闭特定的 explorer 实例?

To do so you need to utilise ShellWindows, see Is there a way to close a particular instance of explorer with C#?

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

For reference the code used there was:

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();
        }    
}

请注意,您首先需要注意不要关闭用户想要打开的窗口.有没有理由关闭窗口?

Note, you need to be careful that you aren't closing a window the user wanted open in the first place. Is there a reason to close the window?

这篇关于启动和关闭 explorer.exe 实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆