Windows程序设计零基础自学_7_进程操作
哈哈, 今天看书看到了内核对象的进程一章,原来以为进程会很难,结果发现如果用心学习的话
其实也不是很难。嘻嘻我指的不难是入门不难,但是要是要完全掌握甚至精通的话还是相当的有难度的,光
那些什么内核对象的继承特性和什么内核对象句柄表就够让人头疼疼了。
下面我们弄一段娱乐代码来看看如何操作进程:
// 01FirstAPP.cpp : Defines the entry point for the console application.// #include "stdafx.h"#include <windows.h> #include <stdio.h>#include <string.h> STARTUPINFO startupinfo;//extern unsigned int _winver; int main(int argc, char* argv[]){int iSelect; iSelect=::MessageBox(NULL,"Hello world!","Wellcome",MB_OKCANCEL); if(IDOK==iSelect) printf("You have select OK\n");else printf("You have select cancel\n"); startupinfo.cb=sizeof(STARTUPINFO);//::GetStartupInfo(&startupinfo); PROCESS_INFORMATION pi; /* char lpCurrentDirectory[100]; GetCurrentDirectory(100,lpCurrentDirectory); if(strlen(lpCurrentDirectory)< (100-10) ) strcat(lpCurrentDirectory,"01FirstAPP");*/ //这里可以用GetCommandline来获取应用程序的路径 char *szCommandLine="01FirstAPP.exe"; startupinfo.wShowWindow=SW_SHOWMINNOACTIVE;//在调用windows API函数时需要弄明白MSDN中那些 IN 和 OUT 的意义。表示的意义 ::CreateProcess(NULL,szCommandLine,NULL,NULL,FALSE,NULL,NULL,NULL,&startupinfo,&pi); // UINT Exit_hAndle; if(IDOK==MessageBox(NULL,"You want exit notepad ?","Ask for information",MB_OKCANCEL)) TerminateProcess(pi.hProcess,0);else CloseHandle(pi.hProcess); char *pcmdline=::GetCommandLine(); puts(pcmdline); //获取应用程序的当前工作路径 char pdir[100]; ::GetCurrentDirectory(100,pdir); puts(pdir); //获取操作系统的版本号//高字节返回系统的 printf("%d\n",::GetVersion()); printf("%8X\n",::GetVersion()); //通过扩展函数获取系统版本号 OSVERSIONINFO osversioninfo; osversioninfo.dwOSVersionInfoSize=sizeof OSVERSIONINFO; ::GetVersionEx(&osversioninfo); printf("os major version is %ld\n",osversioninfo.dwMajorVersion); printf("%p",GetModuleHandle(NULL)); //输出应用程序进程加载到内存空间是的基址。 这个值在GUI中是程序的hInstance句柄。 // printf("%d",_winver); printf("\nHello World!\n"); getc(stdin);return 0;}
我学C语言一直以来有个疑问,既然非main函数需要通过main函数直接或者间接的来调用,
而main也是一个函数? 那么在应用程序启动的时候main函数是否也要被调用呢? 如果需要那么是
一个怎么样的机制呢? 如果不需要那么是否和函数需要被调用有点矛盾呢?这个问题从2006年春天
接触C语言以来就一直困扰着我,终于今天我明白了,main函数也需要被调用。
1、启动函数
win下编译程序的时候并不决定C程序将如何执行,而是在链接的过程中决定C程序如何开始执行。
我们知道在win下主要定义了4个入口点函数, 就是通常说的entry point。
他们分别是:
控制台应用程序(CUI): mian 和 wmain
窗口应用程序(GUI): WinMain 和 wWinMain (嘻嘻, 原型就不写了)
我们知道在编译完成后会生成obj文件(记得好像应该是COFF格式的,好像谭的书上说过,
这个应该没错), 然后通过链接程序LINK 上系统库文件最终生成exe或者其他PE格式的可执行
文件。 在链接的过程,以前我就知道会连接printf这样的库函数,不知道在这个阶段会做一些与
函数启动执行相关的事情。
当应用程序被链接的时候,会被嵌入可执行的启动函数到要生成的可执行文件, 在win下有4个
启动函数:
控制台两个: mainCRTStartup 和 wmainCRTStartup
窗口应用程序: WinMainCRTStartup 和wWinMainCRTStartup
这两组启动函数可以通过链接程序开关来指定,也可以在IDE环境进行指定。
cmd形式需要指定:
/SUBSYSTEM:WINDOWS 开关指定链接 WinMainCRTStartup 和wWinMainCRTStartup
/SUBSYSTEM:CONSOLE开关指定链接 mainCRTStartup 和 wmainCRTStartup
(注: 带前缀w和不带w区别编译ANSI兼容和Unicode兼容代码,w表示支持宽字符语言)
2、启动函数的作用
1、检索指向新进程的完整的命令行指针
2、检索指向新进程环境变量的指针
3、对C运行期的全局变量进行初始化
4、初始化内存单元分配函数和其他低层输入输出函数使用的栈
5、为应用程序的全局对象分配内存空间
当完成这些工作后就会以大体下面的形式来调用入口点函数:
GetStartupInfo(&startupinfo); //startupinfo 为一个STARTUPINFO结构体
int nMainRetVal=main(__argc,__argv,_environ);
这与我们的
int main(int argc, char **argv)的原型基本相似, 只不过在win下main函数可以需要一个
_environ环境变量参数, _environ不是从命令行串口输入的,而是系统检测的。
当main函数或者winmain函数返回时,通常用return 0;或者 return msg.wParam;
启动函数会利用就调用C运行期函数exit,将返回值nMainRetVal传递给exit函数,就像下面这
样:
GetStartupInfo(&startupinfo); //startupinfo 为一个STARTUPINFO结构体
int nMainRetVal=main(__argc,__argv,_environ);
/*
** main函数代码或其直接、间接调用的代码
*/
exit(nMainRetVal);
3、进程的建立
如果在windows资源管理器里面启动一个应用程序,这个过程其实就涉及到了进程的建立过程。
Explorer.exe 通过调用下面类似的代码来启动应用程序:
char *szCommandLine="01FirstAPP.exe"; startupinfo.wShowWindow=SW_SHOWMINNOACTIVE;//在调用windows API函数时需要弄明白MSDN中那些 IN 和 OUT 的意义。表示的意义 ::CreateProcess(NULL,szCommandLine,NULL,NULL,FALSE,NULL,NULL,NULL,&startupinfo,&pi);
主要是CreateProcess函数来创建进程,至于这个函数的用法,这里就不多说了,当然为了防止
资源管理器的内存泄露,可能在资源管理器进程里面会调用:
CloseHandle(pi.hProcess);
通过上面的函数来是内核对象引用计数进行减1操作, 当内核对象的引用计数==0 的时候操作系统就会
回收内核对象占用的系统资源。嘻嘻,进程也是一种内核对象,很神奇吧,内核对象根本不是很神秘,在
taskmgr中就可以看到内核对象。
至于其他的关于进程的信息,还是慢慢看书吧,还是挺有意思的..............
4、 如何防止应用程序启动两个应用实例
在VB中可以通过APP全局对象来实现这个功能,在Delphi中也可以通过application全局对象来
实现这个功能,而在C语言中,因为WinMain函数接收的第二参数hPrevInstance参数总是NULL,就需要
利用其他方法来实现这个功能,可以通过创建一个系统可见的内核对象来实现这个功能。
例如可以利用互斥对象实现,也可以通过内存映射文件实现。
具体代码就不写了,反正大家都会...............
嘻嘻嘻.............
转载于:https://www.cnblogs.com/volcanol/archive/2011/09/09/2172882.html
Windows程序设计零基础自学_7_进程操作相关推荐
- 视频教程-2020新版C语言程序设计零基础入门小白自学编程-C/C++
2020新版C语言程序设计零基础入门小白自学编程 7年的开发架构经验,曾就职于国内一线互联网公司,开发工程师,现在是某创业公司技术负责人, 擅长语言有node/java/python,专注于服务端研发 ...
- 非零基础自学计算机操作系统 第1章 操作系统概述 习题一
非零基础自学计算机操作系统 第1章 操作系统概述 习题一 [1]什么是操作系统?操作系统有哪些特性? 答:操作系统是管理计算机硬件与软件资源的计算机程序,它的主要特性有并发性.易用性.稳定性和异步性. ...
- 非零基础自学计算机操作系统 第1章 操作系统概述 1.4 操作系统的分类 1.4.1 多道批处理操作系统 1.4.2 分时操作系统
非零基础自学计算机操作系统 文章目录 非零基础自学计算机操作系统 第1章 操作系统概述 1.4 操作系统的分类 1.4.1 多道批处理操作系统 1.4.2 分时操作系统 第1章 操作系统概述 1.4 ...
- 零基础学python用什么书-零基础自学python3 好用的入门书籍推荐
零基础自学python3 好用的入门书籍推荐,博学谷小班整理了六本数,推荐阅读 <Python for data analysis>.<Python数据分析与挖掘实战>.< ...
- python3入门书籍-零基础自学python3 好用的入门书籍推荐
零基础自学python3 好用的入门书籍推荐,博学谷小班整理了六本数,推荐阅读 <Python for data analysis>.<Python数据分析与挖掘实战>.< ...
- 零基础学python用哪本书好-零基础自学python3 好用的入门书籍推荐
零基础自学python3 好用的入门书籍推荐,博学谷小班整理了六本数,推荐阅读 <Python for data analysis>.<Python数据分析与挖掘实战>.< ...
- 小猿圈Linux零基础自学之路
对于不是科班出身的IT从业者,其实刚开始学习是很难的,特别是没有人带的时候,有时候一个问题可以困扰你几天甚至几周,小猿圈Linux讲师给大家讲一个linux学员的自学之路,希望对大家有所启发. 对于L ...
- 大数据自学要多久?为什么零基础自学大数据那么久?
伴随着大数据时代的冲击,大数据开发相关的技术人才成为目前招聘市场炙手可热的高薪岗位,越来越多想要通过技术获得高薪工作的同学选择大数据技术方向.我们知道目前学习大数据可以通过自学或者参加培训两种方式,参 ...
- html带颜色表格怎么做,使用HTML添加表格4(行颜色与表格嵌套)——零基础自学网页制作...
行颜色设置的简便方法 使用HTML添加表格4(行颜色与表格嵌套)--零基础自学网页制作 昨天我们在<使用HTML添加表格3(间距与颜色)--零基础自学网页制作>(目录在结尾)中学习了设置单 ...
最新文章
- Nsight Compute Profilier 分析
- Maya基础入门学习教程
- Delphi实现WebService带身份认证的数据传输
- 教你C语言实现通讯录的详细代码
- 第十六章 tcp_wrappers
- 通过仿真和综合认识JK触发器(Verilog HDL语言描述JK触发器)
- 为什么链接库的顺序有时会导致GCC错误?
- JavaWeb第五讲 Web核心基础之HTTP协议
- 深入浅出之正则表达式(二)(转载)
- c++ 向量的值逆序输出_C++中vector的常用方法
- [IoC容器Unity]第三回:依赖注入
- java和python哪个学习编程_初学编程,选Java还是Python?
- windows无法确定此计算机是否包含,服务器用U盘虚拟光驱装系统,有做RAID5,加载RAID驱动成功后,安装到最后会报“windows无法确定此计算机是否包含有效系统卷”错误...
- (转)MyBatis框架的学习(二)——MyBatis架构与入门
- WordPress如何开启用户注册功能
- 395.至少有K个重复字符的最长子串
- 云计算就业方向有哪些 未来的发展前景怎么样
- C# AES填充加密解密
- STorM32 BGC 相关
- SMB服务搭建与访问