3

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 プロセス自体を超えて追加の作成が見られないことです。

これを解決できる他の方法はありますか?コントロールパネルウィンドウが閉じられるまで、関数が返されないようにしたいだけです。

4

1 に答える 1

3

他の誰かが同じ問題に遭遇した場合: Microsoft Tech Support の助けを借りて、最終的にこれを回避しました。

元の RunDll32 プロセスがまだ実行されていること (新しいプロセスが生成されていないこと) を確認できましたが、なんらかの理由で答えがわからないため、WaitForSingleObject() はそのプロセスにすぐに戻ります。

回避策は、次の例のように CPLApplet を使用して、別の方法でコントロール パネル ウィンドウを起動することです: http://support.microsoft.com/kb/232536

ただし、32 ビット モデムのコントロール パネルが 64 ビット Windows では機能しないため、問題はさらに複雑になります (表示されますが、[追加] ボタンは機能しません)。64 ビット プラットフォームの RunDLL ソリューションで WOW64 リダイレクトを既にオフにしていて、それはうまくいきましたが、32 ビット アプリに 64 ビット ライブラリをロードできないため、これを行うには新しいプロセスを生成する必要がありました。 .

要約すれば:

Win 7 64 bit: call CPLApplet via CreateProcess in 64-bit executable
Win 7 32 bit: call CPLApplet within my installer
XP / Vista 64 bit: turn off WOW64 redirection, use RunDll32
XP / Vista 32 bit: use RunDll32
于 2010-03-11T16:58:04.827 に答える