当我尝试从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。答案 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();