首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >不同机器间的Process.WaitForExit不一致

不同机器间的Process.WaitForExit不一致
EN

Stack Overflow用户
提问于 2012-01-17 13:00:58
回答 1查看 3.4K关注 0票数 15

此代码在大量计算机上按预期运行。然而,在一台特定的机器上,对WaitForExit()的调用似乎被忽略了,并且实际上将进程标记为已退出。

代码语言:javascript
复制
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。

我的问题是,那台机器上的什么条件会造成这种情况?我该查些什么?

编辑-到目前为止我尝试过的东西/更新/可能相关的信息:

  • 重新安装.NET。
  • 关闭任务管理器中不知道的任何进程。
  • Windows尚未在这台机器上被激活。
  • 按照注释中的建议,我尝试使用GetProcessesByName获取“现有”进程Id,但这只是在问题机器上返回一个空数组。因此,很难说问题是否与WaitForExit相匹配,因为调用GetProcessesByName甚至在调用WaitForExit之前都不会返回该进程。
  • 在问题机器上,生成的记事本进程的是代码手动启动的记事本进程的ID,换句话说,记事本是生成子进程并终止自身。
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-01-17 15:41:42

问题是,默认情况下,Process.StartInfo.UseShellExecute设置为true。将此变量设置为true,而不是自己启动流程,您将请求shell为您启动它。这可能非常有用-它允许您执行诸如“执行”一个HTML文件( shell将使用适当的默认应用程序)。

当您想要在执行应用程序之后跟踪它(正如您发现的那样)时,情况就不太好了,因为启动应用程序有时会对它应该跟踪的实例感到困惑。

这种情况发生的内部细节可能超出了我的能力范围--我确实知道,当UseShellExecute == true时,框架使用ShellExecuteEx Windows,而当它使用UseShellExecute == false时,它使用CreateProcessWithLogonW,但是为什么其中一个导致可跟踪的进程,而另一个却不知道,因为它们似乎都返回进程ID。

编辑:经过一小段挖掘之后:

这个问题向我指出了诺森斯标志,它确实是在使用ShellExecute时设置的。掩码值的文档声明:

在某些情况下,例如当通过DDE会话满足执行时,将不返回句柄。调用应用程序负责在不再需要句柄时关闭句柄。

因此,它确实表明返回进程句柄是不可靠的。我仍然没有足够的深度,以了解哪一种特殊的边缘情况,你可能打在这里。

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8895026

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档