C++で外部アプリを終了させたい

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
DAICHI0922
記事: 26
登録日時: 8ヶ月前

C++で外部アプリを終了させたい

#1

投稿記事 by DAICHI0922 » 4ヶ月前

C++でCtrl+Delを押すと、フォアグラウンドの外部アプリを終了させるプログラムを書いています。

以下のようなプログラムなのですが、うまくいくときと行かないときがあります。
メモ帳のような単一のexeで動いているプログラムは終了できるのですが、その他のアプリは終了できないようです。以下のコードでは、PostMessageを使っていますがDestroyWindowやTerminateProcessなども使ってみましたが無理のようです。まるでメッセージを送っても処理する気が無いように...

このプログラムのどこがおかしいか指摘していただけると嬉しいです。

コード:

#include<Windows.h>
#include<thread>

using namespace std;

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR CmdLine, int CmdShow) {
	MSG msg;
	LPSTR lpStr = 0;
	while (TRUE) {
		if (GetAsyncKeyState(VK_CONTROL) < 0 && GetAsyncKeyState(VK_DELETE) < 0) {
			HWND hWnd = GetForegroundWindow();
			if (hWnd == NULL) {
				MessageBox(hWnd, "ウィンドウを閉じることができませんでした", "エラー", MB_ICONERROR);
			}
			else {
				if (SendNotifyMessage(hWnd, WM_DESTROY, 0, 0) == 0) {
					MessageBox(hWnd, "ウィンドウを閉じることができませんでした", "エラー", MB_ICONERROR);
				}
				else this_thread::sleep_for(chrono::milliseconds(300)); //複数ウィンドウを閉じてしまうの防止
			}
		}

		if (GetAsyncKeyState(VK_CONTROL) < 0 && GetAsyncKeyState('Q') < 0) {
			HWND hWnd = GetForegroundWindow();
			int ret = MessageBox(hWnd, "終了しますか?", "ウィンドウ操作", MB_ICONINFORMATION | MB_YESNO);
			if (ret == IDYES)break;
		}
		this_thread::sleep_for(chrono::milliseconds(3)); //負荷を軽くするため?に少し止める
	}
	return 0;
}

YuO
記事: 936
登録日時: 8年前
住所: 東京都世田谷区

Re: C++で外部アプリを終了させたい

#2

投稿記事 by YuO » 4ヶ月前

基本的なこととして,WM_DESTROYDestroyWindowによって生成されるメッセージであって,
それを送ることでWindowを破棄するためのものではありません。
通常は,WM_CLOSEを送って処理を依頼します。
オフトピック
WM_CLOSEはWindowを閉じることの依頼
メモ帳などでは,WM_CLOSE→(確認)→DestroyWindow→WM_DESTROY→PostQuitMessageという流れで終了しているのだと思います。

DAICHI0922 さんが書きました:
4ヶ月前
メモ帳のような単一のexeで動いているプログラムは終了できるのですが、
だいたいは単一の.exeだと思うのですが……。
単一のexe→単一のWindowと読み替えるのであれば,該当するProcess内の全てのWindowにWM_CLOSEを送ればよいわけです。
つまり,GetWindowThreadProcessIdで目的のProcess IDを取得し,EnumWindowsで列挙したWindowのProcess IDを比較しながらWM_CLOSEを送っていく,という流れになります。
DAICHI0922 さんが書きました:
4ヶ月前
TerminateProcessなども使ってみましたが無理のようです。
TerminateProcessでプロセスが終了しない,は問題なのですが……。
無理と言うのは,TerminateProcessがTRUEを返したのに終了しなかった,ということですか?

DAICHI0922
記事: 26
登録日時: 8ヶ月前

Re: C++で外部アプリを終了させたい

#3

投稿記事 by DAICHI0922 » 4ヶ月前

ありがとうございます。
TerminateProcessは第一因数にウィンドウハンドルを渡してみたのですが、何一つ終了できませんでした。(エラーとなります)

GetWindowThreadProcessをつかってアルゴリズムの例、もう少し詳しく聞かしていただけませんか?

アバター
あたっしゅ
記事: 242
登録日時: 8年前
住所: 東京23区
連絡を取る:

Re: C++で外部アプリを終了させたい

#4

投稿記事 by あたっしゅ » 4ヶ月前

https://dobon.net/vb/dotnet/process/get ... title.html
ウィンドウのタイトルからプロセスを探す - DOBON.NET(ja)
ここでは、ウィンドウのタイトルバーに表示されているテキスト(タイトル、キャプション)、あるいは、ウィンドウが属しているクラス名から、そのウィンドウを作成したプロセスを探す方法を紹介します。

これで、どうだ。
手提鞄あたっしゅ、[MrAtassyu] http://atassyu.rosx.net/
2019(R01)-08-11(日・祝) コミックマーケット C96 日 西さ34a 手提鞄屋魚有店(てさげかばんやうおありてん)

アバター
あたっしゅ
記事: 242
登録日時: 8年前
住所: 東京23区
連絡を取る:

Re: C++で外部アプリを終了させたい

#5

投稿記事 by あたっしゅ » 4ヶ月前

よく見たら、C++ じゃなくて、VB, C# だった。
手提鞄あたっしゅ、[MrAtassyu] http://atassyu.rosx.net/
2019(R01)-08-11(日・祝) コミックマーケット C96 日 西さ34a 手提鞄屋魚有店(てさげかばんやうおありてん)

アバター
あたっしゅ
記事: 242
登録日時: 8年前
住所: 東京23区
連絡を取る:

Re: C++で外部アプリを終了させたい

#6

投稿記事 by あたっしゅ » 4ヶ月前

https://code.i-harness.com/ja-jp/q/1cd25f
c++ プロセスハンドル プロセスハンドル取得 - プロセスIDからメインウィンドウのハンドルを取得するには? - CODE Q&A 問題解決(ja)

http://akky.xrea.jp/mfc/appclose.html
起動したアプリケーションを終了させる(ja)
手提鞄あたっしゅ、[MrAtassyu] http://atassyu.rosx.net/
2019(R01)-08-11(日・祝) コミックマーケット C96 日 西さ34a 手提鞄屋魚有店(てさげかばんやうおありてん)

返信

“C言語何でも質問掲示板” へ戻る