.NET 中通过 Process.Start 生成的进程会挂起线程

2024-02-11

我们的应用程序有一个后台线程,它通过以下方式生成一个进程System.Diagnostics.Process:

Process.Start(
    new ProcessStartInfo
    {
        FileName = url,
        UseShellExecute = true
    }
);

这曾经完全没有问题。但现在,后台线程正在悄然消亡;它永远不会从调用中返回Process.Start。此代码的 catch 块,用于处理System.Exception,也没有达到。即使我在 Visual Studio 调试器中抛出异常时启用处理,我也没有看到任何异常。奇怪的是,这个进程生成得很好;用户的默认浏览器将使用预期的 URL 启动。

我们进程的入口点标记为[STAThread]按照建议。

什么可能导致我们的线程默默终止?我可以使用任何技术来调试线程终止期间发生的情况吗?

Update:

看起来线程毕竟还活着;它只是没有从通话中返回。这是它的堆栈跟踪:

  • [在睡眠中等待或加入]
  • System.dll!System.Diagnostics.ShellExecuteHelper.ShellExecuteOnSTAThread() + 0x63 字节
  • System.dll!System.Diagnostics.Process.StartWithShellExecuteEx(System.Diagnostics.ProcessStartInfo startInfo) + 0x19d 字节
  • System.dll!System.Diagnostics.Process.Start() + 0x39 字节
  • System.dll!System.Diagnostics.Process.Start(System.Diagnostics.ProcessStartInfo startInfo) + 0x32 字节
  • 我的方法

更新2:

解决方法是启动 cmd.exe 而不使用 shell 来执行。非常感谢!不过我还是想知道why电话没有回电。

更新3:

Shell 挂钩听起来确实像是对可能导致调用不返回的原因的逻辑解释。我找不到流氓模块,但在最后一次尝试通过 shell 执行来运行之后,调用did return.

无论如何,用户可能加载了 shell 扩展,这可能会扰乱进程启动并导致我的代码无法返回。我们无能为力that,所以正确的答案是使用启动 cmd.exe 进程的解决方法。


正如汉斯·帕桑特(Hans Passant)所说,悬挂Process.Start打电话可能是原因。使用时Process.Start with UseShellExecute set to true、Windows API函数ShellExecuteEx在后台调用,在某些情况下可能不会返回。

您可以通过向代码中添加跟踪消息来检查是否是这种情况:

System.Diagnostics.Trace.WriteLine("About to start process.");
Process.Start(
   new ProcessStartInfo
   {
       FileName = url,
       UseShellExecute = true
   }
);
System.Diagnostics.Trace.WriteLine("Process started.");

要监听跟踪消息,您可以使用TraceListener,检查Visual Studio的输出窗口或使用DebugView等工具。

作为解决方法,您可以使用start命令。以下代码启动一个隐藏的 shell 窗口,该窗口“启动”该 url:

Process.Start(
    new ProcessStartInfo()
    {
        FileName = "cmd.exe",
        Arguments = "/c start http://www.google.com",
        WindowStyle = ProcessWindowStyle.Hidden,
        UseShellExecute = false
    });
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

.NET 中通过 Process.Start 生成的进程会挂起线程 的相关文章