On Windows XP and Vista, I can run this code:
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);
}
and it operates as I would expect, i.e. the WaitForSingleObject does not return until the Modem Control Panel window has been closed by the user.
On Windows 7, the same code, WaitForSingleObject returns straight away (with a return code of 0 indicating that the object signalled the requested state).
Similarly, if I take it to the command line, on XP and Vista I can run
start /wait rundll32.exe shell32.dll,Control_RunDLL modem.cpl
and it does not return control to the command prompt until the Control Panel window is closed, but on Windows 7 it returns immediately.
Is this a change in RunDll32? I know MS made some changes to RunDll32 in Windows 7 for UAC, and it looks from these experiments as though one of those changes might have involved spawning an additional process to display the window, and allowing the originating process to exit. The only thing that makes me think this might not be the case is that using a process explorer that shows the creation and destruction of processes, I do not see anything additional being created beyond the called rundll32 process itself.
Any other way I can solve this? I just don't want the function to return until the control panel window is closed.