do { // if (!OpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hThisToken )) // { // PrintfDbgStr(TEXT("OpenProcessToken error !error code:%d\n"),GetLastError()); // bSuccess = FALSE; // break; // } // if(!SetPrivilege(hThisToken,SE_TCB_NAME,TRUE)) // { // PrintfDbgStr(TEXT("SetPrivilege error !error code:%d\n"),GetLastError()); // bSuccess = FALSE; // break; // } DWORD dwSessionId = WTSGetActiveConsoleSessionId(); if(!WTSQueryUserToken(dwSessionId,&hToken)) { PrintfDbgStr(TEXT("WTSQueryUserToken error !error code:%d\n"),GetLastError()); bSuccess = FALSE; break; } STARTUPINFO si; PROCESS_INFORMATION pi; ZeroMemory(&si,sizeof(STARTUPINFO)); ZeroMemory(&pi,sizeof(PROCESS_INFORMATION)); si.cb = sizeof(STARTUPINFO); si.lpDesktop = _T("WinSta0\\Default"); si.wShowWindow = TRUE; si.dwFlags = STARTF_USESHOWWINDOW; LPVOID pEnv = NULL; DWORD dwCreationFlag = NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE; if(!CreateProcessAsUser(hToken,NULL,pBuf,NULL,NULL,FALSE,dwCreationFlag,pEnv,NULL,&si,&pi)) { PrintfDbgStr(TEXT("CreateProcessAsUser error !error code:%d\n"),GetLastError()); bSuccess = FALSE; break; } }while(0);
这种方法创建的进程不是管理员权限的,因为是调用了用户的令牌创建的进程。不过,确实能顺利弹出UI。
HANDLE hToken = NULL; HANDLE hTokenDup = NULL; do { if(OpenProcessToken(GetCurrentProcess(),TOKEN_ALL_ACCESS,&hToken)) { if(DuplicateTokenEx(hToken, TOKEN_ALL_ACCESS,NULL, SecurityIdentification, TokenPrimary, &hTokenDup)) { DWORD dwSessionId = WTSGetActiveConsoleSessionId(); if(!SetTokenInformation(hTokenDup,TokenSessionId,&dwSessionId,sizeof(DWORD))) { PrintfDbgStr(TEXT("SetTokenInformation error !error code:%d\n"),GetLastError()); bSuccess = FALSE; break; } STARTUPINFO si; PROCESS_INFORMATION pi; ZeroMemory(&si,sizeof(STARTUPINFO)); ZeroMemory(&pi,sizeof(PROCESS_INFORMATION)); si.cb = sizeof(STARTUPINFO); si.lpDesktop = _T("WinSta0\\Default"); si.wShowWindow = SW_SHOW; si.dwFlags = STARTF_USESHOWWINDOW /*|STARTF_USESTDHANDLES*/; LPVOID pEnv = NULL; DWORD dwCreationFlag = NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE | CREATE_UNICODE_ENVIRONMENT; if(!CreateEnvironmentBlock(&pEnv,hTokenDup,FALSE)) { PrintfDbgStr(TEXT("CreateEnvironmentBlock error !error code:%d\n"),GetLastError()); bSuccess = FALSE; break; } if(!CreateProcessAsUser(hTokenDup,NULL,pBuf,NULL,NULL,FALSE,dwCreationFlag,pEnv,NULL,&si,&pi)) { PrintfDbgStr(TEXT("CreateProcessAsUser error !error code:%d\n"),GetLastError()); bSuccess = FALSE; break; } if(pEnv) { DestroyEnvironmentBlock(pEnv); } } else { PrintfDbgStr(TEXT("DuplicateTokenEx error !error code:%d\n"),GetLastError()); bSuccess = FALSE; break; } } else { PrintfDbgStr(TEXT("cannot get administror!error code:%d\n"),GetLastError()); bSuccess = FALSE; break; } }while(0); if(hTokenDup != NULL && hTokenDup != INVALID_HANDLE_VALUE) CloseHandle(hTokenDup); if(hToken != NULL && hToken != INVALID_HANDLE_VALUE) CloseHandle(hToken);这里就能用管理员权限打开一个进程并,弹出UI了,注意dwCreationFlag和si的参数设定,我是经过多次试验得出的,错了的话,可能就弹不出来了哦。这种方法是打开用户的令牌但是把服务的所有权限都给这个令牌,所以用户令牌就有足够的权限用管理员打开进程了。