代码之家  ›  专栏  ›  技术社区  ›  Jacob

进程通过Process.Start 在.NET中挂起线程

  •  6
  • Jacob  · 技术社区  · 14 年前

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

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

    Process.Start . 此代码的catch块,用于处理 System.Exception ,也没有联系到。即使我在visualstudio调试器中启用了异常处理,也看不到异常。奇怪的是,这个过程很好地孕育出来了;用户的默认浏览器将使用预期的URL启动。

    我们流程的入口点标记为 [STAThread]

    是什么导致我们的线程自动终止?有什么技术可以用来调试线程终止期间发生的事情吗?

    更新:

    看来这根线毕竟是活的;只是电话没回。下面是它的堆栈跟踪:

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

    更新2:

    发射cmd.exe 不使用shell执行works作为解决方法。非常感谢!不过,我还是想知道 为什么?

    在任何情况下,用户可能加载了shell扩展,这可能会干扰进程的启动,导致我的代码无法返回。我们什么也做不了 那个

    2 回复  |  直到 14 年前
        1
  •  5
  •   Dirk Vollmar    14 年前

    正如汉斯·帕桑所说 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

    作为解决方法,您可以使用 start

    Process.Start(
        new ProcessStartInfo()
        {
            FileName = "cmd.exe",
            Arguments = "/c start http://www.google.com",
            WindowStyle = ProcessWindowStyle.Hidden,
            UseShellExecute = false
        });
    
        2
  •  5
  •   Hans Passant    14 年前

    不,线程不会自动终止,它们会发出很大的咔嚓声。至少您会在输出窗口中看到线程退出通知。这个Process.Start()方法阻塞是另一种解释,尽管没有解释。你的代码片段太短了,不能给出一个像样的诊断。可能是环境问题。


    这在您的计算机上导致了一个问题,这仍然指向一个环境问题,一种劫持ShellExecuteEx()调用的系统外接程序。并指望运行真正的STA线程。您应该能够在Debug+Windows+Threads窗口中找到帮助线程。它应该在堆栈上包含“ShellExecuteFunction”。像这样的“系统附加组件”就是病毒扫描器。在项目的调试选项卡中选中“启用非托管调试”之后,您应该能够在Debug+Windows+Modules窗口中找到alienware。

    顺便说一句,使用UseShellExecute=false的解决方法在这里是可以接受的。只是从外观上看,你的机器有点乱,这一点当然不是。