从零开始学www.yahu11.con-www.yahu11.con学习教程分享,www.yahu11.con技术交流论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 4477|回复: 9
打印 上一主题 下一主题

c语言枚举进程以及遇到的编码问题

[复制链接]

1059

主题

1781

帖子

3683

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
3683

最佳新人活跃会员热心会员推广达人宣传达人灌水之王突出贡献优秀版主荣誉管理论坛元老

跳转到指定楼层
楼主
发表于 2016-4-27 15:54:30 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
首先了解枚举进程需要用到的相关的api:CreateToolhelp32Snapshot 获取进程快照
[mw_shl_code=c,true]函数原型:
HANDLE WINAPI CreateToolhelp32Snapshot(
DWORD dwFlags, //用来指定“快照”中需要返回的对象,可以是TH32CS_SNAPPROCESS等
DWORD th32ProcessID //一个进程ID号,用来指定要获取哪一个进程的快照,当获取系统进程列表或获取 当前进程快照时可以设为0
);
//调用成功,返回快照的句柄,调用失败,返回INVALID_HANDLE_VALUE
[/mw_shl_code]

Process32First 获取第一个进程信息
[mw_shl_code=c,true] Process32First(
    HANDLE hSnapshot,//CreateToolhelp32Snapshot 返回的句柄
    LPPROCESSENTRY32 lppe//保存进程信息的结构
);[/mw_shl_code]
PROCESSENTRY32 结构如下:
[mw_shl_code=c,true]typedef struct tagPROCESSENTRY32 {
    DWORD dwSize; // 结构大小;
    DWORD cntUsage; // 此进程的引用计数;
    DWORD th32ProcessID; // 进程ID;
    DWORD th32DefaultHeapID; // 进程默认堆ID;
    DWORD th32ModuleID; // 进程模块ID;
    DWORD cntThreads; // 此进程开启的线程计数;
    DWORD th32ParentProcessID;// 父进程ID;
    LONG pcPriClassBase; // 线程优先权;
    DWORD dwFlags; // 保留;
    WCHAR szExeFile[MAX_PATH]; // 进程全名;
} PROCESSENTRY32;[/mw_shl_code]

Process32Next 来获得下一个进程信息
参数同Process32First  。


纯c语言实现代码:
[mw_shl_code=c,true]#include
#include
#include
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;
}
[/mw_shl_code]

vs2013 执行结果:

这时候发现一个很重要的问题,和预料的不同啊,进程名称显示乱码!代码并没有什么指针泄露,也不是printf安全不安全的问题,习惯性的丢到vc6里面,把代码修改为兼容vc6的标准(就是变量定义放在前面{:4_125:}):
[mw_shl_code=c,true]#include
#include
#include
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;
}[/mw_shl_code]

运行结果:

竟然没有出现乱码!!
机智的我这时候考虑到了编码问题,vc6的编码是Ansi,vs2013默认的Unicode,
那么vs修改项目文件属性,把字符集Unicode改为多字节字符集(以Ansi为基础的字符集):

再次在vs2013下运行:

这样就正常了,问题解决。

导致这个问题的原因是在Unicode编码下processEntry.szExeFile是WCHAR(宽字节)类型数组
在多字节字符集下是CHAR(窄字节)类型数组,如果希望不改变项目的字符集解决这一问题,可以通过编码转换的方式把Unicode编码下获取到的processEntry.szExeFile转换为Ansi编码,然后输出。
不改变项目字符集,成功枚举进程的代码:
[mw_shl_code=c,true]#include
#include
#include
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);//编码转换-unicode转ansi
                printf("ProcessID:%d  %s\n",processEntry.th32ProcessID,str);
                bRet = Process32Next(hProcessSnap,&processEntry);
        }
        CloseHandle(hProcessSnap);
        system("pause");
        return 0;
}

[/mw_shl_code]
运行结果同上。





不积跬步,无以至千里

5

主题

28

帖子

76

积分

Kib

Rank: 3Rank: 3

积分
76
2#
发表于 2016-4-28 11:14:52 来自手机 | 只看该作者
腻害!!

0

主题

20

帖子

70

积分

Kib

Rank: 3Rank: 3

积分
70
沙发
发表于 2016-5-8 01:18:39 | 只看该作者
www.yahu11.con经验很丰富啊

1

主题

60

帖子

74

积分

Kib

Rank: 3Rank: 3

积分
74
4#
发表于 2017-3-5 21:32:09 | 只看该作者
感谢分享

1

主题

60

帖子

74

积分

Kib

Rank: 3Rank: 3

积分
74
板凳
发表于 2017-3-5 21:33:08 | 只看该作者
感谢分享

1

主题

60

帖子

74

积分

Kib

Rank: 3Rank: 3

积分
74
6#
发表于 2017-3-5 21:33:25 | 只看该作者
感谢分享

1

主题

60

帖子

74

积分

Kib

Rank: 3Rank: 3

积分
74
地板
发表于 2017-3-5 21:33:44 | 只看该作者
感谢分享

0

主题

18

帖子

40

积分

Byte

Rank: 2

积分
40
8#
发表于 2017-5-8 16:29:32 | 只看该作者
666666666666666666

0

主题

37

帖子

69

积分

Kib

Rank: 3Rank: 3

积分
69
9#
发表于 2017-10-31 14:57:42 | 只看该作者
感谢大大们的分享

0

主题

37

帖子

69

积分

Kib

Rank: 3Rank: 3

积分
69
10#
发表于 2017-10-31 14:59:00 | 只看该作者
感谢大大们的分享
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

展开

QQ|Archiver|手机版|小黑屋|从零开始学www.yahu11.con ( 豫ICP备15032706号-2 )

GMT+8, 2019-11-11 06:35 , Processed in 0.178219 second(s), 55 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表