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

Jac*_*cob 6 .net browser shell multithreading process

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

Process.Start(
    new ProcessStartInfo
    {
        FileName = url,
        UseShellExecute = true
    }
);
Run Code Online (Sandbox Code Playgroud)

这曾经没有任何问题.但现在,后台线程正在悄无声息地死去; 它永远不会从通话中回来Process.Start.处理此代码的catch块System.Exception也未到达.即使我在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进程的解决方法.

Han*_*ant 5

不,线程没有默默地终止,它们发出响亮的kaboom声音.至少你会在Output窗口中看到线程退出通知.Process.Start()方法阻塞将是另一种解释,尽管没有解释.你的片段太短,无法提供合适的诊断.也许是一些环境问题.


你的堆栈跟踪有帮助,ShellExecuteOnSTAThread()确实在一个小帮助线程上执行阻塞Thread.Join().该线程是调用本机ShellExecuteEx()API函数所必需的,它只能从STA线程调用.它有一个缺点,STA线程也必须泵出一个消息循环.这个小帮手没有.

这会导致您的计算机出现问题仍然指向环境问题,某种系统加载项会劫持ShellExecuteEx()调用.并依靠运行真正的STA线程.您应该能够在Debug + Windows + Threads窗口中找到该帮助程序线程.它应该在堆栈中包含"ShellExecuteFunction".例如,那种吸引像这样的特技的"系统附加组件"就是病毒扫描程序.在项目的"调试"选项卡中选中"启用非托管调试"后,您应该能够在Debug + Windows + Modules窗口中找到该alienware.

使用UseShellExecute = false的解决方法在这里完全可以接受.事实上,你的机器看起来有点混乱,当然不是.

  • 我有完全相同的问题,结果发现阿瓦斯特正在劫持我的,所以你在那里找到汉斯.很抱歉要重振这一点,只是想给予应有的信用,我花了一整天的时间来解决这个问题! (3认同)

Dir*_*mar 5

正如汉斯帕斯特所提到的那样,悬挂Process.Start电话可能就是原因.当使用Process.StartUseShellExecute设置为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.");
Run Code Online (Sandbox Code Playgroud)

要收听跟踪消息,您可以使用a 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
    });
Run Code Online (Sandbox Code Playgroud)