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

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

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

这曾经没有任何问题.但现在,后台线程正在悄无声息地死去;它永远不会从调用Process.Start返回.处理System.Exception的此代码的catch块也未到达.即使我在Visual Studio调试器中抛出时启用了处理异常,我也看不到异常.奇怪的是,这个过程很快就会产生;使用预期的URL启动用户的默认浏览器.

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

什么可能导致我们的线程无声终止?是否有任何技术可用于调试线程终止期间发生的事情?

更新:

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

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

更新2:

在不使用shell执行的情况下启动cmd.exe可以解决此问题.谢谢你!但是,我仍然想知道为什么呼叫没有返回.

更新3:

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

在任何情况下,用户可能加载了shell扩展,这可能会导致进程启动并导致我的代码无法返回.我们无法做任何事情,所以正确的答案是使用启动cmd.exe进程的解决方法.

最佳答案
正如Hans Passant所提到的那样,挂起的Process.Start调用可能就是原因.当使用Process.Start并将UseShellExecute设置为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
    });

转载注明原文:通过.NET中的Process.Start生成的进程挂起了该线程 - 代码日志