Windows XP と Vista では、次のコードを実行できます。
STARTUPINFO si;
PROCESS_INFORMATION pi;
BOOL bResult = FALSE;
ZeroMemory(&pi, sizeof(pi));
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(STARTUPINFO);
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = SW_SHOW;
bResult = CreateProcess(NULL,
"rundll32.exe shell32.dll,Control_RunDLL modem.cpl",
NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL,
&si, &pi);
if (bResult)
{
WaitForSingleObject(pi.hProcess, INFINITE);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
つまり、ユーザーがモデム コントロール パネル ウィンドウを閉じるまで、WaitForSingleObject は戻りません。
Windows 7 では、同じコードである WaitForSingleObject がすぐに戻ります (戻りコード 0 は、オブジェクトが要求された状態を通知したことを示します)。
同様に、コマンド ラインで実行すると、XP と Vista で実行できます。
start /wait rundll32.exe shell32.dll,Control_RunDLL modem.cpl
また、コントロール パネル ウィンドウが閉じられるまでコマンド プロンプトに制御が戻りませんが、Windows 7 ではすぐに戻ります。
これは RunDll32 の変更ですか? MS が UAC のために Windows 7 の RunDll32 にいくつかの変更を加えたことを私は知っています。これらの実験から、これらの変更の 1 つは、ウィンドウを表示するための追加のプロセスを生成し、元のプロセスを終了できるようにすることが含まれているように見えます。これが事実ではないかもしれないと私に思わせる唯一のことは、プロセスの作成と破棄を示すプロセスエクスプローラーを使用して、呼び出された rundll32 プロセス自体を超えて追加の作成が見られないことです。
これを解決できる他の方法はありますか?コントロールパネルウィンドウが閉じられるまで、関数が返されないようにしたいだけです。