首先了解枚举进程需要用到的相关的api:CreateToolhelp32Snapshot 获取进程快照
[C] 纯文本查看 复制代码
1
2
3
4
5
6
|
函数原型:
HANDLE WINAPI CreateToolhelp32Snapshot(
DWORD dwFlags,
DWORD th32ProcessID
);
|
Process32First 获取第一个进程信息
[C] 纯文本查看 复制代码
1
2
3
4
|
Process32First(
HANDLE hSnapshot,
LPPROCESSENTRY32 lppe
);
|
PROCESSENTRY32 结构如下:
[C] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
|
typedef struct tagPROCESSENTRY32 {
DWORD dwSize;
DWORD cntUsage;
DWORD th32ProcessID;
DWORD th32DefaultHeapID;
DWORD th32ModuleID;
DWORD cntThreads;
DWORD th32ParentProcessID;
LONG pcPriClassBase;
DWORD dwFlags;
WCHAR szExeFile[MAX_PATH];
} PROCESSENTRY32;
|
Process32Next 来获得下一个进程信息 参数同Process32First 。
纯C语言实现代码:
[C] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
|
#include <Windows.h>
#include <TlHelp32.h>
#include <stdio.h>
int main()
{
PROCESSENTRY32 processEntry = { 0 };
processEntry.dwSize = sizeof (PROCESSENTRY32);
HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
if (hProcessSnap == INVALID_HANDLE_VALUE) return -1;
BOOL bRet = Process32First(hProcessSnap,&processEntry);
while (bRet)
{
printf ( "ProcessID:%d %s\n" ,processEntry.th32ProcessID,processEntry.szExeFile);
bRet = Process32Next(hProcessSnap,&processEntry);
}
CloseHandle(hProcessSnap);
system ( "pause" );
return 0;
}
|
vs2013 执行结果: <ignore_js_op> 这时候发现一个很重要的问题,和预料的不同啊,进程名称显示乱码!代码并没有什么指针泄露,也不是printf安全不安全的问题,习惯性的丢到vc6里面,把代码修改为兼容vc6的标准(就是变量定义放在前面 ):
[C] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
#include <Windows.h>
#include <TlHelp32.h>
#include <stdio.h>
int main()
{
HANDLE hProcessSnap;
PROCESSENTRY32 processEntry = { 0 };
BOOL bRet ;
processEntry.dwSize = sizeof (PROCESSENTRY32);
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
if (hProcessSnap == INVALID_HANDLE_VALUE) return -1;
bRet= Process32First(hProcessSnap,&processEntry);
while (bRet)
{
printf ( "ProcessID:%d %s\n" ,processEntry.th32ProcessID,processEntry.szExeFile);
bRet = Process32Next(hProcessSnap,&processEntry);
}
CloseHandle(hProcessSnap);
system ( "pause" );
return 0;
}
|
运行结果: <ignore_js_op> 竟然没有出现乱码!! 机智的我这时候考虑到了编码问题,vc6的编码是Ansi,vs2013默认的Unicode, 那么vs修改项目文件属性,把字符集Unicode改为多字节字符集(以Ansi为基础的字符集): <ignore_js_op> 再次在vs2013下运行: <ignore_js_op> 这样就正常了,问题解决。
导致这个问题的原因是在Unicode编码下processEntry.szExeFile是WCHAR(宽字节)类型数组 在多字节字符集下是CHAR(窄字节)类型数组,如果希望不改变项目的字符集解决这一问题,可以通过编码转换的方式把Unicode编码下获取到的processEntry.szExeFile转换为Ansi编码,然后输出。 不改变项目字符集,成功枚举进程的代码:
[C] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
#include <Windows.h>
#include <TlHelp32.h>
#include <stdio.h>
int main()
{
PROCESSENTRY32 processEntry = { 0 };
processEntry.dwSize = sizeof (PROCESSENTRY32);
HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
if (hProcessSnap == INVALID_HANDLE_VALUE) return -1;
BOOL bRet = Process32First(hProcessSnap,&processEntry);
while (bRet)
{
int nLength = WideCharToMultiByte(CP_ACP, 0, processEntry.szExeFile, -1, NULL, 0, NULL, NULL);
char *str = ( char *) malloc ( sizeof ( char )*nLength);
WideCharToMultiByte(CP_ACP, 0, processEntry.szExeFile, -1, str, nLength, NULL, NULL);
printf ( "ProcessID:%d %s\n" ,processEntry.th32ProcessID,str);
bRet = Process32Next(hProcessSnap,&processEntry);
}
CloseHandle(hProcessSnap);
system ( "pause" );
return 0;
}
|
运行结果同上。 |
原文地址:http://www.c0ks.com/thread-1291-1-1.html