此代码在大量计算机上按预期运行。然而,在一台特定的机器上,对WaitForExit()的调用似乎被忽略了,并且实际上将进程标记为已退出。
static void Main(string[] args)
{
Process proc = Process.Start("notepad.exe");
Console.WriteLine(proc.HasExited); //Always False
proc.WaitForExit(); //Blocks on all but one machines
Console.WriteLine(proc.HasExited); //**See comment below
Console.ReadLine();
}请注意,与SO上的相似问题不同,调用的进程是notepad.exe (出于测试原因),所以错误不太可能是它造成的--也就是说,它不会产生第二个子进程并关闭。即使如此,它也无法解释为什么它能在所有其他机器上工作。
在问题机器上,对Console.WriteLine(proc.HasExited))的第二个调用返回true,即使记事本在屏幕上和任务管理器中仍然是明显打开的。
该机器运行的是Windows7和.NET 4.0。
我的问题是,那台机器上的什么条件会造成这种情况?我该查些什么?
编辑-到目前为止我尝试过的东西/更新/可能相关的信息:
GetProcessesByName获取“现有”进程Id,但这只是在问题机器上返回一个空数组。因此,很难说问题是否与WaitForExit相匹配,因为调用GetProcessesByName甚至在调用WaitForExit之前都不会返回该进程。发布于 2012-01-17 15:41:42
问题是,默认情况下,Process.StartInfo.UseShellExecute设置为true。将此变量设置为true,而不是自己启动流程,您将请求shell为您启动它。这可能非常有用-它允许您执行诸如“执行”一个HTML文件( shell将使用适当的默认应用程序)。
当您想要在执行应用程序之后跟踪它(正如您发现的那样)时,情况就不太好了,因为启动应用程序有时会对它应该跟踪的实例感到困惑。
这种情况发生的内部细节可能超出了我的能力范围--我确实知道,当UseShellExecute == true时,框架使用ShellExecuteEx Windows,而当它使用UseShellExecute == false时,它使用CreateProcessWithLogonW,但是为什么其中一个导致可跟踪的进程,而另一个却不知道,因为它们似乎都返回进程ID。
编辑:经过一小段挖掘之后:
这个问题向我指出了诺森斯标志,它确实是在使用ShellExecute时设置的。掩码值的文档声明:
在某些情况下,例如当通过DDE会话满足执行时,将不返回句柄。调用应用程序负责在不再需要句柄时关闭句柄。
因此,它确实表明返回进程句柄是不可靠的。我仍然没有足够的深度,以了解哪一种特殊的边缘情况,你可能打在这里。
https://stackoverflow.com/questions/8895026
复制相似问题