windows核心编程心解--进程相关

总述,系统如何管理正在运行的所有应用程序。

1、进程解释:

正在运行的一个程序的一个实例定义为进程。

进程一般包含两部分:

*一个内核对象,操作系统用它来管理进程,同时也是操作系统保存进程统计信息的地方。

*一个地址空间,其中包含所有可执行文件或者dll模块的代码和数据。同时也包含动态内存分配,比如线程堆栈和堆的分配。

进程要做一件事情的时候,其实不是进程在做,而是只要进程一旦创建,就会随之立刻创建一个线程,这个线程通常就叫主线程,其他的事情,或者说真正需要做的事情都有这个线程来做,包括创建更多的线程,或者执行地址空间中的代码。当然每个线程都有自己的独有的cpu寄存器和堆栈,操作系统通过轮询方式为每个线程分配时间片,达到所有线程同时执行的假象。

 

2、windows应用程序:

windows支持两种类型的应用程序,GUI和CUI程序。两者界限比较模糊。只是通过vs来创建的时候会有不同的链接器开关。同时CUI不很友好界面。链接器开关不同,链接器

就会寻找正确的入口函数,如果找不到入口函数,就提示无法解析的外部命令错误。当出现这种链接错误时,可以解决办法:配置属性—链接器—系统—子系统,更改链接器开

关。同时更改使用字符集。

可以在crtexe.c中找到c入口函数的源代码。

入口函数返回后,启动函数将调用c运行库函数exit。

 

3、进程实例句柄:

加载到进程地址空间的每一个可执行文件或者dll文件都被赋予了一个唯一的实例句柄。可执行文件的实例被当做WinMain函数的第一个参数hIinstanceExe传入,这个参数实际

值是一个内存基地址,系统将可执行文件的映像加载到进程地址空间的某个位置。可以通过函数GetModuleHandle来检查主调进程的地址空间得到具体的这个位置。当然GetModuleHandle函数还可以返回主调进程的可执行文件的基地址。

比如函数LoadIcon和函数GetModleFileName的第一个参数HMODULE和HINSTANCE两种类型是完全一样的,这里写的不一样是为了兼容16位的windows系统。这个参数包含了那个唯一的实例句柄。

 

 4、进程的命令行:

系统在创建一个新的进程的时候,都会传一个命令行给这个新的进程。

首先,在任何情况下,写入缓冲区的是时候都不应该越界。

也可以这样通过函数GetCommandLine来得到一个缓冲区的指针,缓冲区中包含了完整的命令行。

利用在ShellAPI.h文件中声明并在Shell32.dll导出的函数CommandLineToArgvW,即可以将任何Unicode字符串分解成单独的标记,(有待于理解什么意思)

 

5、进程的环境变量

每一个进程都有一个与它相关联的环境块,这是在进程地址空间中分配的一块内存。

有两种办法访问这个环境块,第一就是通过函数GetEnvironmentString来获取完整的环境块。使用这个函数完成后要记得用Free*函数释放。

                                                    第二就是CUI程序独有,通过main入口函数的参数env来得到。

通常,子进程会继承一组和父进程一样的环境变量的副本。不是共享同一个。

 对环境变量的操作有三个函数,GetEnvironmentVariable函数可以判断预期的环境变量是否存在。

                                                         执行字符串替换的函数ExpandEnvironmentStrings函数。

                                                         可以使用SetEnvironmentVariable函数添加、删除和修改一个变量的值。

 

6、进程的错误模式:

默认情况下,子进程会继承父进程的错误模式标志。但是也可以通过创建子进程的时候通过参数设置不让子进程来继承父进程(自己)的错误模式。

进程可以调用函数SetErroMode来告诉系统如何处理这些个错误。

 

 7、进程当前所在的驱动器和目录

如果不提供完整的路径名,各种windows函数会在当前驱动器的当前目录查找文件和目录。

一个线程可以调用以下两个函数来获取和设置其所在进程的当前驱动器和目录

GetCurrentDirectory函数和SetCurrentDirectory函数

操作系统会跟踪记录着当前进程的驱动器和目录,把这些信息保存在进程的环境块的环境变量中。

 如果调用一个函数传入的路径名不是当前进程的驱动器,那么系统会在进程的环境块中查找,是否存在这个传入的驱动器,若果有,系统就把变量的值当做当前目录使用,如

果没有找到,系统就假定指定的驱动器的当前目录是它的根目录。

windows的文件函数从来不会添加或者更改驱动器号环境变量,它只是读取这个变量。也可以使用c运行库函数_chdir来更改当前目录,从而使不同驱动器的当前目录得以保留。

通常情况下,子进程会继承父进程的环境块,如果父进程想专门给子进程单独的环境变量,那么父进程就要在创建子进程之前,创建驱动器的环境变量并写入环境块,父进程可以调用函数GetFullPathName来得到它的当前目录。

 

8、系统版本:

可以通过函数GetVersionEx得到系统版本号的相关内容,其中的参数是一个比较复杂的结构体参数;

可以通过函数VerifyVersionInfo来比较主机系统的版本和要求的版本是不是一样。

 

9、CreateProcess函数

10、终止进程:

终止进程方法有4种,

第一:主线程的入口点函数返回

第二:进程中的一个线程调用ExitProcess函数,当然也有ExitThread函数来结束线程。这两种方式都有一定的隐患,前一个函数会导致清理不能正常,第二个函数会导致内存

泄露。

第三:任何线程都可以调用函数TerminateProcess,这个函数可以终止另一个进程或者自己的进程。

            这个函数是异步执行的(这是什么意思?),为了确定进程是否已经终止,需要调用WaitForSingleObject函数来捕捉。

 

11、当进程中的所有线程终止时:

当操作系统得知一个进程中没有任何一个线程在执行时,就会结束这个进程的存在,进程的推出代码被设为最后一个终止的那个线程的退出代码。

 

12、当进程终止运行时:

进程终止运行时,系统会做一些清理和释放和统计计数的工作,总之,这么说,进程创建内核对象,内核对象来管理进程的运行机制,进程的结束是这个进程本身下面还有没有线程执行地址空间中的代码,而内核对象的结束是使用计数是不是0.

可以通过函数GetExitCodeProcess来获得已经终止的一个进程的退出代码。这个函数可以在任何时候使用来监测一个进程是否结束。

 

13、子进程:

设计应用程序时候遇到的工作执行机制:

第一:调用函数或者调用子程序,这样就是所谓的单任务同步机制。

第二:可以在进程里面新创建一个线程,让这个线程来做一定的工作,这就是所谓的异步机制。

第三:可以新生成一个子进程,让这个子进程来做一定的工作,这个就是所谓的既可以是同步也可以是异步机制,但是好处是,工作期间可以保护主进程的地址空间。

           这里就涉及到一个问题,就是所谓的不同进程之间传递数据的方法。windows提供了这些,动态数据交换(DDE)、OLE、管道、邮件槽等。其中还有共享数据最方便的方式之一就是使用内存映射文件。

            这里又涉及到几个函数,WaiteForSingleObject函数,这个函数会一直等,直到他本身的第一个参数所标识的对象变为已触发,进程在终止的时候就会变为已经触发。

             还有这里,良好的编程习惯,在CreateProcess创建子进程返回后,就立刻关闭(其实不是关闭,只是使用CloseHandle函数)子进程的主线程的句柄。

 

14、独立运行子进程:

独立运行的意思是,一旦进程创建并开始执行,父进程和子进程就不再有任何通信,就是毫无关系。比如windows资源管理器就是这样。

为了达到这样的独立运行效果,就是一旦创建成功后,立刻关闭这个进程和主线程的句柄。

 

15、用户以标准用户权限运行时:(不是很理解,有待补充)

16、自动提升进程的权限:

关于自动提升用户的权限有三种方法可以使用:

第一:向可执行文件中嵌入清单文件(RT_MANIFEST),系统会自动检查清单文件中的有效字段。

第二:将清单保存在可执行文件同级目录下面,后缀名为.manifest

第三:手动在可执行文件的属性里面,下面有兼容性里面可以设置。

 

17、手动提升进程的权限:

可以通过函数ShellExecuteEx来设置。

18、当前权限上下文:

在这里使用函数GetProcessElevation能够返回提升类型和一个指出进程是否正在以管理员身份运行的bool值。

19、枚举系统中正在运行的进程:

关于枚举正在运行的进程,有几个函数可以使用:

第一:windows NT开发团队,开发了EnumProcesses函数,包含在PSAPI.dll中。

第二:ToolHelp API中 Process32First和Process32Next函数。

20、Process Information示例程序

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值