服务程序中创建带管理员权限的UI进程问题总结

来源:互联网 发布:python画聚类图 编辑:程序博客网 时间:2024/06/12 01:27

如果UI进程仅仅是一个普通的进程而不需要申请管理员权限,那问题不大,直接在服务里获取explorer.exe的token或者用WTSGetActiveConsoleSessionId和WTSQueryUserToken,然后用CreateProcessAsUser创建即可,好多参数都可以设置默认,当然前提是要等桌面创建好再获取,因为服务是在桌面创建之前就启动了的,这个要注意。然而管理员权限的进程可是不好启动的,以上方法你将会发现类似740之类的错误码(权限不够),于是网上搜了下发现用服务本身的Token,并做相应的设置就可以做到在session1启动这个带管理员权限的UI进程,当然过程花了不少时间,先是能启动了,但是后面发现访问不了当前用户的桌面等,尤其CFileDialog 一弹出就会报一个错误,最后在同事的提醒下应该是环境变量的问题,瞬间恍然大悟,CreateEnvironmentBlock创建环境变量时必须要用当前桌面进程的token来创建,于是就搞定了访问当前用户桌面路径访问不到的问题,现在还有一个当前用户注册表访问不自然的问题,必须要通过获取当前用户的SID来组合访问注册表HKEY_CURRENT_USER,好了废话少说,虽然现在创建出来的进程用户名仍然是SYSTEM,但是它的访问权限是在管理员之上的,当前用户的东西也可以访问了,在session 1下,只是注册表访问有点不问题,不过可以通过其他方式解决。如果有哪位同仁能够直接创建出具有管理员权限的UI进程,同时创建出来的进程用户名是当前用户烦请告知一声,哈哈,我研究了两天没搞定,放弃了。以下是代码:


#define LOG_BUFFER_SIZE 2048void PrintfDbgStr( const char * pszformatstring , ... ){char szBuffer[LOG_BUFFER_SIZE]={0};va_listarg_ptr ;va_start( arg_ptr, pszformatstring ) ;vsprintf(szBuffer, pszformatstring, arg_ptr);va_end( arg_ptr ) ;OutputDebugStringA(szBuffer);}/*是否已经进入桌面*/BOOL IsDesktopVisible(){BOOL  bRet = FALSE;HANDLE hProcessSnap = NULL;PROCESSENTRY32 pe32 = {0};hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);if (hProcessSnap == INVALID_HANDLE_VALUE)return (FALSE);pe32.dwSize = sizeof(PROCESSENTRY32);if (Process32First(hProcessSnap, &pe32)){do{if(!_tcscmp(_wcsupr(pe32.szExeFile),_T("EXPLORER.EXE"))){bRet =  TRUE;break;}}while (Process32Next(hProcessSnap, &pe32));}CloseHandle (hProcessSnap);return bRet;}


下面是启动进程的函数

BOOL  RunExeInSession1(TCHAR* szExeFile){BOOL  bSuccess = TRUE;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("SetTokenInformation error !error code:%d",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*/;HANDLE hToken;LPVOID pEnv = NULL;WTSQueryUserToken(dwSessionId, &hToken);if(!CreateEnvironmentBlock(&pEnv,hToken,FALSE)){PrintfDbgStr("CreateEnvironmentBlock error !error code:%d",GetLastError());CloseHandle(hToken);bSuccess = FALSE;break;}CloseHandle(hToken);DWORD dwCreationFlag = NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE | CREATE_UNICODE_ENVIRONMENT;if(!CreateProcessAsUser(hTokenDup,NULL,szExeFile,NULL,NULL,FALSE,dwCreationFlag,pEnv,NULL,&si,&pi)){PrintfDbgStr("CreateProcessAsUser error !error code:%d",GetLastError());bSuccess = FALSE;break;}if(pEnv){DestroyEnvironmentBlock(pEnv);}}else{PrintfDbgStr("DuplicateTokenEx error !error code:%d",GetLastError());bSuccess = FALSE;break;}}else{PrintfDbgStr("cannot get administror!error code:%d",GetLastError());bSuccess = FALSE;break;}}while(0);if(hTokenDup != NULL && hTokenDup != INVALID_HANDLE_VALUE)CloseHandle(hTokenDup);if(hToken != NULL && hToken != INVALID_HANDLE_VALUE)CloseHandle(hToken);return  bSuccess;}



参考文章:

  http://blog.csdn.net/woshinia/article/details/7850295

0 0
原创粉丝点击