Visual C++ 8.0Windows VistaWindows 2003Visual Studio 2005Windows 2000Windows XP中级开发Visual StudioWindowsC++
列出由特定用户创建的进程






4.08/5 (6投票s)
当你想列出由特定用户创建的进程,而不是由 SYSTEM、LOCAL SERVICE 等创建的进程时,你可以使用我的代码!
引言
有时,在任务管理器中,你可能只想查看由特定用户创建的进程,而不是所有进程。当你打开任务管理器时,它通常会列出所有进程以及创建它们的用户名。用户名将包括你的用户名、“SYSTEM”、“LOCAL SERVICE”等。
我创建了一个名为 GetProcessUserName
的函数,它可以检索进程的用户名信息,以便你可以列出由特定用户创建的所有进程。
背景
我有一个项目需要我收集有关进程的信息,如下所示
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...
此列表将显示由用户创建的所有进程,并且尖括号将显示用户正在关注的进程。
使用代码
以下是主函数,它可以从 PID(进程 ID)检索用户信息。我使用了所有函数的 Unicode 版本。因此,请记住在 UNICODE 模式下编译程序。
LPWSTR GetProcessUserName(DWORD dwPID)
{
/* Get The the username information form a Process.
* Parameters: dwPID , the Process's ID which you want to look for
* Return: The username of the process
*
* Author: Vincent,Wei kernelbean@gmail.com
*
*/
HANDLE hProcessToken;
HANDLE hProcess;
//Open the Remote Process
hProcess=::OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ,0,dwPID);
if(hProcess)
{
//Open The Process's Token which can be used
//to achieve more security information
if(::OpenProcessToken(hProcess,TOKEN_READ,&hProcessToken))
{
DWORD TokenInformationLength;
DWORD ReturnLength;
PTOKEN_USER tuUser=new TOKEN_USER;
LPWSTR UserName=new WCHAR[255]; // Username declared in the Heap
DWORD cchName;
LPWSTR lpReferencedDomainName=new WCHAR[255];
DWORD cchReferencedDomainName;
SID_NAME_USE peUse;
TokenInformationLength=sizeof(tuUser);
//Get the User Information from the Token
if(::GetTokenInformation(hProcessToken,TokenUser,tuUser,
TokenInformationLength,&ReturnLength))
{
::LookupAccountSid(NULL,tuUser->User.Sid,UserName,&cchName,
lpReferencedDomainName,&cchReferencedDomainName,&peUse);
}
else // The structure is not large enough
{
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;
}
第二个重要的过程是获取焦点窗口的 PID。
我们可以使用 ToolHelp 函数获取进程列表。然后,我们可以检查焦点窗口的 PID 是否等于列表中的成员。如果你不知道如何获取焦点窗口的进程 ID,请阅读以下代码
HWND hwndFocusWindow;
DWORD dwFocusPID;
hwndFocusWindow=GetForegroundWindow();
//Get the Focus Window
::GetWindowThreadProcessId(hwndFocusWindow,&dwFocusPID);
// Get the PID from that window
关注点
我首先在 MSDN 中查找一个可以实现此功能的 API,但失败了。关键是从进程获取信息。幸运的是,我发现一个进程的 TokenInformation
可以向我们展示很多关于进程的信息。你可以在 MSDN 中搜索该函数,以便实现许多有趣的想法!