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 nameLPCTSTR lpValue // new value for variable);
<3>
DWORD GetEnvironmentVariable( LPCTSTR lpName, // environment variable nameLPTSTR lpBuffer, // buffer for variable valueDWORD nSize // size ofbuffer);
<4>
BOOL FreeEnvironmentStrings(LPTSTRlpszEnvironmentBlock // environmentstrings);
6 进程的当前文件夹
程序的当前文件夹是能够进行改变的。当前文件夹和进程的启动文件夹是不同的,启动文件夹就是exe或者dll被调用的文件夹,我们能够通过GetModuleFineName函数进行处理。
<1>
DWORD GetCurrentDirectory(DWORD nBufferLength, //size of directory bufferLPTSTR 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 );
}
版权声明:本文博客原创文章,博客,未经同意,不得转载。
转载于:https://www.cnblogs.com/blfshiye/p/4643359.html
Windows创建的基本含义和进程的进程的内核相关推荐
- Go 学习笔记(44)— Go 标准库之 os(获取文件状态、获取/修改文件权限、创建、删除目录和文件、获取进程ID、设置获取环境变量)
1. 概述 os 包提供了操作系统函数的不依赖平台的接口.失败的调用会返回错误值而非错误码.通常错误值里包含更多信息.例如,如果某个使用一个文件名的调用(如Open.Stat)失败了,打印错误时会包含 ...
- widnows命令行常用命令使用 和 windows创建文件,写内容到文件
widnows命令行常用命令使用 和 windows创建文件,写内容到文件 1 查看windows命令行常用命令的使用文档 1.1 查看windows中命令行命令 1.2 windows查看某个指定命 ...
- potplayer 多个进程_进程组、会话、控制终端概念,如何创建守护进程?
守护进程 概念: 守护进程,也就是通常所说的Daemon进程,是Linux中的后台服务进程.周期性的执行某种任务或等待处理某些发生的事件. Linux系统有很多守护进程,大多数服务都是用守护进程实现的 ...
- linux 下的进程创建线程,Linux线程 之 线程 线程组 进程 轻量级进程(LWP)
线程是有栈的,我们知道,普通的一个进程,它的栈空间是8M,我们可以通过ulmit -a查看: stack size (kbytes, -s) 8192 线程也不例外,线程也是需要栈空间的这句话是废话, ...
- Linux-进程控制详解(进程创建+进程终止+进程等待+进程程序替换)
Linux进程控制 1. 进程创建 1.1 fork 1.2 vfork 2. 进程终止 3. 进程等待 3.1 为什么要进程等待 3.2 wait 3.3 waitpid 3.4 获取子进程退出信息 ...
- 【Linux】进程控制 —— 进程创建/终止/等待
目录 一.进程创建 1.fork创建子进程,操作系统做了什么? 2.fork的用法以及失败的原因 二.进程终止 1.三种退出情况 2.main函数为什么一般情况下都要return 0 3.进程的退出码 ...
- 小实验:用创建进程()打开计算器,然后关闭进程句柄。再用打开进程(进程ID),使用两次,得到两个进程句柄。实验目的:这两个进程句柄都能控制这个进程吗?通过该试验加深对句柄的理解!!...
小实验:用创建进程()打开计算器,然后关闭进程句柄.再用打开进程(进程ID),使用两次,得到两个进程句柄.实验目的:这两个进程句柄都能控制这个进程吗? .版本 2 .程序集 窗口程序集1 .子程序 _ ...
- Linux进程-进程的创建
今天学习了Linux的进程创建的基本原理,是基于0.11版本核心的.下面对其作一下简单的总结. 一.Linux进程在内存中的相关资源 很容易理解,Linux进程的创建过程就是内存中进程相关资源产 ...
- linux创建多个子进程,[Linux进程]使用fork函数创建多个子进程
#include #include int main (void) { pid_t pid1,pid2; //进程标识符 pid1 = fork(); //创建一个新的进程 if(pid ...
最新文章
- 美国新规:自动驾驶车,从此不需要驾驶位了
- VSS admin用户忘记密码的解决方法
- 面试:从volatile说到i++的线程安全问题
- CentOS下开启配置端口转发
- 算法图解第四章笔记与习题(快速排序)
- php针式打印机打多张,如何将多页内容打印在一张A4纸上
- corpus iweb_智能网络语料库iWeb及其在英语教学中的应用
- mysql数据狛聘_.net 生成拼音码与五笔码实例代码
- 主编编辑器如何设置我的签名?
- 观远数据带你乘云驾“务”,让决策更智能
- 【编程不良人】SpringSecurity实战学习笔记04---RememberMe
- P68-70 王者荣耀
- vue 监听input停止输入后发送请求
- 一样的操作,同样的引入,爆红:can’t resolve symbol
- Apache实现盗链与防盗链与隐藏版本信息
- 全国计算机一级第七套试题及答案,计算机一级考试第七套试卷及答案.doc
- 用户交互设计10个可用性指标
- 分析自动化测试收益_分析自动化测试结果
- boss直聘zp_stoken逆向分析源码放送
- MPEG音频编码实验