void CGetErrorDlg::OnBnClickedOk()
{
// TODO: ここにコントロール通知ハンドラ コードを追加します。
//OnOK();
UpdateData();
//コマンドオプションの連結
//LunchProcessの3つ目の引數に全部入れないとコマンドラインオプションが実行されないため
CString strCommand;
strCommand.Format(_T("/"%s/" %s"), m_ExecFileName, CommandLine);
//個別インストーラの起動
DWORD nErrorCode = LunchProcess(m_hWnd, NULL, strCommand, TRUE, TRUE);
m_ERRORCODE.Format("終了コード(%d)",nErrorCode);
UpdateData(FALSE);
}
DWORD CGetErrorDlg::LunchProcess(HWND hWnd, LPCTSTR lpszExecFileName, LPCTSTR lpszCommandLine, BOOL bWait, BOOL bMessageLoop)
{
DWORD dwExitCode = 0;
STARTUPINFO StartupInfo;
PROCESS_INFORMATION ProcessInfo;
::memset(&StartupInfo, 0, sizeof(StartupInfo));
::memset(&ProcessInfo, 0, sizeof(ProcessInfo));
if(::CreateProcess(lpszExecFileName, (LPTSTR)lpszCommandLine, NULL, NULL, FALSE, CREATE_SUSPENDED|NORMAL_PRIORITY_CLASS, NULL, NULL, &StartupInfo, &ProcessInfo))
{
::ResumeThread(ProcessInfo.hThread);
if(bWait)
{
// 外部プログラムの終了を待つ場合は、呼び出し元はDisableに設定する。
// ただ終了を待っていると、呼び出しもとの再描畫等が行われなくなるので
// メッセージループを行うようにしておく。
// WaitForSingleObjectの待ち時間はとりあえず、0.1秒としておく。
::EnableWindow(hWnd, FALSE);
while(::WaitForSingleObject(ProcessInfo.hProcess, 100) == WAIT_TIMEOUT)
{
if(bMessageLoop)
{
MSG msg;
while(::PeekMessage(&msg, NULL, NULL, NULL, PM_REMOVE))
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
}
}
::GetExitCodeProcess(ProcessInfo.hProcess, &dwExitCode);
::EnableWindow(hWnd, TRUE);
// 外部プログラムから戻ってきた時は下記の様な事を行わなければ、呼び出し元がキチンとアクティブにならない。
int nTargetID, nForegroundID;
DWORD sp_time;
// フォアグラウンドウィンドウを作成したスレッドのIDを取得
nForegroundID = GetWindowThreadProcessId(::GetForegroundWindow(), NULL);
// 目的のウィンドウを作成したスレッドのIDを取得
nTargetID = GetWindowThreadProcessId(hWnd, NULL);
// スレッドのインプット狀態を結び付ける
AttachThreadInput(nTargetID, nForegroundID, TRUE); // TRUE で結び付け
// 現在の設定を sp_time に保存
SystemParametersInfo(SPI_GETFOREGROUNDLOCKTIMEOUT, 0, &sp_time, 0);
// ウィンドウの切り替え時間を 0ms にする
SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, (LPVOID)0, 0);
// ウィンドウをフォアグラウンドに持ってくる
::SetForegroundWindow(hWnd);
// 設定を元に戻す
SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, &sp_time, 0);
// スレッドのインプット狀態を切り離す
AttachThreadInput(nTargetID, nForegroundID, FALSE); // FALSE で切り離し
}
::CloseHandle(ProcessInfo.hProcess);
}
return dwExitCode;
}