17623


お世話になります。

前回、dllでのフォームが閉じないという内容で投げた質問の続きになります。  
その時は、はっきりと原因を突き止めずに質問をしてしまい、大変申し訳ありませんでした。

やろうとしていることは、前回と同じです。  
アプリのフォームが立ち上がっているときに、Windowsのシャットダウン、あるいは  
再起動をかけるると、アプリの子供のフォームが消えずに残ってしまい、SDや再起動を  
妨げてしまうのを解決する方法です。

前回は自分でdllだからかと思ってしまいましたが、回答者様が指摘していただいたとおり、  
dll云々は関係ありませんでした。

メインのフォームでやっていることは、タスクトレイ常駐型のアプリを作ろうとしているため、  
クローズボタンでは閉じず、タスクトレイのアイコンを右クリックで表示されるコンテキスト  
メニューの『閉じる』選択で、Application.Exit()で終了させています。  
しかし、SD、及び再起動時に、メインのフォームは最小化するだけ、子供として呼び出した  
フォームは閉じずに残り、再起動などを妨げます。また、一度再起動をキャンセルし、  
もう一度シャットダウンをしても、やはり同じように残り続けます。  
メインフォームは閉じられませんが、再起動を妨げたりしません。

下記に、必要と思われる全コードを掲示します。

再度お手数をおかけすることになると思いますが、何卒ご助力をお願いいたします。

* * *
[code]

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    using Microsoft.Win32;
    
    namespace ResidentForm
    {
        public partial class Form1 : Form
        {
            //　問題の閉じないフォーム。ただ単純なフォームです。
            private Form3 f = new Form3();
    
            public Form1()
            {
                InitializeComponent();
                SystemEvents.SessionEnding +=
                    new SessionEndingEventHandler(SystemEvents_SessionEnding);
            }
    
    
    
            private void tsmiQuit_Click(object sender, EventArgs e)
            {
                notifyIcon1.Visible = false; // アイコンをトレイから取り除く
                Application.Exit(); // アプリケーションの終了
            }
    
            private void notifyIcon1_DoubleClick(object sender, EventArgs e)
            {
                this.Visible = true; // フォームの表示
                if (this.WindowState == FormWindowState.Minimized)
                {
                    this.WindowState = FormWindowState.Normal; // 最小化をやめる
                }
                this.Activate(); // フォームをアクティブにする
            }
    
            private void Form1_FormClosing(object sender, FormClosingEventArgs e)
            {
                if (e.CloseReason != CloseReason.ApplicationExitCall
                  //　追記しました
                  || e.CloseReason != CloseReason != CloseReason.WindowsShutDown
                )
                {
                    e.Cancel = true; // フォームが閉じるのをキャンセル
                    this.Visible = false; // フォームの非表示
                }
            }
    
            //ログオフ、シャットダウンしようとしているとき
            private void SystemEvents_SessionEnding(object sender, SessionEndingEventArgs e)
            {
                if (e.Reason == SessionEndReasons.Logoff || e.Reason == SessionEndReasons.SystemShutdown)
                {
                    this.f.Hide();
                    Application.Exit();
                }
            }
    
            private void SlideshowBackForm_FormClosed(object sender, FormClosedEventArgs e)
            {
                //イベントを解放する
                SystemEvents.SessionEnding -=
                    new SessionEndingEventHandler(SystemEvents_SessionEnding);
            }
    
            private void Form1_Shown(object sender, EventArgs e)
            {
                this.f.Visible = true;
            }
        }
    }
    
    namespace ResidentForm
    {
        partial class Form1
        {
            /// <summary>
            /// 必要なデザイナー変数です。
            /// </summary>
            private System.ComponentModel.IContainer components = null;
    
            /// <summary>
            /// 使用中のリソースをすべてクリーンアップします。
            /// </summary>
            /// <param name="disposing">マネージ リソースが破棄される場合 true、破棄されない場合は false です。</param>
            protected override void Dispose(bool disposing)
            {
                if (disposing && (components != null))
                {
                    components.Dispose();
                }
                base.Dispose(disposing);
            }
    
            #region Windows フォーム デザイナーで生成されたコード
    
            /// <summary>
            /// デザイナー サポートに必要なメソッドです。このメソッドの内容を
            /// コード エディターで変更しないでください。
            /// </summary>
            private void InitializeComponent()
            {
                this.components = new System.ComponentModel.Container();
                System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1));
                this.notifyIcon1 = new System.Windows.Forms.NotifyIcon(this.components);
                this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components);
                this.tsmiQuit = new System.Windows.Forms.ToolStripMenuItem();
                this.contextMenuStrip1.SuspendLayout();
                this.SuspendLayout();
                // 
                // notifyIcon1
                // 
                this.notifyIcon1.ContextMenuStrip = this.contextMenuStrip1;
                this.notifyIcon1.Icon = ((System.Drawing.Icon)(resources.GetObject("notifyIcon1.Icon")));
                this.notifyIcon1.Visible = true;
                this.notifyIcon1.DoubleClick += new System.EventHandler(this.notifyIcon1_DoubleClick);
                // 
                // contextMenuStrip1
                // 
                this.contextMenuStrip1.ImageScalingSize = new System.Drawing.Size(20, 20);
                this.contextMenuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
                this.tsmiQuit});
                this.contextMenuStrip1.Name = "contextMenuStrip1";
                this.contextMenuStrip1.Size = new System.Drawing.Size(115, 30);
                // 
                // tsmiQuit
                // 
                this.tsmiQuit.Name = "tsmiQuit";
                this.tsmiQuit.Size = new System.Drawing.Size(114, 26);
                this.tsmiQuit.Text = "終了";
                this.tsmiQuit.Click += new System.EventHandler(this.tsmiQuit_Click);
                // 
                // Form1
                // 
                this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 15F);
                this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
                this.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom;
                this.ClientSize = new System.Drawing.Size(282, 253);
                this.KeyPreview = true;
                this.Name = "Form1";
                this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Form1_FormClosing);
                this.Shown += new System.EventHandler(this.Form1_Shown);
                this.contextMenuStrip1.ResumeLayout(false);
                this.ResumeLayout(false);
    
            }
    
            #endregion
            private System.Windows.Forms.NotifyIcon notifyIcon1;
            private System.Windows.Forms.ContextMenuStrip contextMenuStrip1;
            private System.Windows.Forms.ToolStripMenuItem tsmiQuit;
        }
    }
    
[/code]


CC BY-SA 3.0
2015-10-14T01:17:03.980
17621
2015-10-14T05:53:27.557
2015-10-14T04:34:02.123
5793
9374
question
c#
C# シャットダウン、再起動時に子のフォームが閉じないで残ってしまう


前の質問にも回答しましたがFormClosing の e.CloseReason の条件に (e.CloseReason !=
CloseReason.WindowsShutDown)も追加してください。  
これを加えないとシャットダウンの時もe.Cancel=Trueにしているので
SystemEvents_SessionEndingイベントが発生しなくなってるような気がします。

なんかe.Cancel=trueにするのは UserClosingのみでいい気がします。  
FormOwnerClosingとかもフォローする必要がありそうなので。  
また子フォームが閉じないのであれば明示的にClose()するとか。

[code]

    if (e.CloseReason == CloseReason.UserClosing) {
        e.Cancel = true;
        this.Visible = false;
    }else{
        this.f.close();
    }
    
[/code]


CC BY-SA 3.0
2015-10-14T01:50:45.860
17623
2015-10-14T05:53:27.557
2015-10-14T05:53:27.557
7343
7343
17621
answer