MFC 中的高级任务管理器






4.57/5 (16投票s)
本文演示了如何在 MFC 中创建一个任务管理器,该任务管理器将列出系统中所有正在运行的进程及其进程详细信息和版本信息。
引言
本文演示了如何使用 MFC 创建一个任务管理器。这个任务管理器被称为“高级任务管理器”,它将显示比标准任务管理器更多的信息,例如正在运行的执行文件的属性和进程详细信息。
背景
可用的标准任务管理器将显示有关正在运行的进程的详细信息,但在某些情况下,我们需要知道进程正在运行的执行文件的路径,而这在标准任务管理器中是不可用的。此应用程序将显示进程的详细信息,例如它正在执行的路径、产品名称、产品版本等。
实现
这里的设计很简单。有三个类执行操作。CProcessEnumerator
负责加载所有 NT 进程。所有这些进程都加载到列表控件中。CProcessViewer
可以提供有关指定进程的信息,而 CVersionViewer
可以提供有关正在运行的执行文件的信息。
以下代码枚举 WIN NT/2000 系统上所有正在运行的进程
// BOOL CProcessEnumerator::EnumWinNTProcs( PROCENUMPROC lpProc, LPARAM lParam ) { LPDWORD lpdwPIDs ; DWORD dwSize, dwSize2, dwIndex ; HMODULE hMod ; HANDLE hProcess ; char szFileName[ MAX_PATH ] ; ENUMINFOSTRUCT sInfo ; dwSize2 = 256 * sizeof( DWORD ) ; lpdwPIDs = NULL ; do { if( lpdwPIDs ) { HeapFree( GetProcessHeap(), 0, lpdwPIDs ) ; dwSize2 *= 2 ; } lpdwPIDs = (LPDWORD)HeapAlloc( GetProcessHeap(), 0, dwSize2 ); if( lpdwPIDs == NULL ) { return FALSE ; } if( !m_lpfEnumProcesses( lpdwPIDs, dwSize2, &dwSize ) ) { HeapFree( GetProcessHeap(), 0, lpdwPIDs ) ; return FALSE ; } }while( dwSize == dwSize2 ) ; dwSize /= sizeof( DWORD ) ; // Loop through each ProcID. for( dwIndex = 0 ; dwIndex < dwSize ; dwIndex++ ) { szFileName[0] = 0 ; hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, lpdwPIDs[ dwIndex ] ) ; if( hProcess != NULL ) { if( m_lpfEnumProcessModules( hProcess, &hMod, sizeof( hMod ), &dwSize2 ) ) { // Get Full pathname: if( !m_lpfGetModuleFileNameEx( hProcess, hMod, szFileName, sizeof( szFileName ) ) ) { szFileName[0] = 0 ; } } CloseHandle( hProcess ) ; } DWORD lastErr = GetLastError(); if(!lpProc( lpdwPIDs[dwIndex], 0, szFileName, lParam)) break ; if( _stricmp( szFileName+(strlen(szFileName)-9), "NTVDM.EXE")==0) { sInfo.dwPID = lpdwPIDs[dwIndex] ; sInfo.lpProc = lpProc ; sInfo.lParam = lParam ; sInfo.bEnd = FALSE ; try { m_lpfVDMEnumTaskWOWEx( lpdwPIDs[dwIndex], (TASKENUMPROCEX) Enum16, (LPARAM) &sInfo); } catch(...) { continue; } if(sInfo.bEnd) break ; } } HeapFree( GetProcessHeap(), 0, lpdwPIDs ) ; return TRUE ; } BOOL CProcessEnumerator::Enum16( DWORD dwThreadId, WORD hMod16, WORD hTask16, PSZ pszModName, PSZ pszFileName, LPARAM lpUserDefined ) { BOOL bRet ; ENUMINFOSTRUCT *psInfo = (ENUMINFOSTRUCT *)lpUserDefined ; bRet = psInfo->lpProc( psInfo->dwPID, hTask16, pszFileName, psInfo->lParam ) ; if(!bRet) { psInfo->bEnd = TRUE ; } return !bRet; } //