int ShellExecAsUser(const TCHAR *const pcOperation, const TCHAR *const pcFileName, const TCHAR *const pcParameters, const HWND &parentHwnd, const bool &threaded) { //Make sure the destination file exists if(!FILE_EXISTS(pcFileName)) { return SHELL_EXEC_AS_USER_NOT_FOUND; } int iSuccess = SHELL_EXEC_AS_USER_FAILED; OSVERSIONINFO osVersion; memset(&osVersion, 0, sizeof(OSVERSIONINFO)); osVersion.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); //Use IShellDispatch2 on supported platforms if(GetVersionEx(&osVersion)) { if((osVersion.dwPlatformId == VER_PLATFORM_WIN32_NT) && (osVersion.dwMajorVersion >= 6)) { shell_exec_as_user_param_t params = { parentHwnd, pcOperation, pcFileName, pcParameters }; iSuccess = MyShellDispatch(ShellExecAsUser_HandlerProc, ¶ms, threaded); } else { iSuccess = SHELL_EXEC_AS_USER_UNSUPPORTED; } } //Fallback mode if((iSuccess == SHELL_EXEC_AS_USER_FAILED) || (iSuccess == SHELL_EXEC_AS_USER_UNSUPPORTED)) { HINSTANCE hInst = ShellExecute(parentHwnd, pcOperation, pcFileName, pcParameters, NULL, SW_SHOWNORMAL); if(((int)hInst) > 32) { iSuccess = SHELL_EXEC_AS_USER_FALLBACK; } } return iSuccess; }
static unsigned __stdcall ShellTest_ThreadHelperProc(void* pArguments) { HRESULT hr = CoInitialize(NULL); if((hr == S_OK) || (hr == S_FALSE)) { if(threadParam_t *params = (threadParam_t*) pArguments) { params->returnValue = MyShellDispatch(params->handler, params->data, false); } DispatchPendingMessages(1000); //Required to avoid potential deadlock or crash on CoUninitialize() !!! CoUninitialize(); } else { if(threadParam_t *params = (threadParam_t*) pArguments) { params->returnValue = SHELL_DISPATCH_FAILED; } } return EXIT_SUCCESS; }