Shell执行将窗口置于前面

我正在使用此function从我的msi调用可执行文件。 但是,可执行文件的窗口隐藏在我的MSI窗口后面。 有没有办法把它带到前面。 对不起,对于nobe的问题,但我已经尝试尽量减less所有的窗口只是在调用ShellExecute之前,但仍然没有把可执行窗口的前面。 谢谢

 extern "C" UINT __stdcall InstallDrivers(MSIHANDLE hInstall) { HRESULT hr = S_OK; UINT er = ERROR_SUCCESS; HANDLE hFile = INVALID_HANDLE_VALUE; BYTE* pbData = NULL; DWORD cbData = 0; char pwzFilename[MAX_PATH], szDriverType[MAX_PATH], pwzSentinelFilename[MAX_PATH], szIsInstalled[MAX_PATH]; LPWSTR szValueBuf = NULL, szIsHaspInstalled = NULL, szIsSentinelInstalled = NULL; hr = WcaInitialize(hInstall, "InstallDrivers"); ExitOnFailure(hr, "Failed to initialize"); WcaLog(LOGMSG_STANDARD, "Initialized."); WcaLog(LOGMSG_STANDARD, "%s", szValueBuf); CreateDirectory("C:\\Temp", NULL); strcpy_s(pwzFilename, "C:\\Temp\\HASPUserSetup.exe"); hr = ExtractBinary(L"Hasp", &pbData, &cbData); ExitOnFailure(hr, "failed to extract binary data"); if ((hFile = CreateFile(pwzFilename, GENERIC_WRITE,FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL)) == INVALID_HANDLE_VALUE) { PMSIHANDLE hRecord = MsiCreateRecord(0); MsiRecordSetString(hRecord, 0, TEXT("Could not create new temporary file")); MsiProcessMessage(hInstall, INSTALLMESSAGE(INSTALLMESSAGE_ERROR + MB_OK), hRecord); return ERROR_INSTALL_USEREXIT; } DWORD cbWritten = 0; if ( !WriteFile(hFile, pbData, cbData, &cbWritten, NULL) ) { PMSIHANDLE hRecord = MsiCreateRecord(0); MsiRecordSetString(hRecord, 0, TEXT("Could not write to file")); MsiProcessMessage(hInstall, INSTALLMESSAGE(INSTALLMESSAGE_ERROR + MB_OK), hRecord); return ERROR_INSTALL_USEREXIT; } CloseHandle(hFile); strcpy_s(pwzSentinelFilename, "C:\\Temp\\sentinel_setup.exe"); hr = ExtractBinary(L"Sentinel", &pbData, &cbData); ExitOnFailure(hr, "failed to extract binary data"); if ((hFile = CreateFile(pwzSentinelFilename, GENERIC_WRITE,FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL)) == INVALID_HANDLE_VALUE) { PMSIHANDLE hRecord = MsiCreateRecord(0); MsiRecordSetString(hRecord, 0, TEXT("Could not create new temporary file")); MsiProcessMessage(hInstall, INSTALLMESSAGE(INSTALLMESSAGE_ERROR + MB_OK), hRecord); return ERROR_INSTALL_USEREXIT; } if ( !WriteFile(hFile, pbData, cbData, &cbWritten, NULL) ) { PMSIHANDLE hRecord = MsiCreateRecord(0); MsiRecordSetString(hRecord, 0, TEXT("Could not write to file")); MsiProcessMessage(hInstall, INSTALLMESSAGE(INSTALLMESSAGE_ERROR + MB_OK), hRecord); return ERROR_INSTALL_USEREXIT; } CloseHandle(hFile); hr = WcaGetProperty(L"DRIVER", &szValueBuf); ExitOnFailure(hr, "failed to get driver info"); wcstombs(szDriverType, szValueBuf, 260); if (strcmp(szDriverType, "Hasp") == 0) { hr = WcaGetProperty(L"SENTINELINSTALLED", &szIsSentinelInstalled); ExitOnFailure(hr, "failed to get driver info"); wcstombs(szIsInstalled, szValueBuf, 260); if (strcmp(szIsInstalled, "Sentinel Protection Installer 7.6.5") == 0) { ShellExecute(NULL, "open", pwzSentinelFilename, NULL, NULL, SW_SHOWNORMAL); } ShellExecute(NULL, "open", pwzFilename, NULL, NULL, SW_SHOWNORMAL); }else { hr = WcaGetProperty(L"HASPINSTALLED", &szIsHaspInstalled); ExitOnFailure(hr, "failed to get driver info"); wcstombs(szIsInstalled, szIsHaspInstalled, 260); if (strcmp(szIsInstalled, "Sentinel Runtime") == 0) { ShellExecute(NULL, "open", pwzFilename, NULL, NULL, SW_SHOWNORMAL); } ShellExecute(NULL, "open", pwzSentinelFilename, NULL, NULL, SW_SHOWNORMAL); } LExit: er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; return WcaFinalize(er); } 

更新的代码:

 extern "C" UINT __stdcall InstallDrivers(MSIHANDLE hInstall) { HRESULT hr = S_OK; UINT er = ERROR_SUCCESS; HANDLE hFile = INVALID_HANDLE_VALUE; BYTE* pbData = NULL; DWORD cbData = 0; char pwzFilename[MAX_PATH], szDriverType[MAX_PATH], pwzSentinelFilename[MAX_PATH], szIsInstalled[MAX_PATH]; LPWSTR szValueBuf = NULL, szIsHaspInstalled = NULL, szIsSentinelInstalled = NULL; SHELLEXECUTEINFO ShExecInfo; ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO); ShExecInfo.fMask = NULL; ShExecInfo.hwnd = NULL; ShExecInfo.lpVerb = NULL; ShExecInfo.lpParameters = NULL; ShExecInfo.lpDirectory = NULL; ShExecInfo.nShow = SW_SHOWNORMAL; ShExecInfo.hInstApp = NULL; hr = WcaInitialize(hInstall, "InstallDrivers"); ExitOnFailure(hr, "Failed to initialize"); WcaLog(LOGMSG_STANDARD, "Initialized."); WcaLog(LOGMSG_STANDARD, "%s", szValueBuf); CreateDirectory("C:\\Temp", NULL); strcpy_s(pwzFilename, "C:\\Temp\\HASPUserSetup.exe"); hr = ExtractBinary(L"Hasp", &pbData, &cbData); ExitOnFailure(hr, "failed to extract binary data"); if ((hFile = CreateFile(pwzFilename, GENERIC_WRITE,FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL)) == INVALID_HANDLE_VALUE) { PMSIHANDLE hRecord = MsiCreateRecord(0); MsiRecordSetString(hRecord, 0, TEXT("Could not create new temporary file")); MsiProcessMessage(hInstall, INSTALLMESSAGE(INSTALLMESSAGE_ERROR + MB_OK), hRecord); return ERROR_INSTALL_USEREXIT; } DWORD cbWritten = 0; if ( !WriteFile(hFile, pbData, cbData, &cbWritten, NULL) ) { PMSIHANDLE hRecord = MsiCreateRecord(0); MsiRecordSetString(hRecord, 0, TEXT("Could not write to file")); MsiProcessMessage(hInstall, INSTALLMESSAGE(INSTALLMESSAGE_ERROR + MB_OK), hRecord); return ERROR_INSTALL_USEREXIT; } CloseHandle(hFile); strcpy_s(pwzSentinelFilename, "C:\\Temp\\sentinel_setup.exe"); hr = ExtractBinary(L"Sentinel", &pbData, &cbData); ExitOnFailure(hr, "failed to extract binary data"); if ((hFile = CreateFile(pwzSentinelFilename, GENERIC_WRITE,FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL)) == INVALID_HANDLE_VALUE) { PMSIHANDLE hRecord = MsiCreateRecord(0); MsiRecordSetString(hRecord, 0, TEXT("Could not create new temporary file")); MsiProcessMessage(hInstall, INSTALLMESSAGE(INSTALLMESSAGE_ERROR + MB_OK), hRecord); return ERROR_INSTALL_USEREXIT; } if ( !WriteFile(hFile, pbData, cbData, &cbWritten, NULL) ) { PMSIHANDLE hRecord = MsiCreateRecord(0); MsiRecordSetString(hRecord, 0, TEXT("Could not write to file")); MsiProcessMessage(hInstall, INSTALLMESSAGE(INSTALLMESSAGE_ERROR + MB_OK), hRecord); return ERROR_INSTALL_USEREXIT; } CloseHandle(hFile); hr = WcaGetProperty(L"DRIVER", &szValueBuf); ExitOnFailure(hr, "failed to get driver info"); wcstombs(szDriverType, szValueBuf, 260); if (strcmp(szDriverType, "Hasp") == 0) { hr = WcaGetProperty(L"SENTINELINSTALLED", &szIsSentinelInstalled); ExitOnFailure(hr, "failed to get driver info"); wcstombs(szIsInstalled, szValueBuf, 260); if (strcmp(szIsInstalled, "Sentinel Protection Installer 7.6.5") == 0) { AllowSetForegroundWindow(ASFW_ANY); ShExecInfo.lpFile = pwzSentinelFilename; ShellExecuteEx(&ShExecInfo); /*ShellExecute(NULL, "open", pwzSentinelFilename, NULL, NULL, SW_SHOWNORMAL);*/ } AllowSetForegroundWindow(ASFW_ANY); ShExecInfo.lpFile = pwzFilename; ShellExecuteEx(&ShExecInfo); /*ShellExecute(NULL, "open", pwzFilename, NULL, NULL, SW_SHOWNORMAL);*/ }else { hr = WcaGetProperty(L"HASPINSTALLED", &szIsHaspInstalled); ExitOnFailure(hr, "failed to get driver info"); wcstombs(szIsInstalled, szIsHaspInstalled, 260); if (strcmp(szIsInstalled, "Sentinel Runtime") == 0) { AllowSetForegroundWindow(ASFW_ANY); /*ShellExecute(NULL, "open", pwzFilename, NULL, NULL, SW_SHOWNORMAL);*/ ShExecInfo.lpFile = pwzFilename; ShellExecuteEx(&ShExecInfo); } AllowSetForegroundWindow(ASFW_ANY); ShExecInfo.lpFile = pwzSentinelFilename; ShellExecuteEx(&ShExecInfo); /* ShellExecute(NULL, "open", pwzSentinelFilename, NULL, NULL, SW_SHOWNORMAL);*/ } LExit: er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; return WcaFinalize(er); } 

Solutions Collecting From Web of "Shell执行将窗口置于前面"

Windows不允许进程抢夺前台窗口,除非用户启动它们。 这是为了避免说服用户将他们的银行信息输入错误的窗口。 但是,当前的前台进程可以将权限传递给另一个进程来执行此操作。 有关详细信息,请参阅AllowSetForegroundWindow 。 要做到这一点,你必须提供进程的进程id将成为前景和ShellExecute不提供。 但是,如果切换到使用ShellExecuteEx ,则可以从SHELLEXECUTEINFO结构中的hProcess成员获取。

然后你可以在你的新进程中调用SetForegroundWindow ,它将被允许。 否则,它只是开始在任务栏上闪烁。

编辑

如果您的初始应用程序是前台应用程序,并且您从中启动了一个子进程,那么该子进程应该自动成为前台,如这些功能的文档中所述。

以下是我们如何选择启用和设置另一个应用程序成为前景窗口的示例。 在这种情况下,它只是创建一个文本文件,并用open动词调用ShellExecuteEx。 我们必须等待子进程开始并准备好窗口,然后我们可以从进程ID中找到窗口,并给它权限并将其窗口设置为前台。 在这种情况下,启动的记事本(或者任何对.txt文件的“打开”动词)无论如何都将是前景。 如果您在通常放入子进程标识的进程的进程标识中分别运行记事本进程和子进程,那么我们可以使另一个进程成为前台进程 – 不是我们进程树的一部分。 这可以使用Visual C ++与cl -nologo -W3 -O2 -MD fg_test.cpp进行cl -nologo -W3 -O2 -MD fg_test.cpp以生成fg_test.exe。

 #define STRICT #define WIN32_LEAN_AND_MEAN #include <windows.h> #include <stdio.h> #include <tchar.h> #include <shellapi.h> #pragma comment(lib, "shell32") #pragma comment(lib, "user32") static void PrintError(LPCTSTR szPrefix, DWORD dwError); static BOOL CALLBACK OnGetWindowByProcess(HWND hwnd, LPARAM lParam); typedef struct { DWORD pid; HWND hwnd; } WINDOWPROCESSINFO; int _tmain(int argc, TCHAR *argv[]) { SHELLEXECUTEINFO sxi = {0}; sxi.cbSize = sizeof(sxi); sxi.nShow = SW_SHOWNORMAL; FILE *fp = NULL; _tfopen_s(&fp, _T("junk.txt"), _T("wt")); _fputts(_T("Example text file\n"), fp); fclose(fp); sxi.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_NOASYNC | SEE_MASK_WAITFORINPUTIDLE; sxi.lpVerb = _T("open"); sxi.lpFile = _T("junk.txt"); if (!ShellExecuteEx(&sxi)) PrintError(_T("ShellExecuteEx"), GetLastError()); else { WINDOWPROCESSINFO info; info.pid = GetProcessId(sxi.hProcess); // SPECIFY PID info.hwnd = 0; AllowSetForegroundWindow(info.pid); EnumWindows(OnGetWindowByProcess, (LPARAM)&info); if (info.hwnd != 0) { SetForegroundWindow(info.hwnd); SetActiveWindow(info.hwnd); } CloseHandle(sxi.hProcess); } return 0; } static BOOL CALLBACK OnGetWindowByProcess(HWND hwnd, LPARAM lParam) { WINDOWPROCESSINFO *infoPtr = (WINDOWPROCESSINFO *)lParam; DWORD check = 0; BOOL br = TRUE; GetWindowThreadProcessId(hwnd, &check); _tprintf(_T("%x %x %x\n"), hwnd, check, infoPtr->pid); if (check == infoPtr->pid) { _tprintf(_T("found window %x for process id %x\n"), hwnd, check); infoPtr->hwnd = hwnd; br = FALSE; } return br; } static void PrintError(LPCTSTR szPrefix, DWORD dwError) { LPTSTR lpsz = NULL; DWORD cch = 0; cch = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dwError, LANG_NEUTRAL, (LPTSTR)&lpsz, 0, NULL); if (cch < 1) { cch = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY, _T("Code 0x%1!08x!"), 0, LANG_NEUTRAL, (LPTSTR)&lpsz, 0, (va_list*)&dwError); } _ftprintf(stderr, _T("%s: %s"), szPrefix, lpsz); LocalFree((HLOCAL)lpsz); }