2010-02-17 54 views
4

我正在尝试让我的一个正在运行的进程被提升为使用标准用户令牌重新启动资源管理器。模拟标准用户

我在做什么,首先我经营的主要过程作为管理员,然后我在运行的快照:

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); 

然后,一旦我得到它的标准下运行资源管理器的PID用户帐户,我呼吁:

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

然后我打电话:

ImpersonateLoggedOnUser(hPToken); 

和国际泳联lly我taskkill explorer.exe和shell再次执行它,但它的管理员权限下运行。

它仿佛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); 

任何意见或建议。

+0

请记住,Process32First/Next函数是为了向后兼容性而保留的,并不总是返回完美的结果。它们不能在64位机器上可靠地工作,并且它们通常返回的实际数量少于svchost.exes。锄头,帮助:) – 2010-02-17 16:00:52

+0

@BillyONeal:它会返回所有进程...如果你有权限SE_DEBUG – 2010-02-17 16:10:43

+0

即使使用'SeDebugPrivilege'它并不总是返回正确数量的svchosts。在Windows API初始化之前(在NT引导过程早些时候),启动任何东西都会遇到问题。“EnumProcesses()”是唯一(记录)的函数,它总是返回正确的答案。 – 2010-02-17 18:33:53

回答

3

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

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

编辑以符合您:

  • 你CreateProcessAsUser的方式,应通过:CREATE_DEFAULT_ERROR_MODE | CREATE_UNICODE_ENVIRONMENTdwCreationFlags

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

  • 你也应该调整desktop和​​的Ace

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

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

For further reading please see this post on Session, Window Station, and Desktop management

+0

我也尝试过,但它返回INVALID_PARAMETER_ERROR 我编辑了我正在使用的方法的问题。 – 2010-02-17 15:28:36

+0

什么是返回INVALID_PARAMETER_ERROR?你打电话给DuplicateTokenEx吗? – 2010-02-17 15:29:44

+0

添加了更多信息。 – 2010-02-17 15:49:01

0

我试图以安装程序作为标准用户以高级管理员权限启动时运行程序时遇到类似问题。使用CreateProcessAsUser函数尝试(并且失败后)执行此操作后,我偶然发现了一个使用ShellExecute从IShellDispatch2接口的解决方案。

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

希望这可以帮助!