Introduction
Sometimes, in the Task Manager, you may be interested only in viewing the processes which are created by a specific user instead of all the processes. When you open the Task Manager, it will normally list all the processes and the users who created them. The user names would include your user name, "SYSTEM", "LOCAL SERVICE" etc.
I created a function called GetProcessUserName
which can retrieve the user name information of a process so that you can list all the processes created by a specific user.
Background
I have a project which needs me to gather information about processes, like below:
8:07:05 am, April 06, 2007 : OUTLOOK.exe, <Firefox.exe>, cmd.exe, WINWORD.exe...
8:07:10 am, April 06, 2007 : OUTLOOK.exe, Firefox.exe, <cmd.exe>, WINWORD.exe...
8:07:15 am, April 06, 2007 : OUTLOOK.exe, Firefox.exe, <cmd.exe>, WINWORD.exe...
This list would show all the processes created by a user and the angle brackets would show the process which the user is focusing on.
Use the code
Followed is the main function which can retrieve the user information from a PID (Process ID). I used the Unicode version of all the functions. Therefore, remember to compile the program in UNICODE mode.
LPWSTR GetProcessUserName(DWORD dwPID)
{
HANDLE hProcessToken;
HANDLE hProcess;
hProcess=::OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ,0,dwPID);
if(hProcess)
{
if(::OpenProcessToken(hProcess,TOKEN_READ,&hProcessToken))
{
DWORD TokenInformationLength;
DWORD ReturnLength;
PTOKEN_USER tuUser=new TOKEN_USER;
LPWSTR UserName=new WCHAR[255];
DWORD cchName;
LPWSTR lpReferencedDomainName=new WCHAR[255];
DWORD cchReferencedDomainName;
SID_NAME_USE peUse;
TokenInformationLength=sizeof(tuUser);
if(::GetTokenInformation(hProcessToken,TokenUser,tuUser,
TokenInformationLength,&ReturnLength))
{
::LookupAccountSid(NULL,tuUser->User.Sid,UserName,&cchName,
lpReferencedDomainName,&cchReferencedDomainName,&peUse);
}
else
{
delete tuUser;
tuUser=(PTOKEN_USER)(new BYTE[ReturnLength]);
TokenInformationLength=ReturnLength;
if(::GetTokenInformation(hProcessToken,TokenUser,tuUser,
TokenInformationLength,&ReturnLength))
{
::LookupAccountSid(NULL,tuUser->User.Sid,UserName,&cchName,
lpReferencedDomainName,&cchReferencedDomainName,&peUse);
}
delete tuUser;
}
delete lpReferencedDomainName;
return UserName;
}
}
return NULL;
}
The second important procedure is to get the PID of the focused window.
We can use ToolHelp functions to get the process list. Then, we can check if the focused window's PID equals to the members in the list. If you don't know how to get the focused window's process ID, please read the following code:
HWND hwndFocusWindow;
DWORD dwFocusPID;
hwndFocusWindow=GetForegroundWindow();
::GetWindowThreadProcessId(hwndFocusWindow,&dwFocusPID);
Points of interest
I first looked in MSDN for an API which could realize this function, but failed. The key point is to get the information from the process. Fortunately, I found that the TokenInformation
of a process can show us a lot about the process. You can search the function in MSDN so that many interesting ideas can be realized!