m_hWin95Kernel=GetModuleHandle(_T("kernel32.dll")); if(!m_hWin95Kernel) { m_strLastError=_T("Could not get kernel32 handle"); return false; } m_p_fnCreateToolhelp32Snapshot=(PFN_CREATETHELP32SNPSHT)GetProcAddress(m_hWin95Kernel,"CreateToolhelp32Snapshot"); if (!m_p_fnCreateToolhelp32Snapshot) { m_strLastError=_T("Could not get CreateToolhelp32Snapshot pointer"); return false; } m_p_fnProcess32First=(PFN_PROCESS32FIRST)GetProcAddress(m_hWin95Kernel,"Process32First"); if (!m_p_fnProcess32First) { m_strLastError=_T("Could not get Process32First pointer"); return false; } m_p_fnProcess32Next=(PFN_PROCESS32NEXT)GetProcAddress(m_hWin95Kernel,"Process32Next"); if (!m_p_fnProcess32Next) { m_strLastError=_T("Could not get Process32Next pointer"); return false; } //获得函数指针bool Win32Process::FindProcesses95(CString* ProcessName, bool bJustCheckingOne) { ///This function gets all the running process, the win95 way, using the ///ToolHelp functions. If you simply are checking if a process is active ///pass its name as a parameter and make the second parameter false. ///Otherwise, the function will ignore the ProcessName param and add to the array ///all the currently active processes... ASSERT(m_p_fnProcess32Next); ASSERT(m_p_fnProcess32First); ASSERT(m_p_fnCreateToolhelp32Snapshot); ///must have successfully called Init() first if (!bJustCheckingOne) { m_strArray.RemoveAll(); } else { m_bActive=false; ASSERT ((*ProcessName)!=""); ///If just checking if a process is alive, this must be the process' name } HANDLE handle; handle=m_p_fnCreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0); if ((const int)handle==-1) { m_strLastError=_T("Failed in creating snapshot"); return false; } PROCESSENTRY32 process; process.dwSize=sizeof(PROCESSENTRY32); BOOL bContinue=m_p_fnProcess32First(handle,&process); while(bContinue) { if (!bJustCheckingOne) //do we want to enumerate all processes, or do we just wanna check if one is active? m_strArray.Add(ExtractProcessName(process.szExeFile)); else { ///if here, then we are just looking to see if a certain process is alive... if ((*ProcessName) == ExtractProcessName(process.szExeFile)) { ///found the process, it is active.... CloseHandle(handle); m_bActive=true; return true; } } bContinue=m_p_fnProcess32Next(handle,&process); } CloseHandle(handle); return true; }
OpenProcess得到进程HANDLE
EnumProcessModules得到该Process的Module数组
对Module数组的第一个Module调用GetModuleFileNameEx得到exe文件全路径
哪位大侠有现成的代码,贴出来参考一下,下班前要搞出来.先谢谢大家了!!!
<1>操作系统用来管理进程的内核对象。内核对象也是系统用来存放关于进程的统计信息的地方。
<2>地址空间。它包含所有可执行模块或DLL模块的代码和数据。它还包含动态内存分配的空间,如线程的堆栈和堆分配空间。
枚举系统进程的实现方法大概有四种,其中有一种可以用来枚举远程NT系统的进程,前提是有远程系统的管理员权限。
<<第一部分:调用PSAPI函数枚举系统进程>>
M$的Windows NT开发小组开发了自己Process Status函数,包含在PSAPI.DLL文件中,这些函数只能在高于NT4.0以后的版本中使用。PSAPI一共有14个函数[实际PSAPI.DLL输出函数有19个,但其中有5个函数有两个版本,分别是ANSI和Unicode版本],通过调用这些函数,我们可以很方便的取得系统进程的所有信息,例如进程名、进程ID、父进程ID、进程优先级、映射到进程空间的模块列表等等。为了方便起见,以下的例子程序只获取进程的名字和ID。
简单的程序如下:
/*************************************************************************
Module:ps.c
说明:调用PSAPI函数枚举系统进程名和ID,Only for NT/2000
*************************************************************************/
#include
#include
#include "psapi.h"#pragma comment(lib,"psapi.lib")
void PrintProcessNameAndID( DWORD processID )
{ char szProcessName[MAX_PATH] = "unknown"; //取得进程的句柄 HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processID ); //取得进程名称 if ( hProcess ) { HMODULE hMod; DWORD cbNeeded; if ( EnumProcessModules( hProcess, &hMod, sizeof(hMod), &cbNeeded) ) GetModuleBaseName( hProcess, hMod, szProcessName,sizeof(szProcessName) ); } //回显进程名称和ID printf( "\n%-20s%-20d", szProcessName, processID );//这儿都有szProcessName了知道怎么作了吧,呵呵。
CloseHandle( hProcess );}void main( ){ DWORD aProcesses[1024], cbNeeded, cProcesses; unsigned int i; //枚举系统进程ID列表 if ( !EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded ) ) return; // Calculate how many process identifiers were returned. //计算进程数量 cProcesses = cbNeeded / sizeof(DWORD); // 输出每个进程的名称和ID for ( i = 0; i < cProcesses; i++ ) PrintProcessNameAndID( aProcesses[i] ); return;}
首先, 调用 CreateToolhelp32Snapshot() 获得当前运行进程的快照,这个函数返回包含正在运行进程的快照句柄。其原形是:HANDLE WINAPI CreateToolhelp32Snapshot(DWORD dwFlags,DWORD th32ProcessID);其中:
dwFlags表示要包含在快照的内容为TH32CS_SNAPPROCESS表示在快照中包含进程列表;
th32ProcessID是进程号,为0表示当前进程。
返回值是一个句柄,如果没有进程正在运行,则返回INVALID_HANDLE_VALUE(可用GetLastError()获得),反之可用BOOL WINAPI Process32First(HANDLE hSnapshot, LPPROCESSENTRY32 lppe);获取返回的进程
如果Process32First返回TRUE,则第一个进程的信息已经在LPPROCESSENTRY32结构中,其余进程信息可用BOOL WINAPI Process32Next(HANDLE hSnapshot, LPPROCESSENTRY32 lppe)获得
LPPROCESSENTRY32结构的定义如下: typedef struct tagPROCESSENTRY32 {
DWORD dwSize; //此结构的大小
DWORD cntUsage; //进程的引用数,如果为0,则次进程已停止
DWORD th32ProcessID; //进程号
ULONG_PTR th32DefaultHeapID;
DWORD th32ModuleID; //此进程引用的模块ID
DWORD cntThreads; //此进程创建的线程数
DWORD th32ParentProcessID; //父进程的ID
LONG pcPriClassBase; //这个进程创建的线程的基本优先权
DWORD dwFlags; //保留
TCHAR szExeFile[MAX_PATH];
} PROCESSENTRY32;
typedef PROCESSENTRY32 *PPROCESSENTRY32;
最后不要忘了调用: CloseHandle();
另用函数是: HANDLE OpenProcess(
DWORD dwDesiredAccess, // access flag
BOOL bInheritHandle, // handle inheritance option
DWORD dwProcessId // process identifier
);
用它可打开一个进程,打开进程后,可用: BOOL TerminateProcess(
HANDLE hProcess, // handle to the process
UINT uExitCode // exit code for the process
);
psapi.h和psapi.lib都是.net才有的.这两个文件我有.但怎么才能在vc6.0下使用?
在第一部分提到的PSAPI函数只能枚举NT系统的进程,在Windows9x环境下我们可以通过调用ToolHelp API函数来达到枚举系统进程的目的。M$的Windows NT开发小组因为不喜欢ToolHelp函数,所以没有将这些函数添加给Windows NT,所以他们开发了自己的Process Status函数,就是第一部分提到的PSAPI了。但是后来M$已经将ToolHelp函数添加给了Windows 2000。ToolHelp共有12个函数,通过调用这些函数可以方面的取得本地系统进程的详细信息,以下这个简单的例子只调用了三个函数,获取我们所需要系统进程名字和进程ID。程序如下:
/**********************************************************************
Module:ps.c
说明:调用ToolHelp函数枚举本地系统进程名和ID,Only for 9x/2000
**********************************************************************/
#include
#include
#include
int main()
{
HANDLE hProcessSnap = NULL;
PROCESSENTRY32 pe32 = {0};
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hProcessSnap == (HANDLE)-1)
{
printf("\nCreateToolhelp32Snapshot() failed:%d",GetLastError());
return 1;
}
pe32.dwSize = sizeof(PROCESSENTRY32);
printf("\nProcessName ProcessID");
if (Process32First(hProcessSnap, &pe32))
{
do
{
printf("\n%-20s%d",pe32.szExeFile,pe32.th32ProcessID);
}while (Process32Next(hProcessSnap, &pe32));
}
else
{
printf("\nProcess32Firstt() failed:%d",GetLastError());
}
CloseHandle (hProcessSnap);
return 0;}
第四:调用NTDLL.DLL中未公开API枚举本地系统进程
那个未公开API就是NtQuerySystemInformation
第五部分:从PDH中取得本地/远程系统进程信息
先简单的说说PDH是什么东西,PDH是英文Performance Data Helper的缩写,Windows NT一直在更新这个称为Performance Data的数据库,这个数据库包含了大量的信息,例如CPU使用率,内存使用率,系统进程信息等等一大堆有用的信息,可以通过注册表函数来访问。注意哦,Windows 9x中并没有配置这个数据库。但是,这个数据库中的信息布局很复杂,很多人并不愿意使用它,包括我。而且刚开始的时候,它也没有自己特定的函数,只能通过现有的注册表函数来操作。后来,为了使该数据库的使用变得容易,MS开发了一组Performance Data Helper函数,包含在PDH.DLL文件中。Windows 2000默认是允许远程注册表操作的,所以我们就可以通过连接远程系统的注册表,从它的PDH中取得我们所需要的系统进程信息了,当然这需要远程系统的Admin权限。
只可惜不能再贴代码了,满了,不让贴
第二种方法是编译过去了,但是GetProcessModule(DWORD dwPID, DWORD dwModuleID, LPMODULEENTRY32 lpMe32, DWORD cbMe32)总是返回0
请帮忙,谢谢!
不过出现很严重的问题.只要不是.exe结尾的进程,全部提示unknown,为什么?
例如System Idle Process 和 System都提示为unknown
LoadLibrary("C:\\WINNT\\system32\\psapi.dll");
通过GetProcAddress得到
EnumProcesses
EnumProcessModules
GetModuleFileNameEx
三个函数指针
#include <tlhelp32.h>typedef HANDLE (WINAPI *PFN_CREATETHELP32SNPSHT)(DWORD,DWORD);
typedef BOOL (WINAPI *PFN_PROCESS32FIRST)(HANDLE,PROCESSENTRY32*);
typedef BOOL (WINAPI *PFN_PROCESS32NEXT)(HANDLE,PROCESSENTRY32*);
HMODULE m_hWin95Kernel;
PFN_PROCESS32NEXT m_p_fnProcess32Next;
PFN_PROCESS32FIRST m_p_fnProcess32First;
PFN_CREATETHELP32SNPSHT m_p_fnCreateToolhelp32Snapshot;
m_hWin95Kernel=GetModuleHandle(_T("kernel32.dll"));
if(!m_hWin95Kernel)
{
m_strLastError=_T("Could not get kernel32 handle");
return false;
}
m_p_fnCreateToolhelp32Snapshot=(PFN_CREATETHELP32SNPSHT)GetProcAddress(m_hWin95Kernel,"CreateToolhelp32Snapshot");
if (!m_p_fnCreateToolhelp32Snapshot)
{
m_strLastError=_T("Could not get CreateToolhelp32Snapshot pointer");
return false;
} m_p_fnProcess32First=(PFN_PROCESS32FIRST)GetProcAddress(m_hWin95Kernel,"Process32First");
if (!m_p_fnProcess32First)
{
m_strLastError=_T("Could not get Process32First pointer");
return false;
} m_p_fnProcess32Next=(PFN_PROCESS32NEXT)GetProcAddress(m_hWin95Kernel,"Process32Next");
if (!m_p_fnProcess32Next)
{
m_strLastError=_T("Could not get Process32Next pointer");
return false;
}
//获得函数指针bool Win32Process::FindProcesses95(CString* ProcessName, bool bJustCheckingOne)
{
///This function gets all the running process, the win95 way, using the
///ToolHelp functions. If you simply are checking if a process is active
///pass its name as a parameter and make the second parameter false.
///Otherwise, the function will ignore the ProcessName param and add to the array
///all the currently active processes...
ASSERT(m_p_fnProcess32Next);
ASSERT(m_p_fnProcess32First);
ASSERT(m_p_fnCreateToolhelp32Snapshot); ///must have successfully called Init() first if (!bJustCheckingOne)
{
m_strArray.RemoveAll();
}
else
{
m_bActive=false;
ASSERT ((*ProcessName)!=""); ///If just checking if a process is alive, this must be the process' name
}
HANDLE handle;
handle=m_p_fnCreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
if ((const int)handle==-1)
{
m_strLastError=_T("Failed in creating snapshot");
return false;
} PROCESSENTRY32 process;
process.dwSize=sizeof(PROCESSENTRY32); BOOL bContinue=m_p_fnProcess32First(handle,&process); while(bContinue)
{
if (!bJustCheckingOne) //do we want to enumerate all processes, or do we just wanna check if one is active?
m_strArray.Add(ExtractProcessName(process.szExeFile));
else
{
///if here, then we are just looking to see if a certain process is alive...
if ((*ProcessName) == ExtractProcessName(process.szExeFile))
{
///found the process, it is active....
CloseHandle(handle);
m_bActive=true;
return true;
}
}
bContinue=m_p_fnProcess32Next(handle,&process);
} CloseHandle(handle);
return true;
}