65.9K
CodeProject 正在变化。 阅读更多。
Home

列出由特定用户创建的进程

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.08/5 (6投票s)

2007年4月16日

CPOL

1分钟阅读

viewsIcon

35507

downloadIcon

306

当你想列出由特定用户创建的进程,而不是由 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 中搜索该函数,以便实现许多有趣的想法!

© . All rights reserved.