【问题标题】:How to handle a crash in a process launched via System.Diagnostics.Process?如何处理通过 System.Diagnostics.Process 启动的进程中的崩溃?
【发布时间】:2010-10-14 22:54:51
【问题描述】:

我正在使用 System.Diagnostics.Process 启动一个外部进程。这是批处理作业的一部分,所以如果一个进程崩溃,我想处理它并让其余的继续。

目前发生的情况是,Windows 会弹出一个对话框,告诉我程序已崩溃,并且只有在我手动关闭该对话框后,进程才会退出。

根据this question,Process.Responding 属性仅适用于具有 UI 的程序(我正在启动的进程是控制台应用程序)。

我还查看了进程提供的各种事件,但没有一个是在崩溃时触发的。

有什么想法吗?

【问题讨论】:

    标签: .net process crash


    【解决方案1】:

    尝试将注册表以下注册表值设置为值 DWORD 2:

    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Windows\ErrorMode = 2
    

    这会影响机器上的每个进程。

    参考: How to Get Rid of System and Application Popup Messages

    如果您有崩溃程序的源代码,您可以通过捕获所有结构化异常并退出而不弹出消息框来防止弹出窗口。如何执行此操作取决于所使用的编程语言。

    如果您没有源,请使用父级中的 SetErrorMode 函数来抑制弹出窗口。错误模式由子进程继承。您必须将 UseShellExecute 设置为 false 才能工作:

    using System;
    using System.Diagnostics;
    using System.Runtime.InteropServices;
    
    
    namespace SubProcessPopupError
    {
    
        class Program
        {
            [DllImport("kernel32.dll", SetLastError = true)]
            static extern int SetErrorMode(int wMode);
    
            static void Main(string[] args)
            {
                int oldMode = SetErrorMode(3);
                Process p;
                ProcessStartInfo ps = new ProcessStartInfo("crash.exe");
                ps.UseShellExecute = false;
                p = Process.Start(ps);
                SetErrorMode(oldMode);
                p.WaitForExit();
            }
        }
    }
    

    如果您看到一个对话框说“您想使用选定的调试器进行调试吗?”,您可以通过将此注册表值设置为 0 来关闭它。

    HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug\Auto = 0
    

    但是,如果您按照上面的说明将错误模式设置为 3,我认为不会出现这种情况。

    【讨论】:

    • 看起来这样可以,但有点像用剑涂抹黄油。该程序必须在其他人的计算机上运行,​​因此无法更改系统范围的属性:(
    • 查看我添加到答案中的额外段落。如果你有源代码...捕获所有异常。
    • 提示我问题的崩溃实际上是在加载程序引用期间引起的-甚至没有输入 Main() 方法-这意味着异常(据我所知)不可能赶上。
    • 我尝试了您的代码,但消息仍然出现(我什至尝试在玩具应用程序的崩溃过程中设置错误模式)。与一位同事交谈后发现,我可能会得到一种不同类型的对话框 - 包含“调试”选项的对话框 - 因为我安装了 Windows SDK。
    • SetErrorMode(3) 对我有用。只影响当前进程和子进程,适合我的应用。
    【解决方案2】:

    另一种选择是在cdb 下运行您的可执行文件,然后使用以下命令行搜索单词“exception”:

    cdb.exe -G -g -c "Q" <your executable>
    

    【讨论】:

      猜你喜欢
      • 2011-07-01
      • 2013-10-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-12
      相关资源
      最近更新 更多