使用shellexecuteex和waitforsingleob

使用shellexecuteex和waitforsingleob

本文介绍了使用shellexecuteex和waitforsingleobject父窗口返回时会失去焦点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用下面的代码运行外部exe文件,当此应用程序终止时,父窗口失去焦点。我想禁用父窗口以避免任何绘制问题,并在WaitForSingleObject终止时重新激活。



有什么解决方案吗?我做错了什么?



Using the code below to run an external exe file, when this app terminates, the parent window loses its focus. I want to disable the parent window to avoid any paint problems and re-activate when the WaitForSingleObject is terminated.

Is there any solution for that ? What am i doing wrong ?

void CMainFrame::OnBtnUpdateApp() {

    SHELLEXECUTEINFO    lpExecInfo;
    DWORD               dwExitCode;
    HINSTANCE           hProcess = 0;
    BOOL                bResult;



    ZeroMemory(&lpExecInfo,sizeof(lpExecInfo));
    lpExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
    lpExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
    lpExecInfo.hwnd = GetSafeHwnd();
    lpExecInfo.lpVerb = _T("open");
    lpExecInfo.lpFile = _T("Update.exe");
    lpExecInfo.lpParameters = _T("");
    lpExecInfo.lpDirectory = _T("");
    lpExecInfo.nShow = SW_SHOWNORMAL;
    lpExecInfo.hInstApp = NULL;
    lpExecInfo.hProcess = hProcess;

    bResult = ShellExecuteEx(&lpExecInfo);

    if(bResult) {

         EnableWindow(FALSE);
         WaitForSingleObject( lpExecInfo.hProcess, INFINITE );

         if (!GetExitCodeProcess(lpExecInfo.hProcess, &dwExitCode)) {
                //failed to terminate normally   
         }

         CloseHandle(lpExecInfo.hProcess);
         EnableWindow(TRUE);

    } else {

        //failed to execute the exe file
    }


}





我尝试了什么:



我试过,BringWindowToTop(),SetActiveWindow(),SetFocus ()



What I have tried:

I tried, BringWindowToTop(), SetActiveWindow(), SetFocus()

推荐答案

SECURITY_ATTRIBUTES sa;
	sa.nLength = sizeof(sa);
	sa.lpSecurityDescriptor = NULL;
	sa.bInheritHandle = TRUE;

	PROCESS_INFORMATION pi;
	STARTUPINFO si;
	BOOL ret = FALSE;
	DWORD flags = CREATE_NO_WINDOW;

	ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
	ZeroMemory(&si, sizeof(STARTUPINFO));
	si.cb = sizeof(STARTUPINFO);
	si.dwFlags |= STARTF_USESTDHANDLES;
	si.hStdInput = NULL;
	si.hStdError = h;
	si.hStdOutput = h;

	CString cmd = _T("cmd /c ") + _T("Update.exe");
	BOOL inherits = FALSE;

	ret = CreateProcess(NULL,
		cmd.GetBuffer(),
		NULL,
		NULL,
		inherits,
		flags,
		NULL,
		NULL,
		&si,
		&pi);

	DWORD dwExitCode = 0;
	if (ret)
	{
		CloseHandle(pi.hProcess);
		CloseHandle(pi.hThread);
		return TRUE;
	}


void CMainFrame::OnBtnUpdateApp() {


	PROCESS_INFORMATION processInfo;
	DWORD				dwExitCode;
	HANDLE				hProcess = 0;
	BOOL				bResult;
	CString				strCmd;
	CUtils				util;
	CString				strPathAndApp;


	strCmd = _T("");



	MONITORINFO mi = { sizeof(mi) };
	::GetWindowPlacement(GetSafeHwnd(), &m_g_wpPrevFrameSize) && ::GetMonitorInfo(MonitorFromWindow(GetSafeHwnd(),MONITOR_DEFAULTTOPRIMARY), &mi);

	strPathAndApp = _T("\"") + util.GetApplicationPath() + _T("\\")+_T(UPDATE_EXE_FILE) + _T("\"") + strCmd;
	//******************************************************************************************
	//Pass the File + Parameters to cmdLine because otherwise it wont run under Winsows XP
	//******************************************************************************************
	bResult = StartupApplicationWithProcess (NULL, strPathAndApp.GetBuffer(),  &processInfo); //CreateProcess goes here
	strPathAndApp.ReleaseBuffer();


	if(bResult) { //(UINT)result > HINSTANCE_ERROR)


		AMLOGINFO(_T("LiveUpdate dialog box opened successfully."));

		DWORD dwRet;

		do {
			dwRet = ::MsgWaitForMultipleObjects(1, &processInfo.hProcess, FALSE, INFINITE, QS_ALLINPUT);
			if (dwRet != WAIT_OBJECT_0) {

				PeekMessageLoop();
			}
		} while ((dwRet != WAIT_OBJECT_0) && (dwRet != WAIT_FAILED));




		if (!GetExitCodeProcess(processInfo.hProcess, &dwExitCode)) {
			   	AMLOGINFO(_T("LiveUpdate is not terminated normally."));
		}

		CloseHandle( processInfo.hProcess );
        CloseHandle( processInfo.hThread );




		AMLOGINFO(_T("LiveUpdate is terminated without any errors."));



	} else {

		CString ErrorDescr = FormatErrorMessage(GetLastError());

		AfxMessageBox("Error !");


	}

    SetForegroundWindow();
    SetActiveWindow();
	BringWindowToTop();
	UpdateWindow();


这篇关于使用shellexecuteex和waitforsingleobject父窗口返回时会失去焦点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-03 14:53