Windows进程机制

news2024/11/14 4:19:44

进程

进程要做任何事情,必须让一个线程在它的上下文运行。该线程负责执行进程地址空间包含的代码。每个进程至少要有一个线程来执行进程地址空间包含的代码。当系统创建一个进程的时候,会自动为进程创建第一个线程,这称为主线程(primary thread)。

对于所有要运行的线程,操作系统会轮流为每个线程调度一些CPU时间。会采取round-robin的方式。

两部分

一个内核对象

一个地址空间

Windows程序

Windows支持两种类型的应用程序:GUI程序和CUI程序。前者是图形用户界面,后者是控制台用户界面。这两种应用程序的界限是模糊的。

用Microsoft Visual Studio来创建一个应用程序项目的时候,继承开发环境会设置各种链接器开关。

对于CUI程序,这个链接器开关是/SUBSYSTEM:CONSOLE

对于GUI程序,这个链接器开关是/SUBSYSTEM:WINDOWS

操作系统的加载程序会检查可执行文件映像的文件头,并获取这个子系统值。如果此值表明是一个CUI程序,加载程序会自动确保有一个可用的文本台窗口,如果此值表明是一个GUI程序,加载器就不会创建控制台窗口。

Windows程序必须有一个入口点函数,应用程序开始运行时,这个函数会被调用。

C/C++采用下面两种入口点函数

Int WINAPI_tWinMain(
    HINSTANCE hInstanceExe,
    HINSTANCE,
    PTSTR pszCmdLine,
    int nCmdShow);


int _tmain(
    int argc,
    TCHAR *argv[],
    TCHAR *envp[]);

具体的符号取决于是否使用Unicode字符串,操作系统并不调用入口点函数。相反,它会调用C/C++运行库并在链接时使用-entry:命令行选项来设置的一个C/C++运行时启动函数。该函数将初始化C/C++运行库,使我们能调用malloc和free之类的函数。还确保了在我们的代码开始执行之前,我们声明的任何全局和静态C++对象都被正确的构造。

应用程序类型入口点函数(入口)嵌入可执行文件的启动函数
处理ANSI字符和字符串的GUI应用程序_tWinMain(Winmain)WinMainCRTStartup
处理Unicode字符和字符串的GUI应用程序

_tWinMain(w

Winmain)

wWinMainCRTStartup
处理ANSI字符和字符串的CUI应用程序_tmain(Main)mainCRTStartup
处理Unicode字符和字符串的CUI应用程序

_tmain(Wmain)

wmainCRTStartup

所有C/C++运行库启动函数所做的事情基本都是一样的,区别在于它们要处理的是ANSI字符串还是Unicode字符串,在初始化C运行库之后,它们调用的是哪一个入口点函数。Visual C++自带C运行库的源代码。可以在crtree.c文件中找到4个启动函数的源代码。

用途如下:

  1. 获取指向新进程的完整命令行的一个指针
  2. 获取指向新进程的环境变量的一个指针
  3. 初始化C/C++运行库的全局变量。如果包含了StdLib.h,我们的代码就可以访问一些变量
  4. 初始化C运行库内存分配函数和其他I/O例程使用的堆
  5. 调用所有全局和静态C++类对象的构造函数

完成这些初始化工作之后,C/C++程序就会调用应用程序的入口点函数。

调用过程如下

GetStartupInfo(&StartupInfo);
int nMainRetVal=&WinMain((HINSTANCE)&_ImageBase,NULL,pszCommandLineUnicode,(StartupInfo.dwFlags&STARTF_USESHOWWINDOW)?StartupInfo.wShowWindow:SW_SHOWDEFAULT);

_Image是操作系统定义的一个伪变量,表明可执行文件被映射到应用程序内存中的什么位置。

进程实例句柄

加载到进程地址空间的每一个可执行文件或者DLL文件都被赋予了一个独一无二的实例句柄。可执行文件的实例句柄。可执行文件的实例被当作(w)WinMain函数的第一个参数hInstanceExe传入。在需要加载资源的函数调用中,一般都要提供此句柄的值。例如,为了从可执行文件的映像中加载一个图标资源,就需要调用下面这个函数:

HICON LoadIcon(
    HINSTANCE hInstance,
    PCTSTR pszIcon);

LoadIcon函数的第一个参数指出哪个文件包含了想要加载的资源。许多应用程序都会将(w)WinMain的hInstanceExe参数保存在一个全局变量中,使其很容易被可执行文件的所有代码访问。

hInstanceExe参数的实际值是一个内存基地址,系统将可执行文件的映像加载到进程地址空间中的这个位置。例如,假如系统打开可执行文件,并将它的内容加载到0x00400000,则w(WinMain)的hInstanceExe参数值为0x04000000。

可执行文件的映像具体加载到哪一个基地址,是由链接器决定的。不同的链接器使用不同的默认基地址。Visual Studio链接器使用的默认基地址是0x00400000,这是在运行Windows 98时,可执行文件的映像能加载到的最低的一个地址。使用Microsoft链接器/BASE:address链接器开关,可以更改要将应用程序加载到哪个基地址。

为了知道一个可执行文件或DLL文件被加载到进程地址空间的什么位置,可以使用GetModuleHandle函数来返回一个句柄/基地址

HMUDULE GetModuleHandle(PCTSTR pszModule);

调用这个函数时,要传递一个以0为终止符的字符串,它指定了已在主调进程的地址空间中加载的一个可执行文件或DLL文件的名称。如果系统找到了指定的可执行文件或DLL文件名称,GetModuleHandle就会返回可执行文件DLL文件映像加载到的基地址。

进程的命令行

系统在创建一个新进程时,会传一个命令行给它。这个命令行几乎总是非空的

用于创建新进程的可执行文件的名称是命令行上的第一个标记(token)

C运行库的启动代码开始执行一个GUI应用程序时,会调用Windows函数GetCommandLine来获取进程的完整命令行,忽略可执行文件的名称,然后将指向命令行剩余部分的一个指针传给WinMain的pszCmdLine函数

应用程序可以通过自己选择的任何一种方式来分析和解释命令行字符串。

进程的环境变量

每个进程都有一个与它关联的环境块,这是在进程地址空间内分配的一块内存,其中包含字符串和下面类似:

可以使用GetEnvironmentStrings函数来获取完整的环境块。

用户登录Windows时,系统会创建shell进程,并将一组环境字符串与其关联。

系统通过检查注册表中的两个注册表项来获得初始的环境字符串。

第一个注册表包含应用于系统的所有环境变量的列表:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment

第二个注册表项包含应用于当前登录用户的所有环境变量的列表

HKEY_CURRENT_USER\Environment

用户可以添加,删除或更该这些环境变量,具体做法是从Control Panel中选择System,然后单击Advanced System Settings,然后点击Environment Variable按钮。

要有管理员权限才能更改system variable列表中包含的变量

应用程序还可以使用各种注册表函数来修改这些注册表项

但是为了使改动对所有应用程序生效,用户必须注销并重新登录,有的应用程序在其主窗口接收到WM_SETTINGCHANGE消息时,用新的注册表来更新它们的环境块。

通常,子进程会继承一组环境变量,这些环境变量和父进程的环境变量相同。不过,父进程可以控制哪些环境变量允许子进程继承。子进程和父进程并不共享一个环境块。

可以用GetEnvironmentVariable函数来判断一个环节变量是否存在

DWORD GetEnvironmentVariable(
    PCTSTR pszName,
    PTSTR pszValue,
    DWORD cchValue);

pszName用于指定预期的变量名称,pszValue指向保存变量的缓冲区,cchValue指出缓冲区大小

找到就返回复制到缓冲区的字符数,没有找到,就返回0

ExpandEnvironmentStrings函数

DWORD ExpandEnvironmentStrings(
    PCTSTR pszSrc,
    PTSTR pszDSt,
    DWORD chSize);

pszSrc参数是包含“可替换环境变量字符串”的一个字符串地址。pszDst参数是用于接收扩展字符串的一个缓冲区地址。chSize参数是这个缓冲区的最大大小。

用SetEnvironmentVariable函数添加一个变量,删除一个变量,或者修改一个变量的值

BOOL SetEnvironmentVariable(
    PCTSTR pszName,
    PCTSTR pszValue);

将pszName所标识的一个变量设为pszValue参数所标识的值,如果已经有了这个名称的变量就会修改值,如果pszValue设置为NULL,就会删除该变量

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1313051.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MyBatis--07--启动过程分析、SqlSession安全问题、拦截器

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 谈谈MyBatis的启动过程具体的操作过程如下:实现测试类,并测试SqlSessionFactorySqlSession SqlSession有数据安全问题?在MyBatis中,SqlSess…

可观测性是什么?新手入门指南!

如果您之前对可观测性重要性,益处,以及组成不甚了解,本文是一个合适的指南手册。 什么是可观测性? 可观测性被定义为根据系统产生的输出数据(如日志,指标和链路追踪)来衡量当前系统运行状态的…

Python虚拟环境指南:告别依赖地狱

一、背景 在SAAS(软件即服务)平台中,用户使用自行定制的Python脚本已经成为司空见惯的做法,然而,由于不同用户对Python三方库的需求各不相同,而底层服务器一般只安装了一个Python版本。举例来说&#xff0…

【STM32单片机】旋转太空人设计

文章目录 一、功能简介二、软件设计三、实验现象联系作者 一、功能简介 本项目使用STM32F103C8T6单片机控制器,使IIC OLED液晶等。 主要功能: 系统运行后,OLED显示动画界面。 二、软件设计 /* 作者:嗨小易(QQ&#x…

Stable Diffusion 系列教程 - 3 模型下载和LORA模型的小白入门

首先,一个比较广泛的模型下载地址为:Civitai Models | Discover Free Stable Diffusion Models 黄框是一些过滤器,比如checkpoints可以理解为比如把1.5版本的SD模型拷贝一份后交叉识别新的画风或场景后得到的模型,可以单独拿出来使…

[CC13X0] XDS100V3连接报错:Make sure your device is unlocked.

用XDS100V3给CC1310下载程序时,发现如下连接错误: An error occurred while hard opening the controller. -----[An error has occurred and this utility has aborted]-------------------- This error is generated by TIs USCIF driver or utilities…

mysql 数据库 关于库的基本操作

库的操作 如果想到 mysql 客户端当中数据 系统当中的命令的话,直接输入的话,会被认为是 mysql 当中的命令。 所以,在mysql 当中执行系统当中的命令的话,要在系统命令之前带上 ststem ,表示系统命令: 但是…

[css] flex wrap 九宫格布局

<div class"box"><ul class"box-inner"><li>九宫格1</li><li>九宫格2</li><li>九宫格3</li><li>九宫格4</li><li>九宫格5</li><li>九宫格6</li><li>九宫格7&l…

2024年高效远程协同运维工具推荐

随着企业的不断发展以及变化&#xff0c;企业的内部IT环境也是日益复杂&#xff0c;一跨高效远程协同运维工具必不可少&#xff0c;不仅可以提高生产力&#xff0c;还能降低运营成本。这里就给大家推荐2024年高效远程协同运维工具。 高效远程协同运维工具应用场景 1、IT运维管…

WPF仿网易云搭建笔记(1):项目搭建

文章目录 前言项目地址动态样式组合样式批量样式覆盖Prism新建UserControler修改Material Design 笔刷收放列表可以滚动的StackPanel列表点击展开或折叠 实现效果 前言 今天接着继续细化代码&#xff0c;把整体框架写出来 项目地址 WPF仿网易云 Gitee仓库 动态样式 【WPF】C#…

linux 查看服务启动时间

文章目录 linux 查看服务启动时间参数解析 linux 查看服务启动时间 [root104 ~]# ps -o lstart -p ps -ef |grep -v grep |grep "zookeeper"|awk {print$2}STARTED Fri Dec 15 16:54:10 2023参数解析 linux 命令中 ps -ef 详解 ps -ef表示查看全格式的进程。 ps …

视频号小店需要缴纳保证金吗?保证金缴纳标准,不懂的快来看!

我是电商珠珠 入驻视频号小店&#xff0c;需要缴纳保证金吗&#xff1f;具体缴纳多少&#xff1f;... 这是想要入驻视频号小店的热门话题&#xff0c;今天我就来给大家一一讲明白。 想要入驻视频号小店&#xff0c;就必须要缴纳保证金。保证金是平台为了约束商家的行为&…

LLM之Agent(六)| 使用AutoGen、LangChian、RAG以及函数调用构建超级对话系统

本文我们将尝试AutoGen集成函数调用功能。函数调用最早出现在Open AI API中&#xff0c;它允许用户调用外部API来增强系统的整体功能和效率。例如&#xff0c;在对话过程中根据需要调用天气API。 函数调用和Agent有各种组合&#xff0c;在这里我们将通过函数调用调用RAG检索增强…

Windows 7如何将分区标记为活动分区?

引导分区&#xff0c;也称为引导卷&#xff0c;是包含引导加载程序和Windows操作系统所需文件的磁盘分区&#xff0c;是正常启动计算机的前提。一个正确的引导分区不只要包含相关的可引导数据&#xff0c;还需要将分区标记为活动分区。那么&#xff0c;如何将Windows 7分区标记…

网络安全——基于Snort的入侵检测实验

一、实验目的要求&#xff1a; 二、实验设备与环境&#xff1a; 三、实验原理&#xff1a; 四、实验步骤&#xff1a; 五、实验现象、结果记录及整理&#xff1a; 六、分析讨论与思考题解答&#xff1a; 七、实验截图&#xff1a; 一、实验目的要求&#xff1a; 1、掌握…

SuperMap iPortal权限介绍

作者&#xff1a;yx 文章目录 前言一、内置权限二、自定义权限&#xff08;11.1.0及以后版本&#xff09;1、修改配置文件2、页面展示3、api调用4、结果验证5、实际应用 前言 iPortal 用户访问和使用门户中资源的能力取决于其用户类型与在门户中拥有的权限&#xff0c;权限通过…

深入分析ClassLocader工作机制

文章目录 一、ClassLoader简介1. 概念2. ClassLoader类结构分析 二、ClassLoader的双亲委派机制三、Class文件的加载流程1. 简介2. 加载字节码到内存3. 验证与解析4. 初始化Class对象 四、常见加载类错误分析1. ClassNotFoundException2. NoClassDefFoundError3. UnsatisfiledL…

2023.12.13 关于 MySQL 复杂查询

目录 聚合查询 聚合函数 group by 子句 执行流程图 联合查询 笛卡尔积 内连接 外连接 左外连接 右外连接 自连接 子查询 单行子查询 多行子查询 EXISTS 关键字 合并查询 union on 和 union 的区别 聚合查询 聚合函数 函数说明COUNT([DISTINCT] expr)返回查询到…

wpf TelerikUI使用DragDropManager

首先&#xff0c;我先创建事务对象ApplicationInfo&#xff0c;当暴露出一对属性当例子集合对于构成ListBoxes。这个类在例子中显示如下代码&#xff1a; public class ApplicationInfo { public Double Price { get; set; } public String IconPath { get; set; } public …

【【ZYNQ 7020显示 图片 实验 】】

ZYNQ 7020显示 图片 实验 关键配置 BRAM 因为本次 我想显示的 图片是 400*400 所以在 内部 的 ROM 存储单元选择 了160000 ZYNQ7020的内部资源 最多是 大概 200000左右的 大小 大家可以根据 资源选择合适的像素 此处存放 内部的 图片转文字的COE文件 PLL设置 我选用的是按…