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

时间:2022-08-29 14:49:42

I'm launching an external process with System.Diagnostics.Process. This is part of a batch job, so if one process crashes, I'd like to handle it and let the rest continue.

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

What currently happens is Windows pops up a dialog telling me that the program has crashed, and only once I've dismissed that manually does the process exit.

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

According to this question, the Process.Responding property is only available for programs with UIs (the process I'm launching is a console app).

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

I also looked at the various events a process provides, but none of them are fired on crashing.

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

Any ideas?

2 个解决方案

#1


25  

Try setting the registry following registry value to value DWORD 2:

尝试将注册表值后面的注册表设置为值DWORD 2:

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

This will affect every process on the machine.

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

Reference: How to Get Rid of System and Application Popup Messages

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

If you have the source code to the program that crashes, you can prevent the popups by catching all structured exceptions and exiting without popping up a message box. How you do this depends on the programming language used.

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

If you don't have the source, use the SetErrorMode function in the parent to suppress popups. The error mode is inherited by subprocesses. You must set UseShellExecute to false for this to work:

如果您没有源,请使用父级中的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();
        }
    }
}

If you are getting a dialog saying "Do you want to debug using the selected debugger?", you can turn that off by setting this registry value to 0.

如果您收到一个对话框“是否要使用所选调试器进行调试?”,则可以通过将此注册表值设置为0来关闭该对话框。

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

However, I don't think this will come up if you have set the error mode to 3 as explained above.

但是,如果您已将错误模式设置为3,我认为不会出现这种情况,如上所述。

#2


0  

Another option is to run your executable under cdb, and then search for the word "exception", using the following command line:

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

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

#1


25  

Try setting the registry following registry value to value DWORD 2:

尝试将注册表值后面的注册表设置为值DWORD 2:

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

This will affect every process on the machine.

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

Reference: How to Get Rid of System and Application Popup Messages

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

If you have the source code to the program that crashes, you can prevent the popups by catching all structured exceptions and exiting without popping up a message box. How you do this depends on the programming language used.

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

If you don't have the source, use the SetErrorMode function in the parent to suppress popups. The error mode is inherited by subprocesses. You must set UseShellExecute to false for this to work:

如果您没有源,请使用父级中的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();
        }
    }
}

If you are getting a dialog saying "Do you want to debug using the selected debugger?", you can turn that off by setting this registry value to 0.

如果您收到一个对话框“是否要使用所选调试器进行调试?”,则可以通过将此注册表值设置为0来关闭该对话框。

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

However, I don't think this will come up if you have set the error mode to 3 as explained above.

但是,如果您已将错误模式设置为3,我认为不会出现这种情况,如上所述。

#2


0  

Another option is to run your executable under cdb, and then search for the word "exception", using the following command line:

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

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