2017-01-24 3 views
1

私のコードでは、次のようにWindows 10 Professional上で動作するアプリケーションがクラッシュします。ShowInTaskbarが例外なく私のアプリケーションをクラッシュさせるのはなぜですか?

this.ShowInTaskbar = true; 

これは2種類のマシンでテストされています。上記のコード行をtry/catchブロックに含めると、例外は表示されません。 Appdomain.UnhandledExceptionイベントに登録しても例外はありません。

System.Windows.Forms.ni.dllにエラーが発生したとのイベントビューアにはEvent ID 1000のアプリケーションエラーがありますが、それ以外は何も意味がありません。

この問題はWindows 10 Professionalでも動作する開発マシンでは再現できません。

フォームには、NotifyIcon以外のコントロールはありません。

private void onFormResize(object sender, EventArgs e) 
{ 
    if (this.WindowState == FormWindowState.Minimized) this.ShowInTaskbar = false; 
} 

private void notifyIcon1_MouseDoubleClick(object sender, MouseEventArgs e) 
{ 
    try 
    { 
     this.ShowInTaskbar = true; 
     this.WindowState = FormWindowState.Normal; 
    } 
    catch (Exception ex) 
    { 
     MessageBox.Show(ex.Message); 
    } 
} 

私が最初WindowStateを変更し、その後、すべてがOKを流れるタスクバー上のフォームを表示する場合は、次の実験の後、私はこの問題は、次のコード行であることを考え出しました。また、のコマンド実行の順序に関係なく、OnFormResizeからコードを削除しても、アプリケーションがクラッシュすることはありません。

+0

try/catchブロックはどのように見えますか?例外を飲み込んでいる可能性があります。 – Soviut

+1

新しいWindowsフォームプロジェクトを作成してこの1つのものを追加するだけでも同じことが起こりますか?私は 'ShowInTaskbar'を変更するとウィンドウが再作成されると思います。おそらくあなたはウィンドウで何か安全でないことをやっているのでしょうか? 'ShowInTaskbar'をtrueに設定するとエラーを再現するサンプルコードを与えることができない限り、私たちは本当にあなたを助けることができません。 – Luaan

+0

@Luaan私は詳細を提供する質問を編集しました。この問題は、言及された行を切り替えることによって克服されました。それはまだアプリがクラッシュした理由は私にはまだ悩ましい。 – Saloom

答えて

4

免責事項:これのほとんどは非契約の行動なので、正式にそれを取ることはありません - Windowsと.NET Frameworkの異なるバージョンや構成が起こっている上、自分の小さな効果を有することができます。

タスクバーにウィンドウを表示します。ウィンドウサイズを変更する必要があります。 resizeイベントハンドラでは、タスクバーのウィンドウを非表示にします。ウィンドウサイズを変更する必要があります。 resizeイベントハンドラでは、タスクバーのウィンドウを非表示にしますが、これはウィンドウを再作成しません。「タスクバーに表示されていますか?フィールドは実際に既に更新されています。しかし、それは有名な "アクセスコントロール"ハンドリングを作成中に処理する無限ループになります - フレームワークのバグかもしれません(フォームが最小化または最大化されていても、 "通常サイズ"ではなく)。 Control.HandleForm.RecreateHandleCoreを呼び出してControl.Handleを呼び出します。完了しました。

これはすべてのマシンでどうして起こりませんか?サイズ変更は必ずしも必要ではないためです。これは、UIテーマ、フォントサイズ、ディスプレイなど、いくつでも関係しているかもしれませんが、基本的なエラーはまだあります。無限の再帰を引き起こしています。 Resizeというイベントが1つ少ないため、スキップされます。

なぜ例外をキャッチできませんか?さて、StackOverflowExceptionはこのように少し卑劣なことがあります。セキュリティの重要なコードの真中にいる可能性があります。ネイティブコールの内側にあります。スタックオーバーフローが発生します。どのくらい正確に回復しますか?すべてのランタイムは、スタックガードがヒットしたことを知っています。誰もがプログラムのメモリの半分を置き換えただけです。 OutOfMemoryExceptionは非常によく似ています。安全な状態に戻す方法がわからないので、唯一の選択肢は失敗に終わることです。 WindowStateShowInTaskbar前に問題を修正し二つの方法を変更する

- 1を、それはあなたのリサイズハンドラの動作方法を変更する - それはあなたのコードのエラーだし、ウィンドウの状態を変更すると、実行しているから、そのコード(ShowInTaskbar = false)を防ぐことができます。もう1つは、フォームがハンドルを再作成するときにアクセスするのは、ウィンドウが最小化または最大化されたときにのみアクセスすることです。つまり、フレームワークの部分です。Control.Handle言うまでもなく、これは非常に壊れやすく、このようなエラーは見つけて修正するのが難しい場合があります。

これを行う正しい方法は何でしょうか?最小化されたときにタスクバーからウィンドウを非表示にしたいとします。これは、ウィンドウの状態が非最小化されていて、最小化に変更された場合に限られます。そのため、古いウィンドウの状態を維持して確認する必要があります。

ShowInTaskbarの方がいいですね。あなたが本当に望むのは、ウィンドウが最小化されたときにウィンドウを隠すことだけです。 ShowHideは完全な信頼を必要とせず、Alt + Tabメニューでフォームを保持しません。 ShowInTaskbarは、何らかの形で接続された複数のウィンドウを持つアプリケーション向けです。別のフォームの上に表示されるモーダルダイアログ、同じZオーダーを持つマルチウィンドウインターフェイスなど。フォームを非表示にする必要がある場合は、非表示にします。私はフレームワークのデザイナーがShowInTaskbarプロパティを与えた唯一の理由は、デザイナーで適切なサポートを与えることだと思っていますが、フォームが作成された後は実際に変更するべきではありません。指定されたフォームはタスクバーに表示されるか、または表示されません。実行時に変更する必要はありません。

+0

Amen !!それは素晴らしい答えでした! – Saloom

関連する問題