如果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 2048
void PrintfDbgStr( const char * pszformatstring , ... )
{
char szBuffer[LOG_BUFFER_SIZE]={0};
va_list arg_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