Почему процесс RunDLL32 завершается рано в Windows 7? - PullRequest
3 голосов
/ 08 марта 2010

В 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 внесла некоторые изменения в RunDll32 в Windows 7 для UAC, и из этих экспериментов видно, что одно из этих изменений могло включать создание дополнительного процесса для отображения окна и разрешение исходящему процессу завершиться. Единственное, что заставляет меня думать, что это может быть не так, это то, что при использовании проводника процессов, который показывает создание и уничтожение процессов, я не вижу ничего дополнительного, созданного помимо самого вызываемого процесса rundll32.

Любой другой способ, которым я могу решить это? Я просто не хочу, чтобы функция возвращалась до тех пор, пока не закроется окно панели управления.

1 Ответ

3 голосов
/ 11 марта 2010

В случае, если кто-то еще столкнется с той же проблемой: я наконец-то обошел эту проблему с помощью технической поддержки Microsoft.

Они смогли подтвердить, что исходный процесс RunDll32 все еще выполняется (он не породил новый процесс), но по любой причине, по которой они не знают ответа, WaitForSingleObject () немедленно возвращается в этот процесс.

Обходной путь - по-другому запустить окно панели управления, используя CPLApplet, как в этом примере: http://support.microsoft.com/kb/232536

Однако проблема усложняется еще и тем, что 32-битная панель управления модемом не работает в 64-битной Windows (она отображается, но кнопка «Добавить» не работает). Я уже отключал перенаправление WOW64 в своем решении RunDLL на 64-битных платформах, и это работало нормально, но вы не можете загрузить 64-битную библиотеку в 32-битном приложении, поэтому мне пришлось создать новый процесс, чтобы сделать это ,

В итоге:

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...