00:00
今天开始呢,我们来这个讲这个Windows系统编程啊,然后我们首先呢,先。打开我的这个环境啊,打开visual studio2017啊,然后我们今天主要以这个环境来进行一个讲解,首先呢,我们创建一个空项目啊,名字呢随意啊点击确定。啊,打开之后呢,我们创建一个新的这个源文件啊。啊,点击啊这个CP啊,我们直接创建一个CP文件就可以了啊,这个may.cp好,首先呢,我们要包含两个通文键啊,一个是这个STI啊,标准输入输出啊,还有一个呢,就是Windows h啊,我们这节课呢,主要就用这两个这个头文件就可以了,然后呢,写一个妹。好,现在呢,我们就来讲一讲咱们进程相关的一些常用的知识啊,就包括我们创建进程啊,便利进程啊,还有一些进程的一些相关结构,以及怎么去结束进程啊,当然都是三环的一些知识啊,啊,就是一些这个入门级的啊,我们之后呢,还会讲这个,比如说一些这个进程三环和灵环结构体啊之类的一些知识啊,那么不是这节课的啊,这之后的有可能有有可能没有啊,先说这么一下,首先呢,我们来了解一下进程这么一个概念啊,就是我们在这个任务管理器里看到的这些东西啊,这些详细信息啊,这些东西都是属于什么,都是属于各个进程啊,这个进程呢,它有什么呢?它有这个进程ID啊,有一些状态啊,然后它归属于某一个用户啊,CPU占有多少啊,这个内存占有多少啊,UC啊有没有啊,那么这些东西呢,是我们的任务管理器体现给我的,那如果说是我操作系统啊,这个东西啊,那么。
01:50
它里边呢,最基本最基本的需要两个部分啊,一个进程啊,需要两个基本部分,这两个基本部分呢,首先第一个就是什么,就是一个管理啊,管理用的啊内核对象啊,也就是我们什么呢?我们的进程句柄。
02:15
啊,进程句柄啊,然后这些东西呢,它呢,其实呢,都是在我们的这个句柄表里啊,当然现在呢,你不用管它啊,你知道有这么一个东西啊,一个内核对象就行了,接下来就是什么呢?还需要一个啊包含啊这个代码数据等啊的啊这个地址空间啊,这个呢是我们一个进程啊,最基本最基本的一个需求啊,需求这么点东西,然后呢,我们这个要创建一个进程呢,通常情况下呢,我们用的比较多的呢,就是啊,当然还有一些也可以创建啊进程啊,其实呢,也不算是创建进程,应该说是执行的一个进程啊呃,像create啊是我们最常用的,还有什么呢?还有类似于这个啊,还有这个这种啊啊这种都是可以创建进程的,包括其实如果说你这个手法诡异一点,用这个system啊,也可以把进程搞起来啊,好,那么我们可以看一下啊,我们create这个函数呢,它实际上是一个紫色的东西,也就是。
03:16
实际上是一个红啊,是一个红啊,这是一个红,那么我们这个红是什么意思,大家应该都知道啊,这是西元的一个知识啊,如果不知道呢,需要去补习一下西语元的一个知识,我们现在呢,就看来看什么呢?看它这个里面啊,我们在点击之后啊F12跟进去,跟进之后你可以看到它有一个process a啊A上边还有一个红的是一个create create process w啊然后我们在这呢,有一个预处理啊,我们把这个预处理拷出来啊,然后给它注释掉,那这个预处理是什么意思呢?其实呢,很明显啊,很明显我们把这个东西啊给它搞过来啊,对齐一点。好,它其实就是什么,如果说我们当前的会议环境是用Co的啊,那我们的DeFine就是使用什么呢?这个credit process的一个宏,就使用process w这个宏,否则呢,就使用这个A的这个宏,那它们俩之间区别呢,实际上是一个编译环境的一个区别,那这个编译环境在哪呢?在这个项目上右键啊有一个属性,属性里边呢,有一个什么呢?有一个叫做这个字符集啊,那如果说你使用的是字符集呢,它选择的就是什么?就是credit price a,如果你选择的是这个unode呢,就是create w啊,这个是根据它的字符集来进行一个选择的,也就是多字节和宽字符的这么一个区别啊,所以说呢,我们这呢,一般情况下呢,会直接使用这个这个credit啊,要由这个自己去选择,到底调用哪一个啊,但是呢,这样呢也有一点不好,就是什么呢?就是它里边有一些参数呢,是字符串的,比如说我们跟进去啊,跟到这个A这里边啊,它是字符串啊,你看这个A这是W,那比如说第一个啊这个什么,这是一。
04:58
这个lp application的一个name啊,也就是我们应用的名称,那这个名称呢,是我们要填写的是什么呢?是我们要执行的这个可执行程序的一个路径,那这个路径如果你是A版的呢,它是什么呢?它是一个型的,如果这个呢,它是什么?它是一个W叉杠下电梯类型的啊,也就是说呢,你在写的时候啊,它会导致什么呢?
05:20
会导致你的这个字符串不兼容啊,因为什么?因为你声明的方式不同啊,如果说你是一个A版的,你字符串就是这样啊,你就说这是A版的字符串啊,那L这个W版的呢,你要前面加一个L啊,对不对啊,所以说呢,它是有一定区别的啊,那么我们现在直接使用它啊,我们来直接创建我们的进程啊,我们来看一下啊,它的每一个参数都是干什么的啊,正常情况下来说呢,我们可以直接啊 Nf1啊,然后进入MSDN啊,它里边呢,会有一个这个do啊啊就可以来看它的文档的一些含义啊,现在呢,我们进的是这个create pricea的一个说明文档,底下要还有一个create price的一个说明文档啊,那我们现在呢,就要来干嘛,就来看一下它的每一个参数都是干什么的啊,你可以看到啊,这个呢,它的参数说明呢,相对而言呢,呃,看起来很复杂,但实际上仍然总结出来就是一句话,就是什么呢?就是这个就是我们要执行的可执行模块模块的一个参数啊,你可以看到可以是吸盘下的啊这个什么一个EE可以是吸。
06:20
盘的一个子目录下的一个EXSE可以是这个子目录的子目录的一个ESE啊就是这么一回事,反正呢,它是一个可执行程序的一个路径,那比如说我们现在呢,给它做一个填写啊,那我们桌面上暂时他没有这个样啊,有这个这个这个东西啊啊算了,我我我出去拷一个吧,我拷一个这个东西回来。啊,你运行啊,运行完它就是这样的啊,那我们现在呢,就干嘛呢,我们啊把它的路径啊设置回来啊,Credit啊右键属性啊,然后直接先把它的这个路径啊回来拿回来啊用这个,因为我们现在是A版,所以说我们直接这样放就行了,接着呢,我们拿它的什么呢?拿它的这个名字部分啊C点啊。
07:07
好,这里边儿呢,我们要处理一下啊,根据西园的规则,我们要处理它的转移。好,这样就正常了啊,那么我们这个参数就是啊,想要执行的可执行程序的啊路径啊,这个路径呢,可以是这个绝对路径,也可以是相对路径啊,都是可以的啊,没有什么问题啊,接下来呢,就是我们的第二个参数啊,第二个参数呢,是什么意思呢?我们来看一下啊,你 Nf12也可以看到的参数啊,然后 Nf1只是说它这个参数有解释啊,你看这个F12里实际上也是一个有有参数的啊,它是一个命令行啊,在这边A版啊命令行啊,那这个命令行呢,就是我们要什么呢?要传递给它来执行的命令行啊,比如说我们这个Windows或者linu啊,有很多的控制台程序,它可以干嘛呢?比如说一个杠T啊,一个杠H1-V之类的啊,它有一些参数,你可以给他这些参数传一些指定的值啊,那我们这个第二个参数就什么呢?第二个参数就是你要传递给可执性模块的一个参数啊,那你想有的时候呢,你就给他传一个,如果你想没有的时候呢,你就给他传一个啊。
08:15
啊,他是接受闹的啊,就是接受他没有这个东西的啊。好,那么下一个参数是什么呢?下一个参数啊,我们来看一下啊,它是一个进程的啊特性啊,但是这个进程特性呢,是什么意思呢?是可以往往前面看啊,它前面有一个这个security啊,就什么意思呢?就是一个安全的啊,所以说呢,它这两整个是一个什么呢?安全特性,然后这个安全特性呢,和底下这个呢,它是一样的一个东西啊,两个都是RP安全特性,其实就是安全特性这个结构的一个地址啊,这两个东西都是地址,然后呢,只是根据它的名字不同,你可以看到上边的是进程特性,下边呢是线程特性,然后你F12再跟进去,你可以看到这个是一个它的一个这个安全特性的一个结构的里边一个成员,这个呢是它的一个长度啊,这个呢,是这什么东西我忘了啊,这个东西是指向了一个叫security什么的一个,呃,结构是另一个结构啊,它虽然是一个lp word的一个缓冲区,但实际上应该按照结构来给它进行一个解析啊好。
09:21
然后呢,我们回来回来之后呢,我们这两个呢,都是可以使用闹的啊,如果使用闹呢,就是使用你当前的默认的一个安全属性啊就可以了。两个闹啊。进程安全属性。如果是no的话,使用默认的安全属性。下边这个呢,是现成的。
10:06
好,那接下来就是什么呢?下一个啊,下一个我们再来看它下一个参数啊,下一个参数是这个,这个呢,你可以看到它是一个布尔值啊,它也是一个输入的值,那这个值的意思是什么呢?是指定了我们当前这个进程中,我们可有一部分的这个句柄啊,它是可继承的句柄,那么这部分可继承句柄是不是可以被我们启动的新继承,新进承所继承,如果是true就是可以继承,如果是false就是不可以继承啊,那这个呢,现在对我们而言无伤大雅,我们就传一个force啊,不让他继承。好,看完这个属性之后,我们再看下一个属性啊,下一个属性这里可以看到它其实就是一个什么,它其实呢是一个这个flag啊,这个flag的作用呢,是标记两种东西,一个是新进程的一个优先级,还有一个呢就是创建的标志。
11:18
那这个东西呢,我们可以给他指定一个零啊。好,那么下一个参数啊,下一个参数这个东西啊,这个东西呢,是指定新进程所使用的环境变量,底下这个呢,你可以看到是当前目录,也就是说要可指定啊,你新进程使用的这个当前目录是什么?这两个呢,我们通常情况下也设置为闹啊,暂时不需要来给它进行规定。
12:23
好,接下来呢,是最后两个参数啊,这两个参数呢,一个是启动,这个启动信息啊,也就是我们的这个呃,Up,一个是程信息啊,那这两个结构呢,我们需要首先给它进行一个定义啊,比如说我这个start,这个start INF for啊,这个A啊,这个结构啊,我们要把它拿出来啊,但实际上我们在定义的时候呢,我们在上面定义的时候呢,我们直接给它定义这个infer就行了啊,不需要专门使用A版,然后呢,我们比如说我给它起个名啊,我们也可以直接用它这里边的一个这个变量名啊,这都没有问题啊,因为我们拿出来的是不带LP的啊,我们这儿也可以不带LP啊啊这样是可以的,然后呢,这个成这个里边呢,有一些成员啊,这是一个结构啊,你可以看到它这个结构在这个位置上啊,这个结构里边呢,都是什么东西呢,我们可以来简单的这个看一下啊,首先呢,这儿有一个or的字,这个ord类型的一个。
13:23
C是个用这个结构之前呢,使用这个呃,Set off它当前的这个结构啊,来进行一个获取设置啊,这个设置呢,是为了防止你当前这个结构未来有新字段填充进来啊,如果你填充进来之外之后呢,你这个字段的大小呢,可能就是不同了啊,所以说呢,为了向下兼容啊,你需要给它填一下它的大小啊,那么这个东西呢,就需要事先啊对它进行一个填充啊,也就是说你在这个位置上啊,有一个这个DW,有一个CB啊,你要直接啊给它设置成什么呢?Size off set off什么呢?Startup这个info啊。
14:07
这个大小啊,我们要给它设置进去啊,那接下来我们回来看一下啊,回来看一下我们这个第二个啊,这个东西你可以看到它名字就知道它是一个保留字段啊,然后接下来这个呢,是指定错桌面的一个,我直接把它复制出来,我们这个写一下啊,防止这个出现这个呃乱掉啊。嗯,我给他写在上面吧。好,这个我们往后拖一点啊,当前结构的大小需要事先啊填充,防止后续啊,这个新增字段啊,防止后续新增字段啊,结构体大小变更,第二个啊保留字段啊未使用。
15:08
第三个啊指定啊指定桌面名称。控制台啊,程序的这个窗口标题。然后这个XY啊,还有这个X size和y size,他们是新窗口的位置信息和尺寸信息,接下来是这个,这个呢是指定啊,你可以看到它这个content也是一个X一个Y啊,其实这是什么意思呢?是指定新窗口控制台可以显示的行数和列数啊,就是X和Y的这个数量,指定了它新窗口框台可以显示的行和列的一个总数啊,然后接下来呢,这个啊,这个呢,你可以看到它是一个这个特性啊,这个什么意思呢?这个是指定指定控制台程序的背景色啊,背景色就是我们当前背景色一般是黑色的,但是你可以设置成其他颜色啊啊然后呢,有需要这个课程回放的呀,还有一些资料的呀,还有一些其他的咨询的呀,可以联系咱们的。
16:27
扫满啊进行咨询,然后接下来啊,这有一个flag啊,这个flag呢,就是一个标志啊,指定了什么呢?指定了啊当前结构的啊哪些啊,哪些成员是有效的,指定了哪些成员是有效的啊然后接下来这个修window啊,这个修window的意思是啊,窗口啊,或者说叫这个窗的窗口的显示方式是什么啊,接下来这两个是保留字段啊保留字段。
17:01
这个也是保留字段啊,只是保留字段呢,这个类型不一样,接下来呢,这个三个呢,你可以看到这三个都是handle,也就是说呢,这三个都是句柄啊,那这三个句柄呢,就有不同的功能,比如说这个啊std input,这个是s TD output,这个是std,实际上是什么意思呢?就是标准的标准的输入啊,输入句柄,然后这个是什么呢?这个是这个标准的输出句柄以及。标准的错误区别啊,那这个呢,就是我们当前这个结构的一个这个完整信息啊,然后呢,我们说完这个信息之后呢,我们也把它进行一个初始化了,初始化之后呢,我们在这个位置上需要把它的地址啊给它填进去啊,然后啊,这样这个就什么这个就是。息启动信息啊,启动信息接着呢,我们最后一个最后一个这个参数啊,参数我们跟进去啊,然后再看一下这个参数是什么,最后一个参数叫做这个。
18:11
嗯,这事啊。它也是一个地址啊,前面的LP了啊,我们直接啊使用这个拿出来,拿出来之后呢,我们再去获取它的名字啊叫什么呢,叫做information。好,那这个结构呢,我们其中呢,有没有要这个初始化的东西呢?啊,我们来简单的给他这个看一下,我们首先呢,还是需要把这个结构的这个信息啊给它取出来。可以看到它的结构信息呢,是相对简单的啊,我们来给它注释一下,这里边呢,一共有四个成员啊,可以看到其实非常简单啊,也非常规范的四个成员,第一个啊是一个句柄类型,就是我们的当前的这个进程的进程句柄啊,不是当前进程啊,是我们当前使用啊创建的这个进程啊的进程句柄,然后这个是什么呢?这个是一个线程句柄,接着呢是进程ID,最后呢是一个线程ID。
19:21
好,那这个呢,就是它的一个完整的一个相关信息,那么我们在使用的时候呢,也是依然啊,要把它的这个信息啊给它填进去,好,那以上呢,这些东西呢,我们基本上呢,就已经给它填全了啊,这是最后一个啊进程相关信息,接着呢,我们在之后给它加一分号啊,我们code price这个参数呢,就算都填上了,我们来看一下它的返回值啊,我们跟一下这个credit a啊这呢是一个布尔值啊,其实呢,这个看到布尔值的时候呢,你应该知道啊,它这个东西是一个什么呢?是一个这个呃,它返回的一个结果啊,那我们也可以通过什么呢?可以通过它的这个文档啊,文档里头这有一个返回值啊,这写的是什么意思啊,也可以他也告诉你了,如果说它出现了错误,那么错误信息呢,你可以调用一个叫做get这个get last error的一个函数来进行一个获取啊,这底下呢,还有一个获取这个退出码的一个函数,叫做get这个什么这个code啊好,然后呢,我们接下。
20:22
再来呢,就来干嘛呢,就来运行一下啊,看看它有没有能直接用啊,我们首先呢,把它返回值啊,给它放上边啊,我们比如说我们用一个b return啊来接收一下它的返回值,接着呢,我们判断啊,做一个判断if,它这个返回值为true啊,为true呢就说明成功了啊,那我们就给它干嘛呢?给它取个反啊取个反如果说是这个不成功的情况下啊,那我们就可以给它进行打印,打印什么呢?打印我们调用了create啊,但是失败了。啊,如果说成功了呢,我们则可以相打印一些相关的信息,比如说啊,我可以直接打印啊,或者直接摆号D啊,然后后边杠二-N跟的是什么呢?跟的是我们这个结构process information里边的一些东西啊,比如说这个进程句柄。
21:20
好,然后呢,我们给他考四个。好,然后把它前面给它加上。
22:02
好,现在呢,我们来给它进行一次运行。啊,这引发了一个异常,我看一下这异常是什么。他这写的是,呃,难道是。首先是一个路径,路径完事是。参数。一个两个三个false,零,Now now。嗯,这两个好像。我给他设置了呀,这个start info这个。
23:15
啊,这有个错误,我看一下啊,She桌面exe。No no no false,零。这块应该也没有问题啊,难道要这样写?嗯,还真是这个问题啊,咱们这个初始化,初始化的不太正确啊,咱们要这么写啊。啊,然后呢,这个直接啊给他这个创建起来了,创建起来之后呢,我们这个创建进程这部分呢,应该是没什么问题了啊,这不是啊,咱们今天是在讲window系统编程的第一课啊,进程相关的知识,包括我们进程相关的结构体啊,这个结构体的信息都是什么意思,如何去填写这个参数啊,然后之后呢,咱们还会讲如何去便利结束进程啊,然后那个创建进程时注入这个,我记得咱们也之前也讲过公开课啊,也讲过公开课啊,你可以去找这个老板领一下啊。
24:25
好,然后呢,咱们这个部分呢,就是如果失败了就进到这儿啊,如果是成功了就进到这啊,刚才我没有看这部分啊,我们再来看一遍,我们点击继续啊,他这进程肯定是创建起来了啊,但是我的我的控制台退出了啊,因为我没有给他暂停一下啊,我需要在这个位置上啊,对我的控制台呢,进行一次暂停的操作,这不是录播啊,这是直播啊啊你可以看到我现在跟你说话啊,这位这个英河路的咕独的程序员啊好,然后呢,我们运行起来,运行起来之后呢,我们首先在这边啊,你可以看到是我们进程成功创建的一个信息,接着呢,它返回了它的句柄啊,进程句柄,线程句柄,然后进程ID和这个线程ID,这个东西呢,我们也可以直接通过右键啊,打开我们的任务管理器管理管理管理器啊,与这个我们系统这个对比一下啊,你看系统的任务管理器的PID9476啊,和我们自己返回的9476是没有什么区别的啊,另外呢,需要注意点是什么呢?如。
25:25
如果说你在这里使用这个process information啊,来给它接收回来了啊,而你这个句柄呢,就不准备用,那你可以使用什么呢?可用可以使用一个close handle啊,在这个尽量早的时态上啊,将它的这个剧本给它关闭掉啊。一个这个进程相关的进程句柄啊,还有一个这个线程相关的这个线程句柄啊。啊,这部分呢,是可以这个尽早给它关掉的,防止有一些这个安全性的问题啊,那以上呢,这部分呢,就是咱们这个创建以及进程的一些基本信息相关的一些东西,那么接下来呢,给大家再讲什么呢?就是它如何去结束进程,以及如何去便利进程啊,那么结束进程如果是结束我当前自己的进程的情况下呢,我们使用的是一般情况下是e sit process啊,那这个函数呢,它只有一个参数啊,我们可以F12跟进去看一下,它只有一个退出代码,这个退出代码呢,是相当于什么呢?相当于你运行之后啊,它这个控制台,你看这有一个返回值为零啊,相当于其实就输出在这个位置上的,那我们现在呢,就可以任意填一个,但是一般情况下呢,填零呢,就代表的是正常退出,那如果说我们没有写这个之前呢,我们应该是在这儿啊,把控制台暂停住啊,因为我这有一个system啊,然后用它暂停,但是我在这如果不暂停的情况下啊,在前面调用了退出进程,我们运行诶你看我控制台就没了啊,但是我这个也创建起来,为什么?因为我创建完之。
26:53
后的一瞬间啊,我调用了一个退出进程啊,我自己退出出去了,那这个呢,是退出我们当前进程啊,退出退出当前当前进程啊,然后呢,退出当前进程,它的参数是退出码。
27:17
啊,那如果我们要退出其他进程,或者说要结束其他进程啊,我们在三环一般比较使用的频繁的是什么呢?是也是一个这个API啊,这个API是这样的啊。嗯,TH不是不是TH啊,是T啊,然后process啊,我们可以F12根进去看一下啊,它其实有两个参数啊,一个参数呢还是推送码,另一个参数呢,就是你要结束的这个进程的一个进程句柄,那这个进程句柄我们如去如何获取呢?啊,不一定是所有的这个都是我们自己创建出来的,对不对啊,所以说只有我们自己创建出来这种我们才可以通过这个拿到的一个呃句柄,那如果说是其他进程呢,那么这个时候呢,我们需要自己获取啊,我们可以通过什么呢?通过进程的这个呃,进程的这个ID啊,因为我们这个进程ID是唯一的啊,是全局唯一的一个ID,我们可以通过它来进行什么呢?进程的一个打开啊,打开之后我们就可以干嘛呢?获取它的句柄啊,我们来看一下啊,我这个C在哪啊C。
28:22
啊,我那个进程关了啊,我重新给他开一下。比如说啊,他当前的这个精神ID是672啊,那么这个时候。啊,我这个不切虚拟机里来了。我的虚拟机在控制台哪啊,哎,不对,我的虚拟机控制台哪去了,我靠。哎,尴尬了。我先进去一下啊。
29:15
完了,我回不去了。啊,找到了找到了啊,我天在这儿回不去了。啊,新来的同学可以点一点关注啊,点一点关注啊,然后也可以咨询咱们老板获取一些这个相关的信息啊好,那现在呢,我们拿到了他的进程ID啊,也就是672啊,那我现在呢,有了进程ID672,但是这个进程ID呢,是这个会随机变的啊,那如果说我们想通过进程名来关呢,一会儿呢,需要学便历啊。
30:01
那现在呢,我先把上面这些东西呢,都给它注释掉啊,因为暂时我们也用不上这个东西了啊,所以说呢,我们先给它注释掉。好,注释完事之后呢,我们在这儿看我们是如何打开这个进程啊,那这个时候呢,我们要调用一个叫做open process的这么一个API啊,那这个API呢,它是不分这个W版和这个A版的啊,你可以看到F12进来之后呢,就是这么一个圆形啊,它一共呢是三个参数啊,我们给它拿出去啊,拿出去我们给它这个解析一下,首先呢,这个有一个这个什么这个win base API啊,这个东西主要是主要是说明一下啊,它是一个WIN32API啊,这个你不用管它啊,我们就去掉,然后呢,这里呢说明什么呢?是一个返回值,返回值是句柄啊,返回值句柄,然后win API的意思是什么呢?这个呢就是一个调用约定,我们跟进去看到它其实就相当于一个s TD call啊,S TD call的调用约定,接下来呢,是什么呢?这三个参数啊,第一个参数呢,实际上是一个访问权限,是一个权限啊,不应该说访问权限啊,就是你可以打开之后,你获取什么样的一个权限啊,一般情况下呢,我们在这儿呢,都使。
31:10
一个完整权限就是process all啊,来获取一个全权限啊,我们跟进去你可以看到啊,里头还有很多其他的权限啊,然后呢,我们第二个参数是什么东西呢?第二个参数啊,是我们的这个句柄啊。我们先填一个false,第二个参数呢,是我们啊返回的句柄是否可以继承,返回的句柄是否可以继承啊,我们在这不是返回了一个句柄吗?那么这一个点啊,就决定了这个参数,决定了我这里返回的这个句柄到底可不可以继承给我的子进程啊好,然后接下来呢,是什么呢?接下来呢,第三个啊是一个静态ID啊,那这个呢,就是我们要打开进程啊,唯一识就这一个东西啊,那我们把注释。
32:11
好,那我现在呢,第三个很明显我要填进程ID了,也就是我们的这个672啊,我们这样就完事了,接下来呢,它会返回什么呢?返回一个句柄啊,一个handle h啊,Process啊,等于啊,Open process啊,那这个东西呢,你可以判断一下啊,它有没有打开成功啊,也可以不判断啊,这个就随你便了,如果说你要判断它是否打开成功,那最好呢,你用判断它什么呢?不等于啊,如果它成功了,它不等于in va Li啊,然后呢是handle v6啊,最好是用它来判断,而不是用now来判断啊,因为什么呢?因为它和闹的值是不一样的啊,你看这个是什么,这个是它的这个红的这个值,用它来判断呢,微软可能会随时更新这个红的值叭较安全,但如果你用一个闹的话啊,用一个闹的话,这个闹的值实际上是个零啊,你可以看到它DeFine一个零,S plus plus是一个零啊,那这种情况下呢,它可能会造成一些误解啊,所以说呢,我们在判断句柄类型的值的时候呢,最好呢,是使用我们的这。
33:11
这个红来进行判断啊,那如果它不等于这个的情况下,这个宏的意思呢,是聚变无效啊,那如果是这个不等于它就说明句柄有效嘛,那我们就可以调用这个结束的这个函数了,如果不是的情况下呢,你也可以直接给它进行一下else叭,如说在这停一下,或者打印一点什么,呃,退出信息啊什么的都是可以的啊。啊,这是特殊信息,那我们现在呢,就可以来看它了啊,首先第一个句柄我们拿到了,我们直接把句柄传进去,那第二个就是什么,第二个就是我们的这个进程ID啊,那我们刚才这个位置672也看见了,我们传进去,接下来呢,我们就可以在这儿啊看着这个进程啊,我们来对比一下啊,我们现在运行。
34:07
你可以看到在我程序运行的一瞬间,我这边的这个进程就已经没了啊,就已经没了,这说明什么呢?说明我们通过这种方式啊,将其结束掉了啊将其结束掉了。好,那么现在呢,我们这个呢,结束这部分呢,我们就看完了啊,这个是我们三环最常用的一种结束方式啊,在前面呢,咱们讲过一些公开课里也可以看到有一些这个暴力结束啊之类的啊,就比如说把它的认定存传刷空啊什么的啊这种方式啊,但是这种呢,实际上是这个最推荐使用的,因为它是正规的退出方式啊好,接下来呢,我们把它们再给注释掉啊。我们来看进程基础的最后一个话题啊,就是我们来便利一下进程啊,便利进程呢,其实是一个非常简单的事情,我们Windows呢,有很多方式都可以便利进程,比如说便利这个进程链表啊什么的啊,但是呢,其中最简单的方式呢,还是以快照的形式啊,这里对其进行便利,我们首先呢,要包含一个投文键,就是TL have32.h这个投文键啊然后呢,我们用什么呢?用一个啊创建啊create啊,Tol用这个啊来创建什么呢?创建我们的进程快照这个函数呢,创建的这个快照呢,顾名思义啊,就是什么呢?就是跟我们啊在这个照相馆拍的那个快照很像,他把当前的啊进程的相关信息啊都给你固定下来啊,那怎么去传他的参数呢?你可以看到他两个参数,第一个是一个flag,第二个呢是一个进程的ID,那为什么还有要便利进程,还有进程ID呢,是主要是因为我们当前的啊,当前的这个东西啊,是不需要什么呢,不需要这个进程ID,但是它其他的功。
35:47
能啊,是需要进程ID的啊,我们首先啊s nap啊,Process啊,这前面是什么来着,T23这个CS,我们来看一下它的这个前四个啊,前四个它这底下还有什么奥什么的啊,那咱们先不管了,我们先看一下前四个。
36:06
好,我给他注释一下。你可以看到啊,这个是什么东西啊,把这个TH3CS和这个SNP去掉之后啊,后边就是它实际的一个用途啊,然后呢,比如说我第一个这是什么呀,这是堆列表啊。堆啊,这是堆,第二个什么呀,是进程,第三个是什么呀?是线程,第四个什么呀,是模块啊,也就是说什么呢?也就是说我当前这个东西就是可以干嘛呢?可以便利堆,可以便利进程,可以不离便利线程,可以便利模块啊然后呢,我这里边呢,进程啊,进程这一项是不需要指定啊,第二个参数的啊,进程ID,但是其他几个都是需要指定的,因为什么呢?因为其他几个啊是需要你指定到底是哪一个进程的,哪一个进程的程和哪一个进程的模块,你要对它做一个筛选啊,所以说呢,你是需要的啊,啊只有进程啊,在便利进程的时候不需要,因为它要便利所有的进程啊,那么接下来呢,我们在现在呢,第二个参数里就要填一下进程ID啊,在我们便利进程的情况下,我们填个零或者now啊都是可以的,接下来呢,我们F12跟进去,你可以看到它返回的。
37:26
也是一个句柄,是一个handle啊,然后呢,是一个HS na啊等于我们接收到啊,它的一个什么呢?这个相当于一个快照句柄啊,啊无论是便利堆,便利进程,便利线程啊,便利模块呢,它都是有一对函数的啊,那像是我们便利这个进程啊,使用的就是啊这一对啊这个first和这个他们两个之间的参数呢,都很接近啊,首先呢,我们这个32FIRST,它第一个参数就是我们刚才啊创建快照的一个快照句柄,第二个参数什么呢?第二个参数呢,它是一个结构体叫做 process entry32我们可以把它拿出来。
38:11
啊,我们在前边要给它做一个定义啊,然后这个呢,我们直接给它改个名叫PE32,那我们PE32这个结构呢,我们首先呢,要给它干嘛呢?要给他进行一个初始化啊,他刚跟我们刚才的start up info一样啊,都需要对其中的size啊,进行这个初始化,也是避免在后续的过程中啊,添加新的成员啊,然后导致它的结构大小不同,那我们就set off一下啊,把这个process entry32填进去啊,对它呢,进行一个初始化,接下来呢,我们来看一下它里边的一个成员啊,首先呢,这个呢,就是我们刚才初始化的啊,这个本结构的一个尺寸啊,其他的呢,我们拿出去啊,给大家再写一下。第一个是什么呀?第一个我们刚才说了啊,是本结构,本结构的尺寸,这个呢是什么啊,这个是啊当前啊这个进程进程的引用技术。
39:13
当前的引用技数啊,然后这个呢是进程ID啊,是当前进程的进程ID,这个呢是默认啊,当前进程默认的ID啊,然后这个呢是模块啊模块ID,这个是线程总数啊,当前进程的线程总数。然后接下来这个呢,是进程ID这个啊。当前。当前进程创建的线程的基本优先级啊好,这个呢是一个flag啊,内部使用啊,我们暂时不用管它标志位。
40:02
好,最后呢,这个是一个派啊路径啊,也就是进程啊,对应的文件名啊,文件名啊有这么多信息,那么现在呢,我们就要来声明这么一个东西了,之后我们把它啊取地址传进去,由什么呢?由API对我们当前的这个结构进行填充,现在呢,我们要来这个获取一下它的返回值,可以看到它返回值也是一个布尔,所以说呢,我们直接啊来接收一下它的这个返回值是什么啊,然后呢,我们通过一个while循环进行遍历判断啊,它的这个返回值是否有效啊,如果有效的情况下呢,我们就继续继续去遍利它里边的信息啊,比如说我可以打印一下什么呢?打印一下它的这个进程名啊,进程ID啊。它呢,就是我们刚才说的P32中的对应的文件名这个东西。
41:14
好,下一个进程ID。好,然后呢,如果你需要其他的,你可以根据它的这个描述啊,来进行打印啊,然后接下来呢,我们就要来啊,我如果说遍历完了当前的这个第一个啊,那我就肯定往后遍历对不对啊,那我调用PRICE32N来查找它下一个啊,它的参数呢,跟刚才是一致的啊,我们直接填进去就可以了,接下来呢,就干嘛呢,用这个啊来接收它的返回值,什么时候它的返回值为false了啊,就说明已经到最后一个进程了啊,不需要再往下走了啊,它这个循环就会结束,然后就往下走,好那么我们运行一下。
42:13
可以看到啊,我们把当前的进程和进程ID啊,都已经打印出来,循环出来了啊。好,那这个呢,就是今天的一个这个全部内容啊,然后有问题呢,现在呢,可以问一下啊,如果没问题呢,我们就进行下一步。紫禁城你要想知道附近城退出的情况下,你可以有两种方式,一个是呃,就是使用这种便利的方式就可以啊,因为什么呢?因为你可以知道自己的附进程是谁,因为你在你的process ng32的一个结构里是有一个附进程ID的,那么这时候你就可以定期监控啊,然后如果说这个进程ID消失了啊,就说明什么,说明你附进程退出了。
43:32
这种情况其实是比较那个,主要是你这个,如果附近程不是自己啊,就是其他人启动西,你可以这么解释,如果说是你自己写的附进程,其实有更多的方法,比如说他两个之间可以互相的这个监控啊,然后就可以保活啊,就是一个进程死了,另一个进程就把他拉起来这种。
44:06
你也可以用消息处理嘛,如果你自己写的附禁城,你消息处理什么样,你比如说我临死前啊,我这个附近城临死前我就发出一个这个消息啊,给我的这个紫禁城,然后紫禁城接收到啊,我就什么这个处理它,或者说你觉得消息你觉得不太好用,你可以用事件啊,你可以用事件啊,我这边一设置啊,我就知道啊,我父亲能挂了啊,那这时候我一处理啊,这种都是可以的。64位的软件在32位的系统中运行,它的汇编是32还是64的,它运行不了,所以你不用考虑它是32还是64的。32位可以通过这个,呃,可以在这个64位在运行,但是64位是不能在32位上运行的,所以你这种想法是完全没有用的。
45:18
还有问题吗?
46:02
因为什么呢?因为我们在那个WIN64下,它有一个特殊的东西叫V64。啊,有有一个这么一个东西啊,但是32位系统没有一个V32,所以说你处理不了这种东西。在那个在哪儿来着。我给忘了。应该是在Windows system下。我记得好像。32。呃,想不起来了。啊,这事啊,SYSTEM64啊。
47:02
这个这个东西就是处理这个64位下的32位程序的,但是32位下肯它不可能有这个东西,为什么呢?因为你的这个首先你地址宽度就不够。你一个64位的程序,我拍一个64位的一个地址长度,那我在32位上,我这长度怎么存呢?对不对,俩俩俩单元格存一个地址嘛,是不是,所以说呢,它这个东西实现不了啊。我看不了群我打不开啊。我直播的时候没有东西能开群。
48:06
还有问题吗?除了QQ群的QQ群,我现在看不了。状态栏内容的获取是吧?啊,状态栏内容的获取其实还是这个比较好搞的,你只要因为那个东西它是它,它其实就跟那个你你搞一些这个小游戏之类的,其实是类似的啊,它里边存的地方有一个内存空间的地址,你找到那个地址之后,它以后都在那儿。你不需要获取什么控件之类的乱七八糟的东西,你只要知道那条字符咒存哪了就行。
49:06
呃,他不会不定啊,不会不定啊,他肯定是有一个最终的地址,但是如果你没找到的话,是有可能的啊。而且呢,他这个东西如果实在不行的情况下啊,它不是有那个处理的过程嘛,你你就在他那儿那个下个断点,因为你下那个内存内内内存网的断点,你看一下哪个函数写过来的,你不行,你把它上级函数截一下,然后呢,直接他写什么,你就先拦下来,你不就知道是什么了吗。呃,因为它这个无论是去设置某一个,你无论是发消息啊,还是直接用用那个控件去那个设置test呀,这种的,它肯定是有一个操作的过程嘛,它这个不可能说是这个凭空生成的嘛,那么如果说你觉得它内存地址不好找的情况下,你可以去拦它的上级函数啊,因为你已经找他的找到他这个东西了嘛,你可以干嘛对它进行改写了,不是吗?那么这个时候你先搜搜到它的内存地址,然后呢,你下内存访问,然后你等着你去修改它,然后你修改它之后,那还要实时的反馈回来不是吗?还要修改这个状态栏的内容不是吗?那么这个时候它的上级call会掉过来对不对。
50:18
CPP如果写爬虫用HTP好还是ul好?你用C加加写这玩意儿我还真没怎么用过,我用原来用C加加写,我就用原生烧写过啊,用那个TP应该说是我我还我还真不知道这个玩意儿怎么用C加加写好,因为这个东西比较麻烦啊,我通常用Python写。啊,我还有一段时间用Java写排冲,我觉得也挺舒服的啊,但是下加血真的不太舒服。
51:12
自绘窗口找不到?自绘窗口怎么会找不到呢?自绘窗口它不有绘制函数吗?你你像是那个,如果你用D3D绘制的,你就找D3D的绘制函数,你这是直接写的绘制文字啊,还是绘制的那个控件的这个线条啊,还是什么,他肯定有绘制函数。你比如说你如果是WIN32,你用g Di画的,那你就去找那个g Di的函数啊。你如果用I'm gii之类的框架,那更好找了,对不对,那怎么会找不到呢?这个你找他绘制函数。啊,具体东西你就不要问我了,具体东西你就不要问我了,我不好给你回答,你知道吧,你说你问我个思路,我还能告诉你,你问我具体的就不太好了。
52:07
CF加载没图标是因为你的那个,呃,你你准确来说就是权限不够。是那个你的句柄被降权了。你可以写个回调处理一下,然后应该就能看见他的那个图标了。好,完事。
我来说两句