プログラムを終了するには?

解決


未来  2006-06-07 22:46:41  No: 22103

プログラムの終了方法を教えてください。

タスクマネージャーのプロセス表示で
イメージ名を右クリックした時の
「プロセスツリーの終了」を実現したいのですが
どうすればよいのでしょうか?

現在、作成しているアプリケーション(A)から他のプログラム(B)を
CreateProcessで呼び出すと、呼び出したプログラム(B)から
別のプログラム(C)が呼び出されています。
中止ボタンをクリックすると、
TerminateProcess で (A)から呼び出したプログラム(B)の
プロセスを終了するところまではできるのですが、
プログラム(C)は動作したままで終了できません。
どうすればよいのでしょうか?


deldel  2006-06-08 00:01:15  No: 22104

h := FindWindow(nil, '対象アプリのタイトル');
if h <> 0 then SendMessage(h, WM_CLOSE, 0, 0);
はどうですか?


未来  2006-06-08 00:10:02  No: 22105

'対象アプリのタイトル'がわかりません。
コンソールアプリケーションだと思いますが、
アプリケーションには表示されてこないのです。


deldel  2006-06-08 01:05:30  No: 22106

WinSightやスパイなどで判りませんかねぇ・・・


Fusa  2006-06-08 09:43:16  No: 22107

プロセスを列挙して、プロセスIDを得てから
次のコードで終了してください。
var
  ProcessID: Cardinal;
  hProcess: THandle;
begin
  //ProcessIDを得ておく
  //ProcessID := xx;

  hProcess := OpenProcess(PROCESS_TERMINATE, False, ProcessID);
  TerminateProcess(hProcess , 0 );
  CloseHandle(hProcess);
end;
プロセス列挙コードは
http://delfusa.main.jp/delfusalibrary/20060527212010/SystemUnit/SystemUnit.pas
のGetProcExeNameList関数になります。 

(A)から呼び出した(C)なのかどうかを
特定する処理はちょっとわかりませんが。
呼び出す前にプロセス列挙して、終了したいときにプロセス列挙して
その差分を求めるとかですかな?

お任せします。


未来  2006-06-08 20:26:57  No: 22108

みなさん、どうもありがとうございます。

>Fusaさん
http://delfusa.main.jp/delfusalibrary/20060527212010/SystemUnit/SystemUnit.pas
これはインターネットアドレスでしょうか?
開くことができませんでした。

ProcessID はクリエイトプロセスで起動したときの
ProcessInformation.hProcess を使ってはだめなのでしょうか?
これを使って OpenProcess を呼び出すと
hProcess が 0になります。

>deldel さん
EnumWindows を使ってウィンドウハンドルをキャッチできす。
ただ、ウィンドウがなければキャッチできません。
つまり、CreateProcess 起動時の StartupInfo.wShowWindow が
SW_SHOW の場合には動作するようにはなりましたが、
SW_HIDE の場合にはハンドルが取れなくなります。

それから・・・
作成しているプログラムAからバッチファイルBを非表示で
実行します。また、BからはプログラムCが呼ばれています。
現在以下のことがわかっています。
実現したいのは2番または3番です。
宜しくお願いします。

1.Bを起動して、タスクマネージャのプロセスで
    Bを[プロセスの終了]で終了すると、
    Bが残る==>NG
    <CreateProcess で起動時の プロセスID を使って
    TerminateProcess を呼び出すと同じ症状になる>
2.Bを起動して、タスクマネージャのプロセスで
    C を[プロセスの終了]で終了すると、
    A,Bが消える==>OK
    <Cを特定することができれば可能ですが、
    現状ではその方法がわかりません>
3.Bを起動して、タスクマネージャのプロセスで
    Bを[プロセスツリーの終了]で終了すると、
    A,Bが消える==>OK
    <実現方法がわかりません>
4.Bのウィンドウが表示するようにするとEnumWindowsを使って
    ハンドルを取得して SendMessage(h, WM_CLOSE, 0, 0); で
    クローズする==>OK(ただし、目的は非表示で動作)
    <CreateProcess で起動時に StartupInfo.wShowWindow        := SW_SHOW
    で起動して、EnumWindows でハンドルを取得し、SendMessage で
    WM_CLOSE を送ることで実現可能>


WH00  2006-06-08 20:39:39  No: 22109

>4.Bのウィンドウが表示するようにするとEnumWindowsを使って
>    ハンドルを取得して SendMessage(h, WM_CLOSE, 0, 0); で
>    クローズする==>OK(ただし、目的は非表示で動作)

Form1.Width := 0;
Form1.Height := 0;
Form1.Top := 3333;

・・・でダメですか?


未来  2006-06-08 20:48:34  No: 22110

みなさん、すみませんでした。

私の認識不足でした。
EnumWindows で呼び出された コールバック関数に
IsWindowVisible が入っていました。
これがはいっているので
StartupInfo.wShowWindow が SW_HIDE のときにハンドルが
取れなかったようです。

おさわがせしてすみませんでした。


Fusa  2006-06-08 22:07:48  No: 22111

HTTPの最初の文字を全角のHにしてますが....

> ProcessID はクリエイトプロセスで起動したときの
> ProcessInformation.hProcess を使ってはだめなのでしょうか?
わかりませんが、
タスクマネージャの列の選択で表示できるPIDと同じものなら
OpenProcessでプロセス終了できるはずですよ。

こちらも参考ください。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加