从零开始,贝博集团论坛

快捷导航
广告联系qq1031180668贝博集团
查看: 4152|回复: 9
打印 上一主题 下一主题

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

[复制链接]
  • ta_mind

    2019-8-30 13:16
  • classn_01: 73 classn_02

    [LV.6]常住居民II

    1041

    主题

    1763

    帖子

    3623

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    3623

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

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


    Process32First 获取第一个进程信息
    [C] syntaxhighlighter_viewsource syntaxhighlighter_copycode
     Process32First(
        HANDLE hSnapshot,//CreateToolhelp32Snapshot 返回的句柄
        LPPROCESSENTRY32 lppe//保存进程信息的结构
    );

    PROCESSENTRY32 结构如下:
    [C] syntaxhighlighter_viewsource syntaxhighlighter_copycode
    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;


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


    纯c语言实现代码:
    [C] syntaxhighlighter_viewsource syntaxhighlighter_copycode
    #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;
    }
    


    vs2013 执行结果:

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


    运行结果:

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

    再次在vs2013下运行:

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

    导致这个问题的原因是在Unicode编码下processEntry.szExeFile是WCHAR(宽字节)类型数组
    在多字节字符集下是CHAR(窄字节)类型数组,如果希望不改变项目的字符集解决这一问题,可以通过编码转换的方式把Unicode编码下获取到的processEntry.szExeFile转换为Ansi编码,然后输出。
    不改变项目字符集,成功枚举进程的代码:
    [C] syntaxhighlighter_viewsource syntaxhighlighter_copycode
    #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;
    }
    
    

    运行结果同上。





    不积跬步,无以至千里
  • ta_mind
    开心
    2016-8-16 11:41
  • classn_01: 12 classn_02

    [LV.3]偶尔看看II

    5

    主题

    28

    帖子

    76

    积分

    注册会员

    Rank: 2

    积分
    76
    沙发
    发表于 2016-4-28 11:14:52 来自手机 | 只看该作者
    腻害!!
  • ta_mind
    开心
    2016-5-8 01:12
  • classn_01: 1 classn_02

    [LV.1]初来乍到

    0

    主题

    20

    帖子

    70

    积分

    注册会员

    Rank: 2

    积分
    70
    板凳
    发表于 2016-5-8 01:18:39 | 只看该作者
    贝博集团经验很丰富啊
  • ta_mind
    开心
    2017-2-19 19:55
  • classn_01: 1 classn_02

    [LV.1]初来乍到

    1

    主题

    60

    帖子

    74

    积分

    注册会员

    Rank: 2

    积分
    74
    地板
    发表于 2017-3-5 21:32:09 | 只看该作者
    感谢分享
  • ta_mind
    开心
    2017-2-19 19:55
  • classn_01: 1 classn_02

    [LV.1]初来乍到

    1

    主题

    60

    帖子

    74

    积分

    注册会员

    Rank: 2

    积分
    74
    5#
    发表于 2017-3-5 21:33:08 | 只看该作者
    感谢分享
  • ta_mind
    开心
    2017-2-19 19:55
  • classn_01: 1 classn_02

    [LV.1]初来乍到

    1

    主题

    60

    帖子

    74

    积分

    注册会员

    Rank: 2

    积分
    74
    6#
    发表于 2017-3-5 21:33:25 | 只看该作者
    感谢分享
  • ta_mind
    开心
    2017-2-19 19:55
  • classn_01: 1 classn_02

    [LV.1]初来乍到

    1

    主题

    60

    帖子

    74

    积分

    注册会员

    Rank: 2

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

    classn_11

    0

    主题

    18

    帖子

    40

    积分

    新手上路

    Rank: 1

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

    classn_11

    0

    主题

    37

    帖子

    69

    积分

    注册会员

    Rank: 2

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

    classn_11

    0

    主题

    37

    帖子

    69

    积分

    注册会员

    Rank: 2

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

    手机版|Archiver|小黑屋|sitemap| 从零开始,贝博集团论坛 - 一个单纯的贝博集团学习交流论坛 ( 豫ICP备15032706号 )

    GMT+8, 2019-9-11 20:45 , Processed in 1.141994 second(s), 28 queries .

    Powered by Discuz! X3.4

    ? 2001-2013 Comsenz Inc.

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