ペイントブラシの終了を待機(C言語)

説明:

95などのペイントブラシ(pbrush.exe)は通常、mspaint.exeを起動して直ちに終了してしまうため、ペイントブラシの終了をWaitForSingleObjectで待機することはできない。以下のサンプルでは、pbrush.exe起動後ジョブオブジェクトに関連付けることにより、pbrushが起動したプロセスを追跡し、それらのプロセスがすべて終了するまで待機する。(注:プロセスはサスペンドでの起動はしていない。また、ジョブオブジェクトに関連付けられているプロセスが終了した場合にそのプロセスIDが他の新規プロセスに割り当てられるかどうかは未調査。)

キーワード:

CreateJobObject, AssignProcessToJobObject, QueryInformationJobObject

サンプルコード:

/* ペイントブラシの終了まで待機 */
void WaitPBrush()
{
	HANDLE hJob;
	STARTUPINFO si;
	PROCESS_INFORMATION pi;
	DWORD i;
	HANDLE hProcess;
	BOOL bJobAllEnd;

	PJOBOBJECT_BASIC_PROCESS_ID_LIST pList;
	pList = (PJOBOBJECT_BASIC_PROCESS_ID_LIST)GlobalAlloc(GMEM_FIXED, 10000);

	si.cb = sizeof(si);
	si.lpReserved = NULL;
	si.lpDesktop = NULL;
	si.lpTitle = NULL;
	si.dwFlags = 0;
	si.cbReserved2 = 0;
	si.lpReserved2 = NULL;

	/* ジョブオブジェクトの作成 */
	hJob = CreateJobObject(NULL, "Test Job Object");

	/* ペイントブラシの起動 */
	CreateProcess("c:\\winnt\\system32\\pbrush.exe", NULL, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);

	/* ペイントブラシをジョブオブジェクトに関連付ける */
	AssignProcessToJobObject(hJob, pi.hProcess);

	/* ペイントブラシの終了まで待機 */
	printf("待機...\n");
	do {
		/* 起動しているプロセス群を取得 */
		QueryInformationJobObject(hJob, JobObjectBasicProcessIdList, pList, 10000, NULL);

		for(i=0; i<pList->NumberOfProcessIdsInList; i++) printf("%d ", pList->ProcessIdList[i]);
		printf("\n");
		
		bJobAllEnd = TRUE;

		/* 全てのプロセスが終了したかどうかを判定。
		   起動しているプロセスがある場合、bJobAllEndがFALSEになる */
		for(i=0; i<pList->NumberOfProcessIdsInList; i++) {
			/* ここでは、プロセスの同期アクセスでのオープンに失敗したら、
			   そのプロセスが終了しているものとする */			
			hProcess = OpenProcess(SYNCHRONIZE, FALSE, pList->ProcessIdList[i]);
			if(hProcess != NULL) {
				CloseHandle(hProcess);
				bJobAllEnd = FALSE;
			}
		}

		Sleep(300);

	} while(!bJobAllEnd); /* 全てのプロセスが終了するまで続行 */

	printf("終了\n");

	/* 後処理 */
	GlobalFree(pList);
	CloseHandle(hJob);
}
(original text:1999/01/11 更新)

本ドキュメントの内容は保証しません。本ドキュメントによって生じた結果について、一切の責任を負いません。