質問: お世話になります。 一般的には、フォームを立ち上げていても、ログオフやシャットダウンをすれば 一緒に閉じるものなのですが、単体起動するフォームのアプリをdllにし、 別のアプリから参照してdll化したフォームを立ち上げると、ログオフ、及び シャットダウンしたときには親フォームはきちんと閉じるのに、dll化した アプリの方が閉じずに、『このアプリが再起動を妨げています。』のような メッセージが出て、シャットダウンが止まってしまいます。 そのため、ネットで調べ、下記のイベントを実装して、シャットダウン、ログオフを しようとしたときに、併せてフォームが閉じるようにしようとしたのですが、これでも駄目。 ``` //ログオフ、シャットダウンしようとしているとき private void SystemEvents_SessionEnding(object sender, SessionEndingEventArgs e) { Application.Exit(); } ``` ちなみに、dll化したフォームはデジタル時計を作ったアプリで、Timerで 一秒ごとフォームを再描画する仕様のものですが、それが何かの原因なのでしょうか? このフォームは、単体のexeのままなら、きちんとシャットダウン時に閉じてくれます。 原因と対策をご指導いただけますでしょうか。 よろしくお願いいたします。 追記・すみません。原因の探り方が甘かったみたいです。 試してみたところ、原因はdll化した方ではなく、呼び出している親アプリの方でした。 一度、ゼロからフォームを立ち上げて、そこに時計のdllフォームを呼び出せば、無事 シャットダウンに併せてクローズ、しかし、空のフォームをdll化して既存の親のアプリで 呼び出すと、時計の時と同じように再起動を妨げました。 dllは一切問題はないようです。確認の方法が不足しており、申し訳ありませんでした。 さて、そこで親元のアプリの方ですが、クローズボタンを押しても終了させず、 最小化させて、タスクトレイに常駐、アプリの終了はCotentMenuStripのメニューから 『終了』を選ぶことで、Application.Exit()を呼び出して終了させる流れを作っています。 これが原因になっているのでしょうか。 更に追記・どうも原因がいろいろと重なっているらしく、親アプリの方でFormClisingで クローズをキャンセルするとシャットダウンの時にも終了されることがないようです。 しかし、シャットダウン時の例の警告画面には親アプリの名前は出てきません。どういうわけか、 親、子とも閉じられていないのに警告は子供のみ表示されるようです。 また、クローズをキャンセルすることで、上記SystemEvents_SessionEndingも 実行されないようです。 更に問題は、例のシャットダウンの警告画面がSystemEvents_SessionEndingメソッドが 走るより前に表示されてしまうため、たとえこのメソッドでクローズさせようとしても もう遅いということです(Windows10にて)。 初めの表題の内容とは意味合いが異なってしまいましたが、システムのシャットダウン時に、 親アプリがきちんと終了させられれば解決できそうですが、 そういった方法はありますでしょうか。 何度も申し訳ありませんが、よろしくお願いいたします。
回答: FormClosing の FormClosingEventArgs e.CloseReason の値で判定できませんか? CloseReason.WindowsShutDown, CloseReason.TaskManagerClosing 以外の時は最小化・タスクトレイ常駐・Cancel=Trueする (質問に記載の要件だけであれば CloseReason.WindowsShutDown以外の時だけでもいいかもしれません )