I am writing a master installer with the following ShellExecuteEx() function that call a few Advanced Installer created installers (installing multiple products) one by one through a loop construct.
// Shell Execute
bool CFileHelper::ShellExecute(CString strCommandPath, CString strOptions)
{
CString strQCommandPath = CString(_T("\"")) + strCommandPath + CString(_T("\"")); //place the command in the quote to handle path with space
LPWSTR szInstallerPath = strQCommandPath.GetBuffer();
LPWSTR szOptions = strOptions.GetBuffer(MAX_PATH);
SHELLEXECUTEINFO ShellInfo; // Name structure
memset(&ShellInfo, 0, sizeof(ShellInfo)); // Set up memory block
ShellInfo.cbSize = sizeof(ShellInfo); // Set up structure size
ShellInfo.hwnd = 0; // Calling window handle
ShellInfo.lpVerb = _T("open");
ShellInfo.lpFile = szInstallerPath;
ShellInfo.fMask = SEE_MASK_NOCLOSEPROCESS; //| SEE_MASK_NOASYNC | SEE_MASK_WAITFORINPUTIDLE;
ShellInfo.lpParameters = szOptions;
bool res = ShellExecuteEx(&ShellInfo); // Call to function
if (!res)
{
//printf( "CreateProcess failed (%d).\n", GetLastError() );
CString strMsg = CString(_T("Failed to execute command ")) + strCommandPath + CString(_T("!"));
AfxMessageBox(strMsg);
return false;
}
WaitForSingleObject(ShellInfo.hProcess, INFINITE); // wait forever for process to finish
//WaitForInputIdle(ShellInfo.hProcess, INFINITE);
CloseHandle( ShellInfo.hProcess);
strQCommandPath.ReleaseBuffer();
strOptions.ReleaseBuffer();
return true;
}
The function work every well when I have this master installer and other individual product installers on hard drive.
However, if I move all of them to either USB drive or CD, the ShellExecuteEx() didn't wait for the previous product installer to complete its task. So all product installers get lunched at once; giving me the error message "Another installation is in progress. You must complete that installation before continuing this one.".
One thing puzzle me is why it works on hard drive but not on USB drive and CD drive. I need to distribute the products on CD.
Putting Sleep(500) before WaitForSingleObject(ShellInfo.hProcess, INFINITE) didn't help as well.