Chinaunix首页 | 论坛 | 博客
  • 博客访问: 14269739
  • 博文数量: 7460
  • 博客积分: 10434
  • 博客等级: 上将
  • 技术积分: 78178
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-02 22:54
文章分类

全部博文(7460)

文章存档

2011年(1)

2009年(669)

2008年(6790)

分类: C/C++

2008-05-27 20:45:50

1.枚举所有的进程

方法很多,这里用EnumProcesses这个方法

DWORD aProcesses[1024], cbNeeded, cProcesses;
 unsigned int i;

if ( !EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded ) )
        return;


 cProcesses = cbNeeded / sizeof(DWORD);


 for ( i = 0; i < cProcesses; i++ )
        PrintProcessNameAndID( aProcesses[i]);

aProcesses数组里包含了所有进程ID,使用EnumProcesses需要安装SDK,并且需要
Header: Declared in Psapi.h.
  Library: Use Psapi.lib.

这个函数在msdn上有详细的说明

 

2.根据进程ID获取进程文件名
有了进程ID  DWORD  dwProcessID

TCHAR szProcessName[MAX_PATH] = _T("");
TCHAR szProcessPath[MAX_PATH] = _T("");

HANDLE hProcess = NULL;
hProcess = OpenProcess( PROCESS_QUERY_INFORMATION |
                                   PROCESS_VM_READ,
                                   FALSE, dwProcessID);

if(hProcess != NULL)
{
 HMODULE hMod;
        DWORD cbNeeded;
  

        if ( EnumProcessModules( hProcess, &hMod, sizeof(hMod),
             &cbNeeded) )
        {
   
  DWORD  dwRetVal = 0;
  DWORD  dwRetValEx = 0;
              dwRetVal = GetModuleBaseName( hProcess, hMod, szProcessName,
                               sizeof(szProcessName) );

  dwRetValEx = GetModuleFileNameEx( hProcess, hMod, szProcessPath,
            sizeof(szProcessPath));

  if(dwRetVal > 0 && dwRetValEx > 0)
  {
   bRetVal = TRUE;
  }
  else
  {
   bRetVal = FALSE;
  }
  
        }

}

GetModuleBaseName只是获得文件名如QQ.exe,
GetModuleFileNameEx是获得文件名,包括路径,如E:\tool\Tencent\qq\QQ.exe

 

3.根据进程的句柄来判断,该进程是否是系统进程

BOOL  IsSysProcess(HANDLE hProcess)
{
 BOOL  bRetVal = FALSE;

 //1.OpenProcessToken
 HANDLE hToken = NULL;

 if(hProcess != NULL)
 {
  bRetVal = ::OpenProcessToken(hProcess,TOKEN_QUERY,&hToken);
 }

 //2.GetTokenInformation
 PTOKEN_USER  pToken_User = NULL;
        DWORD        dwTokenUser = 0L;

 if(hToken != NULL)
 {
  ::GetTokenInformation(hToken, TokenUser, NULL,0L, &dwTokenUser);
 }

 if(dwTokenUser>0)
 {
  pToken_User = (PTOKEN_USER)::GlobalAlloc( GPTR, dwTokenUser );
 }

        if(pToken_User != NULL)
 {
  bRetVal = ::GetTokenInformation(hToken, TokenUser, pToken_User, dwTokenUser, &dwTokenUser);
 }

 //3.LookupAccountSid...
    TCHAR szAccName[MAX_PATH] = {0};
 TCHAR szDomainName[MAX_PATH] = {0};

 if(bRetVal != FALSE && pToken_User != NULL)
 {
  SID_NAME_USE eUse  = SidTypeUnknown;

  DWORD dwAccName    = 0L;  
  DWORD dwDomainName = 0L;
  
  PSID  pSid = pToken_User->User.Sid;
  
  bRetVal = ::LookupAccountSid(NULL, pSid, NULL, &dwAccName,NULL,&dwDomainName,&eUse );
  
  if(dwAccName>0 && dwAccName< MAX_PATH && dwDomainName>0 && dwDomainName <= MAX_PATH)
  {
      bRetVal = ::LookupAccountSid(NULL,pSid,szAccName,&dwAccName,szDomainName,&dwDomainName,&eUse );
  }
 }

 //4.Compant
        if(bRetVal != FALSE)
 {
  if(::_tcsnicmp(szAccName,TEXT("SYSTEM"),6) != 0L)
  {
   bRetVal = FALSE;
  }
 }

 //4.Free pToken_User
        if (pToken_User != NULL)
 {
  ::GlobalFree( pToken_User );
 }

 //5.CloseHandle
 if(hToken != NULL)
 {
  ::CloseHandle(hToken);
 }

 return bRetVal ;
}

返回TRUE,那么就说明是系统进程
如果返回FALSE,说明不是系统进程,是用户的

这些函数在msdn上都有说明的,我记得这些例子也是从上面获得的,呵呵

 

4.根据可执行文件名,获得这个文件的图标

SHFILEINFO            shFileInfo   = {0};

::SHGetFileInfo(szProcessPath,0,&shFileInfo,sizeof(SHFILEINFO),SHGFI_ICON);

shFileInfo.hIcon保存的,就是这个可执行文件的图标句柄,可以直接拿来用

比如调用CImageList的成员函数int CImageList::Add( HICON hIcon );
插入CImageList


如果想把可执行文件的图标插入listctrl,做了一个类似于任务管理器一样的进程管理器
那么有个更简单的办法

HIMAGELIST hImageList = NULL;

bRetVal = Shell_GetImageLists(&hImageList,NULL);

获取系统的imagelist

CImageList  m_image

 if(hImageList != NULL)
 m_image.Attach(hImageList);


然后m_listctrl.SetImageList(&m_image,LVSIL_SMALL);

SHFILEINFO            shFileInfo   = {0};

::SHGetFileInfo(szProcessPath,0,&shFileInfo,sizeof(SHFILEINFO),SHGFI_SYSICONINDEX);

这样,根据shFileInfo.iIcon
可以获得这个图标在imagelist的序号,然后直接调用

CListCtrl::InsertItem

int InsertItem(
int nItem,
LPCTSTR lpszItem,
int nImage );

把带图标的行插入listctrl中,这是个很简单的方法了

关于一般的把图标插入listctrl方法,可以参考博客中的另一文章“VC中使用ListCtrl经验总结(1)”


5、结束进程

可以参考博客中的另一文章“vc中枚举所有的任务,任务管理器的一些资料的整理”


好了,整理了那么多,累了,就这么多吧,以后再补充吧~~ ^_^ 

阅读(272) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~