2

ActiveX オブジェクトを使用し、WCF サービスを提供する C# WPF プログラムがあります。そのため、多くのスレッド、アンマネージ コードへの呼び出しが多数あります。全負荷でアプリケーションがクラッシュすることがあります。問題を調査しています - ActiveX のどこかに問題があるようで、変更できません。とにかく、クラッシュ後にプログラムを復元する方法が必要です。今のところ、私は解決策を見つけました:

public partial class App : Application
 {
    private static readonly Logger log = LogManager.GetCurrentClassLogger();

    bool isClosing = false;


    [System.Runtime.ExceptionServices.HandleProcessCorruptedStateExceptionsAttribute]
    void D_UnhandledException(object sender, UnhandledExceptionEventArgs e)
    {
        log.FatalException("Error UnhandledException ", (Exception)e.ExceptionObject);
        MonitoringSvc.host.Close();
        log.Info("Restarting");
        if (!isClosing)
        {

            System.Windows.Forms.Application.Restart();
            System.Windows.Application.Current.Shutdown();
        }
    }


    private void Application_Startup(object sender, StartupEventArgs e)
    {
        AppDomain D = AppDomain.CurrentDomain;
        D.UnhandledException += new UnhandledExceptionEventHandler(D_UnhandledException);
    }

    private void Application_Exit(object sender, ExitEventArgs e)
    {
        isClosing = true;
    }
}

プログラムは、未処理の例外で再起動します (確かにシミュレートされた場合)。しかし、古いコピーはシステムメッセージ「プログラムが予期せず終了しました」で閉じられません。プログラムはほとんどの場合ユーザーとやり取りしないため、誰もそのメッセージを閉じてプログラムを閉じることはできません。問題は、その古いウィンドウを静かに閉じる方法です。

4

1 に答える 1

5

プログラムのクラッシュ時に表示されるウィンドウを無効にする方法は次のとおりです。WERだけでなく、WERが無効になっている場合でも、他のウィンドウが表示されます(プログラムを閉じるかデバッグするかを尋ねます)。

    [DllImport("kernel32.dll", SetLastError = true)]
    static extern int SetErrorMode(int wMode);

    [DllImport("kernel32.dll")]
    static extern FilterDelegate SetUnhandledExceptionFilter(FilterDelegate lpTopLevelExceptionFilter);
    public delegate bool FilterDelegate(Exception ex);

    App()
    {
        FilterDelegate fd = delegate(Exception ex)
        {
            return true;
        };
        SetUnhandledExceptionFilter(fd);

        SetErrorMode(SetErrorMode(0) | 0x0002 );
    }
于 2012-05-19T23:08:30.200 に答える