質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.34%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

Windows Forms

Windows Forms(WinForms)はMicrosoft .NET フレームワークに含まれる視覚的なアプリケーションのプログラミングインターフェイス(API)です。WinFormsは管理されているコードの既存のWindowsのAPIをラップすることで元のMicrosoft Windowsのインターフェイスのエレメントにアクセスすることができます。

Q&A

1回答

370閲覧

C# 別プロセス終了時にその別プロセスが最終的に開いたプロセスを全て終了させたい

mysknj

総合スコア4

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

Windows Forms

Windows Forms(WinForms)はMicrosoft .NET フレームワークに含まれる視覚的なアプリケーションのプログラミングインターフェイス(API)です。WinFormsは管理されているコードの既存のWindowsのAPIをラップすることで元のMicrosoft Windowsのインターフェイスのエレメントにアクセスすることができます。

0グッド

0クリップ

投稿2024/11/25 18:01

編集2024/11/25 19:09

実現したいこと

現在質問している以下の質問でいろいろ調べているうちに別の疑問が生まれたので少し変えて質問させていただきます。
https://teratail.com/questions/7dtgt9o444m1ch

自フォームから別のプロセスを起動させ、起動したプロセスやその子孫プロセスすべてをフォーム側で終了させたく、以下のサイトを参照して起動させた親プロセスを終了時に子孫プロセスも終了させる処理を記載しましたが、上手くいきませんでした。
https://qiita.com/kenichiuda/items/3079ab93dae564dd5d17

試しに例に記載のメモ帳の起動と終了に関しては上手くいったので、原因を調べたところ
今回終了させたいexeが以下の挙動をしていました。
①プロセス起動
②起動したプロセスのさらに下層のフォルダにある別のexeを起動
③①で起動したプロセスは終了

このような場合は、親プロセスとなる最初に開いたプロセスが既に終了しているためそのあとに開かれたexeは子孫プロセスには該当しないため、現状のコードでは最終的に実行されているプロセスを終了できないのでしょうか?

また、今回のような場合に最終的に開いたプロセスを、フォーム側で直接指定して終了させる術はあるのでしょうか?
フォーム側でプロセスを起動しなくても、対象exeを指定して、対象のexeが最終的に開いたexeを終了や
フォーム側でプロセスを起動した際に、そのプロセスが最終的に開いたプロセスを補足して保持しておき、終了したいときに終了させる等、方法は何でもよいのでご教示いただきたいです。

ちなみにですが、子孫プロセスを終了させる方法として以下のサイトも参照しましたが、こちらはちょっと難しくてよくわからず実行できませんでした。このサイトのやり方ならできるとかあるのでしょうか?
https://www.meziantou.net/killing-all-child-processes-when-the-parent-exits-job-object.htm

皆様ご教授お願いいたします。

発生している問題・分からないこと

上記をまとめると以下の通りです。

親プロセスとなる最初に開いたプロセスが既に終了している場合、最終的に開かれたプロセスは子孫プロセスには該当しないのか。

上記理由で現状のコードでは終了できないのか。

最終的に開いたプロセスをフォーム側で直接指定して終了させる術はあるのか?
※フォーム側でプロセスを起動しなくても、対象exeを指定して、対象のexeが最終的に開いたexeを終了や
フォーム側でプロセスを起動した際に、そのプロセスが最終的に開いたプロセスを補足して保持しておき、終了したいときに終了させる等、方法は何でもよいです。

知識は疎いので詳しく説明していただけるとありがたいです。
皆様のお知恵をお借りさせていただきたいです。よろしくお願いいたします。

該当のソースコード

C#

1//クラス 2//クラスに関しては長すぎて文字数制限を超えてしまうため以下URLを参照していただきたいです。クラスはそのままコピペして使ってます。 3https://qiita.com/kenichiuda/items/3079ab93dae564dd5d17 4 5//フォーム側の処理 6Process process; 7 8 private void open_Click(object sender, EventArgs e) 9 { 10 process = Process.Start(対象のexe); 11 } 12 13 private void close_Click(object sender, EventArgs e) 14 { 15 using (var job = JobObject.CreateAsKillOnJobClose()) 16 { 17 job.AssignProcess(process); 18 } // notepad.exe killed 19 }

試したこと・調べたこと

  • teratailやGoogle等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果

最終的に開かれたプロセスが子孫プロセスに該当しないのか、プロセスを終了できない。

補足

C#
visualstudio:Windowsフォーム

現状の対応では、起動したexeのファイルパスを参照して
起動したexeが格納されているフォルダとその下層にあるフォルダ内で実行されているexeを全て終了させるという対応をしていますが、この場合実行されているプロセスを全て参照し、ファイルパスが一致しているかという処理を行っているため、処理に時間がかかるので、時間がかからないように
最終的に開いたプロセスを補足して終了させたいです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kikukiku

2024/11/25 23:57

仮に一番簡単な構成としましょう。 下記のような順番で呼びだしたとします。  アプリA→アプリB→アプリC 確認です。 ・アプリAは改修可能ですか? ・アプリBは改修可能ですか? ・アプリCは改修可能ですか?
dodox86

2024/11/26 00:08

@質問者 mkmtさん 先のご質問やコメント中の記載にも言えますが、プロセス(起動したEXE)の親子関係と、それらEXEファイルの配置場所のフォルダーの位置(下層、上層)は関係ありません。言葉が足りなかったのかあるいは本当に誤解しているのか分かりませんが、区別して考えることは重要です。 (例えばC:\hoge\fuga\parent.exeがC:\hoge\child.exeを起動すれば、下層に配置されているC:\hoge\fuga\parent.exeが親プロセスになります) ※ごっちゃにしていると話がかみ合わなくと思ったのでコメントする次第です。
matukeso

2024/11/26 12:44

qiitaの記事でも、win32 job objectを作ってプロセスを属させているので、子が先に死んだ孫であっても殺せるはずです。 >上手くいきませんでした。 どうダメだっんですか?
guest

回答1

0

親プロセスとなる最初に開いたプロセスが既に終了している場合、最終的に開かれたプロセスは子孫プロセスには該当しないのか。

子孫プロセスという概念は存在しません。
以下のような親子関係があったとして、process Bが終了すると、process Cとprocess Aの関係は切れてしまいます。
process A -> process B -> process C

なので、プロセスツリー(プロセスの階層構造)の途中のプロセスが終了した後で、元のプロセスツリーに含まれていたプロセスの一覧を得る一般的な方法はありません。

プロセスの修了について
勘違いしているような気がするのですが、プロセスは通常の方法で外から止めることはできません。それは親プロセスを子プロセスが修了させる場合も同様です。プロセスは自分の判断で修了するのが通常の方法です。
質問にあるリンクの方法も、ちゃんと読んでませんが、「子プロセスとして起動されるプロセスが、親プロセスの修了を検知して自分で修了するようなしくみにする」という内容だと思います。
今回の場合、呼び出すプログラム(exe)やその子孫を改変できないのであれば、同様の仕組みを入れることはできません。

質問の状況で、残っているプロセスの修了を待つのではなく、強制的に修了したいのであれば、前の質問にあるように、プロセスの情報から該当するものを抽出して強制的に止めるしかないでしょうね。
ただし、プロセスによっては、強制的に修了されないようにしてあるものもあるかもしれません。
また、コメントにもありますが、プロセスの強制修了には危険が伴います。たとえば、プロセスの起動に必要なファイルを開いて編集しているときに強制修了することでそのファイルが破損し、次回以降起動できなくなるなどの問題が発生したりなど。

投稿2024/11/26 06:06

TakaiY

総合スコア13907

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.34%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問