开发中有时会遇到这样的问题,当服务程序需要使用某些功能时,由于用户的关系而受到限制,比如访问注册表的HKEY_CURRENT_USER键,使用网络等等,这时候就需要以当前登陆用户的身份去进行操作,通常会创建一个进程来完成需要的功能。如果使用CreateProcess来创建进程的话,新创建的进程和服务程序依然是相同的用户身份,还是无法达到目的,只有使用CreateProcessAsUser了。但CreateProcessAsUser的第一个参数是HANDLE hToken,该参数通常应该用LogonUser来获得,但是LogonUser又需要用户名和用户密码,这样就很不现实。那应该怎么办呢?我想到了一个方法可以绕过LogonUser直接获得hToken。因为用户已经登陆,那么肯定有Shell(就是EXPLORER.EXE)运行了,我们可以通过遍历进程来取得Shell的hToken来运行进程。下面就是示例代码: BOOL GetTokenByName(HANDLE &hToken,LPSTR lpName) { if(!lpName) { return FALSE; } HANDLE hProcessSnap = NULL; BOOL bRet = FALSE; 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(!strcmp(_strupr(pe32.szExeFile),_strupr(lpName))) { HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE,pe32.th32ProcessID); bRet = OpenProcessToken(hProcess,TOKEN_ALL_ACCESS,&hToken); CloseHandle (hProcessSnap); return (bRet); } } while (Process32Next(hProcessSnap, &pe32)); bRet = TRUE; } else bRet = FALSE; CloseHandle (hProcessSnap); return (bRet); } BOOL RunProcess(LPCSTR lpImage) { if(!lpImage) { return FALSE; } HANDLE hToken; if(!GetTokenByName(hToken,"EXPLORER.EXE")) { return FALSE; } STARTUPINFO si; PROCESS_INFORMATION pi; ZeroMemory(&si, sizeof(STARTUPINFO)); si.cb= sizeof(STARTUPINFO); si.lpDesktop = TEXT("winsta0\\default"); BOOL bResult = CreateProcessAsUser(hToken,lpImage,NULL,NULL,NULL, FALSE,NORMAL_PRIORITY_CLASS,NULL,NULL,&si,&pi); CloseHandle(hToken); if(bResult) { OutputDebugString("CreateProcessAsUser ok!\r\n"); } else { OutputDebugString("CreateProcessAsUser false!\r\n"); } return bResult; } 这样就可以以登陆用户的身份来运行程序了,呵呵。 如果哪位朋友有更好的方法,欢迎提出一起讨论。 
|