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

首先了解枚举进程需要用到的相关的api:CreateToolhelp32Snapshot 获取进程快照

[C] 纯文本查看 复制代码

?


1

2

3

4

5

6

函数原型:

HANDLE WINAPI CreateToolhelp32Snapshot(

DWORD dwFlags, //用来指定“快照”中需要返回的对象,可以是TH32CS_SNAPPROCESS等

DWORD th32ProcessID //一个进程ID号,用来指定要获取哪一个进程的快照,当获取系统进程列表或获取 当前进程快照时可以设为0

);

//调用成功,返回快照的句柄,调用失败,返回INVALID_HANDLE_VALUE

Process32First 获取第一个进程信息

[C] 纯文本查看 复制代码

?


1

2

3

4

Process32First(

    HANDLE hSnapshot,//CreateToolhelp32Snapshot 返回的句柄

    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; // 进程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] 纯文本查看 复制代码

?


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);//编码转换-unicode转ansi

                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

时间: 2024-12-14 02:24:06

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

python语言学习8——字符串和编码

Unicode编码 计算机只能处理数字,如果要处理文本,就必须把文本转化为数字才能处理 有许多编码标准,但是不同的编码标准有时候会混乱,所以Unicode应运而生 Unicode把所有语言统一到一套编码里,这样就不会再有乱码问题 ASCII编码和Unicode编码的区别: ASCII编码是1个字节,而Unicode编码通常是2个字节. 字母A用ASCII编码是十进制的65,二进制的01000001: 字符0用ASCII编码是十进制的48,二进制的00110000,注意字符'0'和整数0是不同的:

C语言之霍夫曼编码学习

?1,霍夫曼编码描述哈夫曼树─即最优二叉树,带权路径长度最小的二叉树,经常应用于数据压缩. 在计算机信息处理中,"哈夫曼编码"是一种一致性编码法(又称"熵编码法"),用于数据的无损耗压缩.这一术语是指使用一张特殊的编码表将源字符(例如某文件中的一个符号)进行编码.这张编码表的特殊之处在于,它是根据每一个源字符出现的估算概率而建立起来的(出现概率高的字符使用较短的编码,反之出现概率低的则使用较长的编码,这便使编码之后的字符串的平均期望长度降低,从而达到无损压缩数据的目

数据结构(java语言描述)哈夫曼编码

原理:哈夫曼编码是根据将已给出的权值作为叶子结点,生成一颗哈夫曼树,然后使得权重最小. 首先生成已给权重的所有的叶子结点,然后取所有节点中最小和次小的结点作为左右孩子生成一个哈夫曼树,计算出父节点的权重放入给出的权重森林中,并把之前的最小和次小的结点从森林中删除,再在种种森林中找最小和次小的结点生成权重树....直到最终只剩下一个树为止. 哈夫曼树的结点用如下结点表示: (有权重,左右孩子,父节点,然后设置一个标识符标志结点是否已经放入哈夫曼树) package tree;/**********

base64编码、解码的C语言实现

转自:http://www.cnblogs.com/yejianfei/archive/2013/04/06/3002838.html base64是一种基于64个可打印字符来表示二进制数据的表示方法.由于26=64,所以每6位为一个单位,对应某个可打印字符.三个字节共24位,对应于4个base64单位,即3个字节需要用4个可打印字符来表示.它常用来作为电子邮件的传输编码.在base64中的可打印字符包括大写英文字母A-Z,小写英文字母a-z.阿拉伯数字0-9,这样共有62个字符,此外两个可打印

02 java语言基础

常量:字面值常量(字符串,字符,整数,小数,布尔,null),自定义常量,''这个不是字符常量,""这个是字符串常量 进制: 02.01_Java语言基础(常量的概述和使用)(掌握) A:什么是常量 在程序执行的过程中其值不可以发生改变 B:Java中常量的分类 字面值常量 自定义常量(面向对象部分讲) C:字面值常量的分类 字符串常量 用双引号括起来的内容 整数常量 所有整数 小数常量 所有小数 字符常量 用单引号括起来的内容,里面只能放单个数字,单个字母或单个符号 布尔常量 较为特

linux系统字符编码详解

众所周知,地球上的语言多种多样,在计算机世界,自然也是要适应各种语言.我们安装各种系统的时候也是明示了要选择语言环境和支持的语言环境. 而linux系统的字符编码设置尤为复杂,这可能也是没有考虑到非技术人员去研究这些东西吧. 我遇到的事情是这样的,我们使用了docker,但是docker容器里的语言环境经常莫名错乱,搞得很头痛,所以偶尔就要切换,或者生成其他字符集.所以现在假设我们需要切换一个中文语言环境,而切换了之后是乱码的,也就是没用的. 基本上,乱码的原因就是没加载到合适的字符编码环境,即

12.30 字符集和字符编码(Charset &amp; Encoding)(转载)

——每个软件开发人员应该无条件掌握的知识! ——Unicode伟大的创想! 相信大家一定碰到过,打开某个网页,却显示一堆像乱码,如"б?ЯАзЪСЯ"."?????????"?还记得HTTP中的Accept-Charset.Accept-Encoding.Accept-Language.Content-Encoding.Content-Language等消息头字段?这些就是接下来我们要探讨的. 目录: 1.基础知识 2.常用字符集和字符编码 2.1. ASCII字符

Java编码与乱码问题

一.为什么要编码? 由于人类的语言太多,因而表示这些语言的符号太多,无法用计算机的一个基本的存储单元----byte来表示,因而必须要经过拆分或一些翻译工作,才能让计算机能理解. byte一个字节即8个bit,所以能表示的字符范围是0~255个,这满足不了人类的需要,要解决这个矛盾必须需要一个新的数据结构char,从char到byte必须经过编码. 二.常用编码介绍 ASCII码 总共128个,用一个字节的低7位表示,0~31是控制字符,如换行.回车.删除等,32~126是打印字符,可以通过键盘

字符集和字符编码(Charset &amp; Encoding)

相信大家一定碰到过,打开某个网页,却显示一堆像乱码,如"б?ЯАзЪСЯ"."?????????"?还记得HTTP中的Accept-Charset.Accept-Encoding.Accept-Language.Content-Encoding.Content-Language等消息头字段?这些就是接下来我们要探讨的. 目录: 1.基础知识 2.常用字符集和字符编码 2.1. ASCII字符集&编码 2.2. GBXXXX字符集&编码 2.3. BI