Windows创建的基本含义和进程的进程的内核
过程
1 这意味着过程:
1.1 一个是在操作系统的内核对象管理处理。
的统计信息的地方。
1.2 还有一个是地址空间。它包括全部可运行模块或DL L 模块的代码和数据。它还包括动态内存分配的空间。如线程堆栈和堆分配空间。
2 操作系统启动应用程序的步骤
2.1 调用C/c++执行时的启动函数
启动函数总共4种,WinMainCRTStartup,wWinMainCRTStartup,mainCRTStartup,wmainCRTStartup。
启动函数完毕例如以下任务:
<1>检索指向新进程的完整命令行的指针
<2>检索指向新进程的环境变量的指针
<3>对C/ C + +执行期的全局变量进行初始化。
假设包括了S t d L i b . h 文件。代码就能訪问这些变量
<4>对C执行期内存单元分配函数(m a l l o c 和c a l l o c )和其它低层输入/输出例程使用的内存栈进行初始化。
<5>为全部全局和静态C+ +类对象调用构造函数。
<6>调用入口点函数
如:int nMainRetVal = wmain(__argc, __wargv, _wenviron);
<7>当进入点函数返回时,启动函数便调用C 执行期的ex i t 函数,将返回值(nMainRetVal )传递给它。
<8>调用由_onexit函数的调用而注冊的不论什么函数
<9>为全部全局的和静态的C++类对象调用析构函数
<10>调用操作系统的ExitProcess函数。将nMainRetVal传递给它。
这使得该操作系统可以撤消进程并设置它的e x i t 代码
3 进程的实例句柄
3.1 进程的当前实例句柄
载入到进程地址空间的每一个exe或者dll文件都会被赋予一个独一无二的句柄。
获取载入的模块(exe,dll)的方法:
GetModuleFileName(HMOUDLEhModule,LPTSTR lpFileName,DWROD nSize);
当hModule的值为NULL 的时候。会返回当前调用模块的所有路径名字。
3.2 进程的前一个实例句柄
C++代码总是将NULL赋值给WinMain函数的第二个參数HINSTANCEhPreInstance,这种原因是在16位的程序中对这个參数有保留使用,那么保留它就方便转用16位程序。
4 进程的命令行
LPTSTR GetCommandLine();获取命令行字符串
5 进程的环境变量
每一个进程都有一个与它相关的环境变量块,环境块是进程的地址空间中分配的一个内存块。每一个环境块都包括一组字符串,形式例如以下所看到的:
VarName1=VarValue1\0
VarName2=VarValue2\0
VarName3=VarValue3\0
当中要注意变脸等号前有没有空格。有空格和没空格代表的是全然不同的环境变量,如:
XYZ=xxx;和XYZ =xxx;这就是两个全然不同的环境变量了。
操作华景变量相关的 函数
<1>
LPVOIDGetEnvironmentStrings(VOID);
<2>
BOOL SetEnvironmentVariable(
LPCTSTR lpName, // environment variable name
LPCTSTR lpValue // new value for variable);
<3>
DWORD GetEnvironmentVariable( LPCTSTR lpName, // environment variable name
LPTSTR lpBuffer, // buffer for variable value
DWORD nSize // size ofbuffer);
<4>
BOOL FreeEnvironmentStrings(LPTSTRlpszEnvironmentBlock // environmentstrings);
6 进程的当前文件夹
程序的当前文件夹是能够进行改变的。当前文件夹和进程的启动文件夹是不同的,启动文件夹就是exe或者dll被调用的文件夹,我们能够通过GetModuleFineName函数进行处理。
<1>
DWORD GetCurrentDirectory(
DWORD nBufferLength, //size of directory buffer
LPTSTR lpBuffer //directory buffer);
<2>
BOOL SetCurrentDirectory( LPCTSTR lpPathName // new directory name);
7 系统的版本号信息获得
GetVersion()
可是这个函数有bug,就是程序猿把主版本。次版本放错了高低字节。
BOOL GetVersionEx( LPOSVERSIONINFO lpVersionInfo // versioninformation);
这个是新的修正过来的。
8 创建进程
BOOL WINAPI CreateProcess(
_In_opt_ LPCTSTR lpApplicationName,
_Inout_opt_ LPTSTR lpCommandLine,
_In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes,
_In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
_In_ BOOL bInheritHandles,
_In_ DWORD dwCreationFlags,
_In_opt_ LPVOID lpEnvironment,
_In_opt_ LPCTSTR lpCurrentDirectory,
_In_ LPSTARTUPINFO lpStartupInfo,
_Out_ LPPROCESS_INFORMATION lpProcessInformation
);
參数解释:
<1> lpApplicationName
被载入模块的名字,必须制定模块的格式。比方exe,由于系统不会默觉得exe,模块的名字能够是部门名字,那么系统就会在当前文件夹去寻找该模块。
通常将其设置为NULL。由于lpCommandLine具有比它更加强大的功能来完毕模块的调用。
<2> lpCommandLine
系统寻找可运行文件exe的顺序是:
应用程序载入的文件夹。
父进程的当前文件夹;
Windows System 文件夹;
Windows文件夹。
环境变量列出的文件夹;
注意:当字符集是Unicode时候,參数类型不能是const类型的,若是就会报错。
<3> lpProcessAttributes
指向 SECURITY_ATTRIBUTES的指针,决定进程创建函数返回的的新进程对象的句柄能否被子进程继承。
当为NULL的时候,获取的是默认安全描写叙述符
<4> lpThreadAttributes
指向SECURITY_ATTRIBUTES 的指针,决定进程创建函数范湖的新线程对象的句柄能否被子进程继承。
当为NULL的时候。获取的是默认安全描写叙述符。
<5> bInheritHandles
假设为True。那么不论什么能够被继承的句柄都会别新创建的进程所继承。假设为FALSE。那么则不会被新进程继承。
<6>dwCreationFlags
新创建的进程的创建标志位设置,决定是父子进程调试信息的反馈,子进程窗体的产生等行为。
<7> lpEnvironment
新进程中指向的环境块。假设该值为NULL。那么就表示新进程继承了父进程的环境块。
<8>lpCurrentDirectory
指向新进程的当前文件夹的指针。假设为NULL。那么则就和调用进程(父进程)具有同样的当前文件夹。
<9> lpStartupInfo
指向 STARTUPINFO or STARTUPINFOEX的指针。
主要指定窗体的状态。外观,标准句柄。
当Wi
n d o w s 创建新进程时。它将使用该结构的有关成员。大多数应用程序将要求生成的应用程序只使用默认值。至少应该将该结构中的全部成员初始化为零,然后将cb 成员设置为该结构的大小。
当里面创建的句柄不在是用的使用,要通过CloseHandle来关闭。
<10> lpProcessInformation
指向PROCESS_INFORMATION结构体的指针。
typedef struct _PROCESS_INFORMATION {
HANDLE hProcess;
HANDLE hThread;
DWORD dwProcessId;
DWORD dwThreadId;
} PROCESS_INFORMATION, *LPPROCESS_INFORMATION;
里面是用的句柄不在使用的时候。要通过CloseHandle函数来关闭。
当进程内核对象创建后,系统赋予该对象一个独一无二的标识号。系统中的其它不论什么进程内核对象都不能使用这个同样的ID号。线程内核对象的情况也一样。当一个线程内核对象创建时,该对象被赋予一个独一无二的、系统范围的ID号。进程ID和线程ID共享同样的号码池。
这意味着进程和线程不可能拥有同样的ID 。
9 创建进程的实例:
#include <Windows.h>
#include <iostream>
using namespace std; void main()
{
STARTUPINFO si;
PROCESS_INFORMATION pi; ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
ZeroMemory( &pi, sizeof(pi) ); // Start the child process.
if( !CreateProcess( NULL, // No module name (use command line).
TEXT("Notepad++"), // Command line.
NULL, // Process handle not inheritable.
NULL, // Thread handle not inheritable.
FALSE, // Set handle inheritance to FALSE.
0, // No creation flags.
NULL, // Use parent's environment block.
NULL, // Use parent's starting directory.
&si, // Pointer to STARTUPINFO structure.
&pi ) // Pointer to PROCESS_INFORMATION structure.
)
{
cout<<TEXT("CreateProcess failed.");
} // Wait until child process exits.
WaitForSingleObject( pi.hProcess, INFINITE ); // Close process and thread handles.
CloseHandle( pi.hProcess );
CloseHandle( pi.hThread );
}
版权声明:本文博客原创文章,博客,未经同意,不得转载。
Windows创建的基本含义和进程的进程的内核的更多相关文章
- linux进程解析--进程的创建
通常我们在代码中调用fork()来创建一个进程或者调用pthread_create()来创建一个线程,创建一个进程需要为其分配内存资源,文件资源,时间片资源等,在这里来描述一下linux进程的创建过程 ...
- Linux下进程的创建过程分析(_do_fork do_fork详解)--Linux进程的管理与调度(八)
Unix标准的复制进程的系统调用时fork(即分叉),但是Linux,BSD等操作系统并不止实现这一个,确切的说linux实现了三个,fork,vfork,clone(确切说vfork创造出来的是轻量 ...
- python全栈开发 * 进程理论 进程创建 * 180724
一.进程理论 1.进程是资源分配的最小单位. 2.进程调度就是多个进程在操作系统的控制下被CPU执行,去享用计算机的资源. 先来先服务 短作业优先 时间片轮转 多级反馈队列 3.进程调度的过程是不能够 ...
- windows Service 之调试过程(附加到进程里调试,而且启动时间不能超过30秒)
最近第一次用C#写了一个windows service ,其实实现的内容比较简单.就是启动remoting 连接,但是调试相对初次写windws service 的我来说,比较烦.没有经验,而且没办法 ...
- Windows中利用共享内存来实现不同进程间的通信
Windows中利用共享内存来实现不同进程间的通信 一.msdn详细介绍 https://docs.microsoft.com/zh-cn/windows/win32/memory/sharing-f ...
- 【说解】在shell中通过mkfifo创建命名管道来控制多个进程并发执行
背景: 工作中有两个异地机房需要传数据,数据全名很规范,在某个目录下命名为统一的前缀加上编号.如/path/from/file.{1..100}.而机房间的专线对单个scp进程的传输速度是有限制的,比 ...
- Windows创建自动化任务
Windows创建自动化任务使得开机就打开相应的Python目录 1:计算机管理 2:找到任务计划程序 3:创建基本任务 4:任务触发器 5: 建立bat执行文件 start "" ...
- linux 进程(二) --- 进程的创建及相关api
一.进程的创建fork()函数 由fork创建的新进程被称为子进程(child process).该函数被调用一次,但返回两次.两次返回的区别是子进程的返回值是0,而父进程的返回值则是 新子进程的进 ...
- Linux进程-进程的创建
今天学习了Linux的进程创建的基本原理,是基于0.11版本核心的.下面对其作一下简单的总结. 一.Linux进程在内存中的相关资源 很容易理解,Linux进程的创建过程就是内存中进程相关资源产生 ...
随机推荐
- Django Form Media 阅读笔记
---恢复内容开始--- Form Media Rendering an attractive and easy-to-use Web form requires more than just HTM ...
- 数据库关于group by 两个或以上条件的分析
首先group by 的简单说明: group by 一般和聚合函数一起使用才有意义,比如 count sum avg等,使用group by的两个要素: (1) 出现在select后面的 ...
- Android画图监听接口OnPreDrawListener具体解释
public static interface ViewTreeObserver.OnPreDrawListener 我们先看下API中的定义: 类概述: 为即将绘制视图树时运行的回调函数定义的接口. ...
- SCSI miniport 驾驶一个简单的框架
前段时间,只需用一台新电脑,由于资金有限没有匹配了心仪已久的SSD.我没感觉到飞翔的感觉,总不甘心,仔细想想.我死了相当大的存储,我们可以假设部分内存作为硬盘驱动器把它弄出来.不会比固态硬盘的速度快, ...
- Oracle JDBC版本区别(转)
oracle\product\11.2.0\dbhome_1\jdbc\lib ojdbc5.jar ojdbc5dms.jar ojdbc5dms_g.jar ojdbc5_g.jar ojdbc6 ...
- Unity3D之挥动武器产生的剑痕特效
网维教程网 观看很多其它教程 眼下已知3种方法能够做这样的剑痕特效 1.尾随特效 2.程序实现动态面来处理剑痕动画. 3.美术实现剑痕动画,直接坐在模型动画里面 (由于我不会美术所以这个忽略 嘿嘿) ...
- Kinect的学习笔记发展(一)Kinect引进和应用
Kinect的学习笔记发展(一)Kinect引进和应用 zouxy09@qq.com http://blog.csdn.net/zouxy09 一.Kinect简单介绍 Kinectfor Xbox ...
- android一些面试题目
1.ListView怎么提高滑动效率 2.说下你做过项目的包的构架,(联网,解析,activity,database) 重点 3.载入大量图片怎么做(包含小图和查看大图) 怎么降低一次跟server的 ...
- 垂死或涅槃重生 -- Delphi XE5 我们将宣布感情的回归
Delphi 在很大程度上是一个被遗忘我的工具. 无论是在使用RapidSql , 我还没有收到Embarcadero 本公司发行参与邀请Delphi XE5该公告将. 可能有人会问,为什么Embar ...
- [状压dp] hdu 4064 Carcassonne
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4064 Carcassonne Time Limit: 3000/1000 MS (Java/Othe ...