2009-07-27 33 views
3

コアアプリケーションはMFC C++でビルドされていますが、.NETで新しいコードを記述しようとしています。既存のMFCダイアログ。MFCダイアログで使用されるマネージC#ユーザコントロールの未処理例外

ただし、ユーザーコントロールから予期しない/未処理の例外がスローされた場合、MFCアプリケーションがクラッシュ(不正なopスタイル)され、回復する機能はありません。

私は、.NETユーザーコントロールのコンストラクタに

AppDomain currentDomain = AppDomain.CurrentDomain; 
currentDomain.UnhandledException += new UnhandledExceptionEventHandler(currentDomain_UnhandledException); 
Application.ThreadException += new ThreadExceptionEventHandler(Application_ThreadException); 

を追加しましたが、何かをキャッチしていないようです。

これらを処理するためにMFCにイベントを追加する方法はありますか?

クイックグーグルは何も役に立ちませんでした。

ありがとうございました。


編集:まだこれに私が好きな方法を解決することができていない、それを行うには最高の方法のように見える、試してみて、すべての.NETコードを周りにキャッチされているので、例外なくわきたつ。

+0

私の編集をチェックしてください。私はすべてのイベントハンドラでそれを使用します。そうすることができます。 –

+0

.NETコードの最も外側にあるイベントハンドラとパブリックエントリポイントを試してみるだけです。 –

+0

ああ、それは私がしなければならないことですが、.NETコードを直接的にも間接的にもすべてカバーします。 – PostMan

答えて

3

私はしばらく前にこの同じ質問を:Final managed exception handler in a mixed native/managed executable?

を私が発見したことは、管理スレッドで実行しているときに未処理の管理例外イベントがONLY発火点です。管理されたWndProcは、魔法が起こる場所です。

CWinAppに低レベルのオーバーライドを配置し、Exception ^をキャッチできます。これは意図しない副作用を伴う可能性があります。または、構造化例外処理(SEH)を使用すると、/ all/unhandled例外をハックすることができます。これは簡単な道ではありません。

0

私はあなたが物事のMFC側で未処理の例外ハンドラを持つようにしたいと思う:

のAppDomain :: CurrentDomain-> UnhandledException + = gcnew UnhandledExceptionEventHandler(& CurrentDomain_UnhandledException)。

[Application.ThreadExceptionに同じ]

は、MSDNフォーラムでこの同様の質問を見ている:もちろんUnhandled Exception in Mixed Mode application

+0

提供されたリンクのコードは実際には機能しませんし、悲しいことにこのコードは提供されていません。 100%コンパイルしますが、結果は同じです – PostMan

+0

実際、これは機能しません。また、なぜイベント登録が実行されるコンテキストが登録に影響するのでしょうか? あなたがリンクしているスレッドの回答が間違っている場合、後の回答からこのAskerの問題が確認されます。 –

0

を、より良いアイデアは、C#コードで例外を処理するかだろうそれを引き起こしているものを見つけ出し、例外がスローされないように修正してください。それを防ぐのは何ですか?ユーザーコントロールのすべてのイベントハンドラで

、try/catchブロックを置く:

private void btnOk_Click(object sender, EventArgs e) { 
    try { 
     // real code here 
    } 
    catch (Exception ex) { 
     LogException(ex); 
     // do whatever you must in order to shut down the control, maybe just 
    } 
} 

は、ここで私が使用しているものです:

public static class UI 
{ 
    public static void PerformUIAction(Control form, Action action) 
    { 
     PerformUIAction(form, action, (string) null); 
    } 

    public static void PerformUIAction(
     Control form, Action action, string message) 
    { 
     PerformUIAction(form, action,() => message); 
    } 

    public static void PerformUIAction(
     Control form, Action action, Func<string> messageHandler) 
    { 
     var saveCursor = form.Cursor; 
     form.Cursor = Cursors.WaitCursor; 
     try 
     { 
      action(); 
     } 
     catch (Exception ex) 
     { 
      MessageBox.Show(
       messageHandler() ?? ex.Message, "Exception!", 
       MessageBoxButtons.OK, MessageBoxIcon.Error, 
       MessageBoxDefaultButton.Button1, 
       MessageBoxOptions.DefaultDesktopOnly); 
      Debug.WriteLine(ex.ToString(), "Exception"); 
      throw; 
     } 
     finally 
     { 
      form.Cursor = saveCursor; 
     } 
    } 
} 

は、私はこのようにそれを呼び出す:

private void _copyButton_Click(object sender, EventArgs e) 
{ 
    UI.PerformUIAction(
     this,() => 
        { 
        // Your code here 
        }); 
} 
+0

例外があるのは、いつ来るのか、なぜ来るのか分からないことです。これは不可能です。 また、ユーザーコントロールにはかなりのイベントとメソッドがあります。 私は可能な例外をコード化しましたが、キャッチしたいものです。 – PostMan

+0

かなりの作業に見えますが、必要な場所に余分なコードを追加する必要のないソリューションが本当に必要です例外をキャッチする(私が期待できるもの以外) – PostMan

+0

あなたが好きです。しかし、開いた "{"と最後の "}"の前に3行のコードを追加していることに注目してください。シンプルな正規表現を気にしない場合は、検索と置換を使用して行うことができます。また気付かなかったかもしれません。 「あなたのコードはここにあります」ブロック内の「送信者」と「e」にアクセスできます。ラッピングしているコードは変更されません。 –

0

未処理の例外ハンドラを.NETのコンストラクタに追加しました。ユーザーコントロール

私はそれがうまくいくとは思わない。私は例外ハンドラがApplication.Runの呼び出しの前にセットアップされている必要がありますと信じています。あなたのアプリでApplication.Runの呼び出しがありますか?

初期化する前に、物事のMFC側でこのようなものはどうですか?NETのコントロール:

Application.SetUnhandledExceptionMode(System.Windows.Forms.UnhandledExceptionMode.CatchException); 
Application.ThreadException += ...; 

ThreadExceptionハンドラが呼び出された場合を参照してください。

+0

興味深いアイデアは、試してみてください。 –

+0

スレッド例外で.NETイベント、つまりMFCコードを呼び出す必要がありますか?申し訳ありませんが、このプログラミング全体の新しい.... – PostMan

+0

もののMFC側にこれを持っています。 C++コードをC++/CLI(マネージC++コード)としてコンパイルする必要があります。 –