DOBON.NETプログラミング道掲示板

No35573 の記事


■35573 / )  Processクラスからbatファイル実行後、KILLできない
□投稿者/ あばば無人君 一般人(1回)-(2024/01/13(Sat) 05:19:30)
  • アイコン環境/言語:[Windows10(64bit/Home/22H2)、NET Framework-4.8.1、C#] 
    分類:[.NET] 

    約3年ぶりの投稿となります。宜しくお願いします。

    掲題の件ですが、WinFormアプリを新規で用意し、
    画面に開始ボタン(button1)と停止ボタン(button2)を配置しました。

    開始ボタンを押下するとProcessクラスでbatファイルを実行し、
    その処理が終わる前に停止ボタンを押下するとProcessクラスの
    KILLを実行して強制終了させる、というシンプルなアプリです。

    その実装は以下となります。
    001 public partial class Form1 : Form
    002 {
    003 private Process myProcess;
    004
    005 public Form1()
    006 {
    007 InitializeComponent();
    008
    009 this.button1.Click += this.button1_Click;
    010
    011 this.button2.Click += this.button2_Click;
    012 this.button2.Enabled = false;
    013 }
    014
    015 private void button1_Click(object sender, EventArgs e)
    016 {
    017 // 開始ボタン:非活性 / 停止ボタン:活性
    018 SwitchButtonEnable(false);
    019
    020 // 10秒間スリープするだけのバッチを指定
    021 this.myProcess = new Process();
    022 this.myProcess.StartInfo.FileName = @".\Sample.bat";
    023
    024 // バッチ処理の終了時に発生させるイベント処理を指定
    025 // ※SynchronizingObjectプロパティに当画面のインスタンスを指定することで
    026 // このイベント処理はGUIスレッドで動作する
    027 this.myProcess.Exited += button2_Click;
    028 this.myProcess.EnableRaisingEvents = true;
    029 this.myProcess.SynchronizingObject = this;
    030
    031 // 開始
    032 this.myProcess.Start();
    033 }
    034
    035 private void button2_Click(object sender, EventArgs e)
    036 {
    037 // すでに当処理が実施済みなら何もしない
    038 if (this.myProcess == null) { return; }
    039
    040 // バッチ処理の終了時に発生させるイベント処理を削除
    041 this.myProcess.Exited -= button2_Click;
    042 this.myProcess.EnableRaisingEvents = false;
    043
    044 if (!this.myProcess.HasExited)
    045 {
    046 try
    047 {
    048 this.myProcess.Kill();
    049 }
    050 catch
    051 {
    052 // 停止ボタン押下直後にプロセスが終了したケースを想定
    053 // よって例外をキャッチしても何もしていない
    054 }
    055 }
    056
    057 // 怒涛のインスタンス開放
    058 this.myProcess.Refresh();
    059 this.myProcess.Close();
    060 this.myProcess.Dispose();
    061 using (this.myProcess) { }
    062
    063 // 閉じるボタン押下とプロセス終了イベントがほぼ同時に発生した時、
    064 // 当関数の処理が2回実行されない様にnullを設定しておく
    065 this.myProcess = null;
    066
    067 // 開始ボタン:活性 / 停止ボタン:非活性
    068 SwitchButtonEnable(true);
    069 }
    070
    071 private void SwitchButtonEnable(bool isEnable)
    072 {
    073 button1.Enabled = isEnable;
    074
    075 button2.Enabled = !isEnable;
    076 }
    077 }

    以上を踏まえて、このアプリ、停止ボタンを押下しても
    起動したbatが終了しません。
    コード22行目で指定している「Sample.bat」は
     timeout /T 10
    というスリープ処理が1行あるだけの物となっています。

    しかもコード22行目の起動対象ファイルを
    ・メモ帳 "C:\Windows\System32\notepad.exe"
    ・エクセルファイル ".\適当.xlsx"
    などにした場合は期待通り終了します。

    ここから質問ですが、
    @batだけ終了しないのは何故か?
    Abatを終了させる方法はあるか?
    が分かる方、いらっしゃいましたらお力添えいただきたいです。
    ※特にAが知りたいです

    長くなりましたが宜しくお願い致します。


違反を報告
返信 削除キー/


Mode/  Pass/


- Child Tree -