我有一个带
的流程句柄HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, 0, THE_PROCESS_ID);
如何获取正在运行该进程的用户的用户名?
我使用的是非托管代码(没有.NET)。
答案 0 :(得分:20)
使用OpenProcessToken获取令牌(显然),然后GetTokenInformation使用TokenOwner
标志获取所有者的SID。然后,您可以使用LookupAccountSid获取用户名。
答案 1 :(得分:5)
如果WMI不是一个选项,那么使用下面的 GetUserFromProcess ,它将进程ID作为输入参数并返回用户名和域:
#include <comdef.h>
#define MAX_NAME 256
BOOL GetLogonFromToken (HANDLE hToken, _bstr_t& strUser, _bstr_t& strdomain)
{
DWORD dwSize = MAX_NAME;
BOOL bSuccess = FALSE;
DWORD dwLength = 0;
strUser = "";
strdomain = "";
PTOKEN_USER ptu = NULL;
//Verify the parameter passed in is not NULL.
if (NULL == hToken)
goto Cleanup;
if (!GetTokenInformation(
hToken, // handle to the access token
TokenUser, // get information about the token's groups
(LPVOID) ptu, // pointer to PTOKEN_USER buffer
0, // size of buffer
&dwLength // receives required buffer size
))
{
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
goto Cleanup;
ptu = (PTOKEN_USER)HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY, dwLength);
if (ptu == NULL)
goto Cleanup;
}
if (!GetTokenInformation(
hToken, // handle to the access token
TokenUser, // get information about the token's groups
(LPVOID) ptu, // pointer to PTOKEN_USER buffer
dwLength, // size of buffer
&dwLength // receives required buffer size
))
{
goto Cleanup;
}
SID_NAME_USE SidType;
char lpName[MAX_NAME];
char lpDomain[MAX_NAME];
if( !LookupAccountSid( NULL , ptu->User.Sid, lpName, &dwSize, lpDomain, &dwSize, &SidType ) )
{
DWORD dwResult = GetLastError();
if( dwResult == ERROR_NONE_MAPPED )
strcpy (lpName, "NONE_MAPPED" );
else
{
printf("LookupAccountSid Error %u\n", GetLastError());
}
}
else
{
printf( "Current user is %s\\%s\n",
lpDomain, lpName );
strUser = lpName;
strdomain = lpDomain;
bSuccess = TRUE;
}
Cleanup:
if (ptu != NULL)
HeapFree(GetProcessHeap(), 0, (LPVOID)ptu);
return bSuccess;
}
HRESULT GetUserFromProcess(const DWORD procId, _bstr_t& strUser, _bstr_t& strdomain)
{
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION,FALSE,procId);
if(hProcess == NULL)
return E_FAIL;
HANDLE hToken = NULL;
if( !OpenProcessToken( hProcess, TOKEN_QUERY, &hToken ) )
{
CloseHandle( hProcess );
return E_FAIL;
}
BOOL bres = GetLogonFromToken (hToken, strUser, strdomain);
CloseHandle( hToken );
CloseHandle( hProcess );
return bres?S_OK:E_FAIL;
}
答案 2 :(得分:1)
WMI可能是阻力最小的路径。您还应该能够使用OpenProcessToken获取令牌,然后使用GetTokenInformation获取所有者的SID。然后,您可以将SID转换为用户名。
答案 3 :(得分:0)
WMI应该可以告诉你这些信息。 否则你需要依赖ntdll.dll中无证件的乐趣。似乎其他人找到了不使用ntdll.dll的解决方案 - 使用它们而不是未记录的东西。