我怎样才能得到使用C ++的SYSTEM进程中的活动用户名?

我已经使用了GetUserName()方法,但是它返回的用户名是SYSTEM中的SYSTEM。如何在SYSTEM进程中获得活动的用户名? 这是我的代码:

void getComputerUsername(char * username,char * domainname) { HANDLE hp , htoken; char buff[1024]; unsigned long size = 1024; TOKEN_USER *tuser; PSID sid; TCHAR * user = new TCHAR[256]; TCHAR * domain=new TCHAR[256]; SID_NAME_USE snu; hp = htoken = INVALID_HANDLE_VALUE; hp = GetCurrentProcess(); if(OpenProcessToken(hp, TOKEN_QUERY, &htoken)) { if(GetTokenInformation(htoken, TokenUser, (void*)buff, size, &size)) { tuser = (TOKEN_USER*)buff; sid = tuser->User.Sid; size = 256; if(LookupAccountSid(NULL, sid, user, &size, domain, &size, &snu)) { int iLength = WideCharToMultiByte(CP_ACP, 0, user, -1, NULL, 0, NULL, NULL); WideCharToMultiByte(CP_ACP, 0, user, -1, username, iLength, NULL, NULL); iLength = WideCharToMultiByte(CP_ACP, 0, domain, -1, NULL, 0, NULL, NULL); WideCharToMultiByte(CP_ACP, 0, domain, -1, domainname, iLength, NULL, NULL); //strcpy( user,username); } } } 

}

您需要使用EnumProcesses枚举所有正在运行的进程

然后看到这个答案从进程中获取用户名:

https://stackoverflow.com/a/2686150/203244

如果您想知道谁登录到了物理控制台,您可以调用WTSGetActiveConsoleSessionId来获取当前处于活动状态的终端服务(又名“快速用户切换”即“远程桌面”)会话标识。

然后可以使用WTSUserName调用WTSQuerySessionInformation来获取用户名。

(如果您感兴趣的用户可能通过远程桌面登录,则此方法无效。)

枚举所有进程是一种方法,但它有一些问题:

1)不能在使用记录的Windows API的相同服务进程中枚举x86和x64进程。 x86服务只能枚举x86进程,而x64服务只能枚举x64进程。 避免这种情况的一种方法是让x86服务启动一个x64辅助进程(反之亦然)来执行其余的枚举任务。

2)跨越不同Windows版本(例如Vista到Windows 10)的登录用户始终存在的唯一过程是explorer.exe,但是该过程在x64操作系统平台上是x64,在x32操作系统平台上是x32,其存在并不意味着该用户正在主动登录。

更好的方法是枚举会话,查找也连接的活动交互式会话或会话,然后获取该会话的用户名。

下面的代码做的比这更多,包括模拟这个用户,并以windows用户的身份运行一个进程,但是如果你只是对用户名感兴趣,请查找第二个调用WTSQuerySessionInformation()函数的实例。

 //Function to run a process as active user from windows service void ImpersonateActiveUserAndRun(WCHAR* path, WCHAR* args) { DWORD session_id = -1; DWORD session_count = 0; WTS_SESSION_INFOA *pSession = NULL; if (WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, &pSession, &session_count)) { //log success } else { //log error return; } for (int i = 0; i < session_count; i++) { session_id = pSession[i].SessionId; WTS_CONNECTSTATE_CLASS wts_connect_state = WTSDisconnected; WTS_CONNECTSTATE_CLASS* ptr_wts_connect_state = NULL; DWORD bytes_returned = 0; if (::WTSQuerySessionInformation( WTS_CURRENT_SERVER_HANDLE, session_id, WTSConnectState, reinterpret_cast<LPTSTR*>(&ptr_wts_connect_state), &bytes_returned)) { wts_connect_state = *ptr_wts_connect_state; ::WTSFreeMemory(ptr_wts_connect_state); if (wts_connect_state != WTSActive) continue; } else { //log error continue; } HANDLE hImpersonationToken; if (!WTSQueryUserToken(session_id, &hImpersonationToken)) { //log error continue; } //Get real token from impersonation token DWORD neededSize1 = 0; HANDLE *realToken = new HANDLE; if (GetTokenInformation(hImpersonationToken, (::TOKEN_INFORMATION_CLASS) TokenLinkedToken, realToken, sizeof(HANDLE), &neededSize1)) { CloseHandle(hImpersonationToken); hImpersonationToken = *realToken; } else { //log error continue; } HANDLE hUserToken; if (!DuplicateTokenEx(hImpersonationToken, //0, //MAXIMUM_ALLOWED, TOKEN_ASSIGN_PRIMARY | TOKEN_ALL_ACCESS | MAXIMUM_ALLOWED, NULL, SecurityImpersonation, TokenPrimary, &hUserToken)) { //log error continue; } // Get user name of this process //LPTSTR pUserName = NULL; WCHAR* pUserName; DWORD user_name_len = 0; if (WTSQuerySessionInformationW(WTS_CURRENT_SERVER_HANDLE, session_id, WTSUserName, &pUserName, &user_name_len)) { //log username contained in pUserName WCHAR string } //Free memory if (pUserName) WTSFreeMemory(pUserName); ImpersonateLoggedOnUser(hUserToken); STARTUPINFOW StartupInfo; GetStartupInfoW(&StartupInfo); StartupInfo.cb = sizeof(STARTUPINFOW); //StartupInfo.lpDesktop = "winsta0\\default"; PROCESS_INFORMATION processInfo; SECURITY_ATTRIBUTES Security1; Security1.nLength = sizeof SECURITY_ATTRIBUTES; SECURITY_ATTRIBUTES Security2; Security2.nLength = sizeof SECURITY_ATTRIBUTES; void* lpEnvironment = NULL; // Get all necessary environment variables of logged in user // to pass them to the new process BOOL resultEnv = CreateEnvironmentBlock(&lpEnvironment, hUserToken, FALSE); if (!resultEnv) { //log error continue; } WCHAR PP[1024]; //path and parameters ZeroMemory(PP, 1024 * sizeof WCHAR); wcscpy(PP, path); wcscat(PP, L" "); wcscat(PP, args); // Start the process on behalf of the current user BOOL result = CreateProcessAsUserW(hUserToken, NULL, PP, //&Security1, //&Security2, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE, //lpEnvironment, NULL, //"C:\\ProgramData\\some_dir", NULL, &StartupInfo, &processInfo); if (!result) { //log error } else { //log success } DestroyEnvironmentBlock(lpEnvironment); CloseHandle(hImpersonationToken); CloseHandle(hUserToken); CloseHandle(realToken); RevertToSelf(); } WTSFreeMemory(pSession); } 

枚举桌面并找到“默认”桌面。 从该桌面获取用户SID。 也许你必须尝试找到正确的访问权限; 我只是从一个交互过程中尝试了代码。

 BOOL CALLBACK EnumDesktopProc(_In_ LPTSTR lpszDesktop, _In_ LPARAM lParam) { // todo: check if desktop is "Default" char info[1000]; auto hd = OpenDesktop(lpszDesktop, NULL, FALSE, DESKTOP_READOBJECTS); GetUserObjectInformation(hd, UOI_USER_SID, info, 1000, NULL); return TRUE; } BOOL CALLBACK EnumWindowStationProc(_In_ LPTSTR lpszWindowStation, _In_ LPARAM lParam) { auto hs = OpenWindowStation(lpszWindowStation, FALSE, WINSTA_ENUMDESKTOPS); EnumDesktops(hs, &EnumDesktopProc, NULL); return TRUE; } int _tmain(int argc, _TCHAR* argv[]) { EnumWindowStations(&EnumWindowStationProc, NULL); return 0; }