如何处理通过System.Diagnostics.Process启动的进程崩溃?

14

我正在使用System.Diagnostics.Process启动外部进程。这是批处理作业的一部分,因此如果一个进程崩溃,我希望能够处理它并让其余进程继续运行。

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

根据这个问题,Process.Responding属性仅适用于具有UI的程序(我要启动的进程是控制台应用程序)。

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

有什么好的想法吗?

2个回答

25

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

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

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

参考:如何摆脱系统和应用程序弹出消息

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

如果没有源代码,请在父级中使用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,则我认为这种情况不会出现。


看起来这样做可能可行,但有点像用剑抹黄油。由于该程序将在其他人的计算机上运行,因此更改系统范围的属性不是一个选项 :( - meatvest
1
我尝试了你的代码,但是消息仍然出现(我甚至在一个玩具应用程序中尝试设置崩溃进程中的错误模式)。与同事交谈后发现,我可能会得到不同类型的对话框 - 包括“调试”选项的那种 - 因为我安装了Windows SDK。 - meatvest
2
SetErrorMode(3) 对我来说很管用。它只影响当前进程和子进程,非常适合我的应用程序。 - Boinst
即使它只影响进程/子进程,我仍然在WaitForExit调用之后的finally块中恢复原始值。 - BrainSlugs83
此外 - 我已经安装了Windows SDK,但我没有看到这个消息 - @CarlosA.Ibarra你确定你的进程中没有包含Debugger.Launch命令吗?- 这将打开你提到的对话框。 - BrainSlugs83
显示剩余5条评论

0

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

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接