模拟标准用户

我正在试图使我的一个正在运行的进程被提升到使用标准用户令牌重新启动资源pipe理器。

我正在做的是首先我以pipe理员身份运行主stream程,然后拍摄运行的快照:

if (Process32First(hSnapshot,&pe32)) { do { if (!wcsicmp(pe32.szExeFile, L"explorer.exe")) { DWORD dwExplorerSessId = 0; if (ProcessIdToSessionId(pe32.th32ProcessID, &dwExplorerSessId) && dwExplorerSessId == dwSessionId) { dwExplorerLogonPid = pe32.th32ProcessID; break; } } } while (Process32Next(hSnapshot, &pe32)); } CloseHandle(hSnapshot); 

那么一旦我得到了在标准用户帐户下运行的资源pipe理器的PID,我打电话给:

 OpenProcessToken(hProcess,TOKEN_DUPLICATE | TOKEN_QUERY | TOKEN_IMPERSONATE ,&hPToken)) 

然后我打电话给:

 ImpersonateLoggedOnUser(hPToken); 

最后我taskkill explorer.exe和shell再次执行它,但它的pipe理员权限下运行。

它仿佛impersonateLoggedonUser不起作用。 虽然它返回true,GetLastError()返回0;

我也尝试使用CreateProcessAsUser(),但总是给出一个ERROR_FILE_NOT_FOUND:

  STARTUPINFO si; GetStartupInfo(&si); PROCESS_INFORMATION pi; ZeroMemory(&pi, sizeof(PROCESS_INFORMATION)); TCHAR tchcmd[MAX_PATH]; _tcscpy(tchcmd, _T("explorer.exe")); PVOID penv; CreateEnvironmentBlock(&penv, hToken, FALSE); HANDLE hNewToken; DuplicateTokenEx(hToken, TOKEN_ALL_ACCESS, NULL, SecurityIdentification, TokenImpersonation, &hNewToken); CreateProcessAsUser(, NULL, tchcmd, 0, 0, 0, CREATE_DEFAULT_ERROR_MODE, penv, 0, &si, &pi ); 

任何想法或build议。

在使用它之前是否在令牌上调用DuplicateTokenEx ? 你应该。

而不是ImpersonateLoggedOnUser ,你可以更容易地调用CreateProcessAsUser 。

编辑以匹配你的:

  • 你的CreateProcessAsUser的方式应该是传递: CREATE_DEFAULT_ERROR_MODE | CREATE_UNICODE_ENVIRONMENT CREATE_DEFAULT_ERROR_MODE | CREATE_UNICODE_ENVIRONMENTdwCreationFlags

  • 你也应该错误检查你的CreateEnvironmentBlock

  • 你也应该调整desktopwindow station的王牌 。

  • 而不是直接在CreateProcessByUser中指定路径,您应该先使用ExpandEnvironmentStringsForUser扩展字符串中的任何环境变量。 这将例如将: %windir%\explorer.exe转换为C:\windows\explorer.exe

 wchar_t szNewCommandLine[MAX_PATH]; if(!::ExpandEnvironmentStringsForUser(hNewToken, tchcmd, szNewCommandLine, MAX_PATH - 1)) { DWORD dwExpandEnvLastError = GetLastError(); //error handling } 

有关进一步阅读,请参阅会话,Window Station和桌面管理上的这篇文章 。

当试图以提升的管理员权限启动的安装程序作为标准用户运行程序时,遇到了类似的问题。 尝试(和失败悲惨)使用CreateProcessAsUser函数来做到这一点,我偶然发现一个解决方案,从IShellDispatch2接口使用ShellExecute。

它可以用来当前交互式用户启动一个进程。 完整的实现请看这里: https : //code.google.com/p/mulder/source/browse/trunk/Utils/nsis_stdutils/Contrib/StdUtils/ShellExecAsUser.cpp?r=327

希望这可以帮助!