对于具有UIAccess =“true”的进程,CreateProcessAsUser失败并显示ERROR_ELEVATION_REQUIRED

我正在尝试使用以下代码从我的服务应用程序(作为local system运行)运行用户模式进程。

用户模式进程的要求是在没有提升的情况下运行,但要在其清单中使用UIAccess="true" ,以便能够在Windows 8下正确显示top-most窗口 。

所以我这样做(从我的服务)来运行我的用户模式过程:

 //NOTE: Error checking is omitted for readability //'dwSessionID' = user session ID to run user-mode process in //'pUserProcPath' = L"C:\\Program Files (x86)\\Company\\Software\\user_process.exe" HANDLE hToken = NULL; WTSQueryUserToken(dwSessionID, &hToken); HANDLE hToken2; DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, NULL, SecurityIdentification, TokenPrimary, &hToken2); LPVOID pEnvBlock = NULL; CreateEnvironmentBlock(&pEnvBlock, hToken2, FALSE); STARTUPINFO si; ZeroMemory(&si, sizeof(STARTUPINFO)); si.cb = sizeof(STARTUPINFO); si.lpDesktop = L"winsta0\\default"; PROCESS_INFORMATION pi; ZeroMemory(&pi, sizeof(pi)); //ImpersonateLoggedOnUser(hToken2); //Not necessary as suggested below PVOID OldRedir; Wow64DisableWow64FsRedirection(&OldRedir); BOOL bSuccess = CreateProcessAsUser( hToken2, // client's access token pUserProcPath, // file to execute NULL, // command line NULL, // pointer to process SECURITY_ATTRIBUTES NULL, // pointer to thread SECURITY_ATTRIBUTES FALSE, // handles are not inheritable NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE | CREATE_UNICODE_ENVIRONMENT, // creation flags pEnvBlock, // pointer to new environment block NULL, // name of current directory &si, // pointer to STARTUPINFO structure &pi // receives information about new process ); int nOSError = ::GetLastError(); Wow64RevertWow64FsRedirection(OldRedir); //RevertToSelf(); //Not necessary as suggested below CloseHandle(pi.hProcess); CloseHandle(pi.hThread); DestroyEnvironmentBlock(pEnvBlock); CloseHandle(hToken2); CloseHandle(hToken); 

如果user_process.exe的清单中的UIAccess="false" ,则运行正常。

但如果我做以下事情:

  • user_process.exe启用UIAccess="true"

在此处输入图像描述

  • 使用我的代码签名证书进行签名

  • 将其放在"C:\Program Files (x86)\Company\Software"文件夹中。

我得到的是CreateProcessAsUser失败,错误为ERROR_ELEVATION_REQUIRED

有人可以建议如何使它工作?

PS。 我尝试调整服务的权限以启用SE_DEBUG_NAMESE_TCB_NAME ,但都没有帮助。

PS2。 如果我只是双击我使用UIAccess="true"编译的user_process.exe进程,进行代码签名,并放在C:\Program Files (x86)\Company\Software文件夹中,它就会启动并运行得很好(不会提升) )。

我找到了答案。 这里也适用于遇到它的人:

DuplicateTokenEx调用之后添加:

 HANDLE hToken2; DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, NULL, SecurityIdentification, TokenPrimary, &hToken2); //ONLY if requiring UIAccess! DWORD dwUIAccess = 1; ::SetTokenInformation(hToken2, TokenUIAccess, &dwUIAccess, sizeof(dwUIAccess));