我们的应用程序有一个后台线程,它通过以下方式生成一个进程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(使用前将#替换为@)