检测并重新启动我崩溃的.NET应用程序。

11

如何检测我的.NET应用程序是否崩溃,并重新启动它?


1
我在提问之前找到了一些解决方案,所以我认为把答案放在SO上会很好。如果你有其他的答案,请随便回答。或者只需投票选择最佳答案来指导其他人。另外,请根据您的判断重新标记此问题的标签。 - Hosam Aly
添加了关于重新启动控制台应用程序的信息,因为这显然是您正在使用的内容。 - HTTP 410
4个回答

15

另一个解决方案(基于 这个例子),是创建一个控制应用程序的启动器:

class LauncherProgram
{
    static int count = 3;

    static void Main()
    {
        Launch();
        Thread.Sleep(Timeout.Infinite);
    }

    static void Launch()
    {
        Process process = new Process();
        process.StartInfo.FileName = "MyApp.exe";
        process.EnableRaisingEvents = true;
        process.Exited += LaunchIfCrashed;
    }

    static void LaunchIfCrashed(object o, EventArgs e)
    {
        Process process = (Process) o;
        if (process.ExitCode != 0)
        {
            if (count-- > 0) // restart at max count times
                Launch();
            else
                Environment.Exit(process.ExitCode);
        }
        else
        {
            Environment.Exit(0);
        }
    }

1
唯一可能的升级是将“看门狗”变成Windows服务。 - Ryan Emerle
最好添加一些时间戳代码,并检测应用程序是否在启动时崩溃。 - Sean
很抱歉,@AshK,我无法帮助你解决这个问题。 - Hosam Aly
添加 process.start(); - undefined

8
如果这是一个Windows Forms应用程序:
- 在App.Config中设置jitDebugging = true。这可以防止触发内置的Windows Forms未处理异常处理程序。
现在无论这是Windows Forms应用程序还是控制台应用程序:
- 注册Application.ThreadException事件,例如在C#中: Application.ThreadException += new Threading.ThreadExceptionHandler(CatchFatalException);
此时,您的应用程序已经进入了黑洞。接下来会发生什么取决于这是否是一个Windows Forms应用程序:
如果是Windows Forms应用程序,在CatchFatalException事件处理程序中调用Application.Restart方法。 否则,您需要使用p/invoke调用application restart and recovery本机函数。该链接讨论Vista,但在我的测试中,它在XP上也可以正常工作。

谢谢。控制台应用程序是否可以执行类似于“Application.ThreadException += MyHandler;”的操作? - Hosam Aly
是的,控制台应用程序也可以做到同样的事情。 - HTTP 410
但是它没有访问Application类,对吗? - Hosam Aly
如果添加正确的命名空间,它确实可以访问Application类。但在我的测试中,我看到了一个“不支持”的异常,所以你是对的,这对于控制台应用程序不起作用。我会修改我的答案来反映这一点。 - HTTP 410

5
  • 在一个AppDomain内运行工作;使用主要的AppDomain来监视它(虽然不能防止进程被杀死)
  • 大量使用异常处理!即不要让致命错误拆除进程
  • 在已经内置回收机制的东西中运行 - 例如IIS

1
谢谢Marc。您能否提供一个示例,演示如何实现您建议的基于AppDomain的解决方案? - Hosam Aly
假设这是一个Windows Forms或控制台应用程序,您可以使用Application.Restart-请参阅我的答案以获取详细信息。 - HTTP 410

1
一种可能的解决方案是创建另一个进程来监视您的应用程序,并在其终止时重新启动它:
class ProcessMonitorProgram
{
    const string myProcess = "MyApp.exe";

    static void Main()
    {
        new Timer(CheckProcess, null, 0, 60 * 1000);
        Thread.Sleep(Timeout.Infinite);
    }

    static void CheckProcess(object obj)
    {
        if (Process.GetProcessesByName(myProcess).Length == 0)
            Process.Start(myProcess);
    }
}

这个解决方案的一个问题是它会一直让进程重启,直到监控应用程序本身被终止。


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