Windows程序如何删除自身

本文介绍几种实现在程序退出后,从磁盘删除自身 exe 文件的方式。该技术通常应用于安装包卸载程序中。

Windows编程

Windows用户界面特权隔离(UIPI)

在早期的 Windows 操作系统中,在同一用户下运行的所有进程有着相同的安全等级,拥有相同的权限。此时进程可以自由地发送Windows 消息到其他进程的窗口。 从 Windows Vista 开始,对于某些 Windows 消息,这一方式再也行不通了,进程(或者其他的对象)开始拥有一个新的属性–特权等级(Privilege Level)。此时一个特权等级较低的进程不再可以向特权等级较高的进程发送消息,即便他们在相同的用户权限下运行也不行,这就是所谓的用户界面特权隔离(User Interface Privilege Isolation, 简称 UIPI)。

Windows编程

Windows注册URL协议

当电脑安装完 Steam 后,我们在浏览器中访问steam://run/123,浏览器会自动提示打开 Steam 程序。类似的功能在迅雷、QQ 等产品上也都有使用,本文讲述如何实现该功能。

Windows编程

Windows内核对象

一、什么是内核对象我们在 windows 开发中经常会遇到内核对象,如事件(Event),管道(Pipe),互斥量(Mutex),完成端口(IOCP),进程(Process),线程(Thread)等,他们都是内核对象。这些内核对象虽然通过不同的系统 API 来创建,但这些 API 都有一个共同特点,就是都需要传入SECURITY_ATTRIBUTES安全描述符结构体指针,并且返回句柄(HANDLE)。依据这个特点,我们有一个简单方法来判断对象是否是内核对象,就是看创建它的函数是否允许传入SECURITY_ATTRIBUTES安全描述符。

Windows编程

了解DPI缩放

dpi 是“Dots Per Inch”的缩写,表示每英寸的像素点个数,也就是像素点的密集度。 dpi不是用来表示屏幕分辨率的,也不是用来表示屏幕物理尺寸的。

Windows编程

Windows内存体系(7)--使用std::string跨MT模块传参

前面的Windows内存体系(6)--跨模块内存分配释放文章解释了跨 MT 模块分配的内存相互释放为什么会崩溃的问题,本文介绍如何解决该问题。

Windows编程

Windows内存体系(6)--跨模块内存分配释放

在《Windows核心编程 第五版》第19章 DLL基础(511页)中给出了一个建议: “当一个 MT 版本的模块如果提供一个内存分配函数的时候,它必须同时提供另一个用来释放内存的函数。”。 说得更加直白一点就是,“对于 MT 的模块,不要跨模块进行内存释放。”。但是核心编程这本书上面没有具体分析原因,本文就来分析具体的原因。

Windows编程

Windows内存体系(5)--堆

一、为什么要使用堆 (Heap)?应用程序虽然可以使用页面粒度的函数(如VirualAlloc)来分配一个最小为4KB或8K的内存块,但是很多时候我们并不需要分配这么大的内存块,我们可能只想分配 1K,2K 的内存块,那么这个时候无论从内存的使用率,还是从性能的角度来看,再分配这么大的一个内存区域显然不是最优的了。 为了满足这种需求,Windows 提供了一个被称为“堆管理器”的组件,它负责管理大内存区域中的内存分配,这些大内存区域就是通过一些页面粒度的内存分配函数(如VirualAlloc)来预定(reserve)的。 堆管理器中的分配粒度相对比较小:在32位系统上是8字节,在64位系统上是16字节。 堆管理器已经被 Windows 系统精心设计,在这些小内存分配的情况下会进行内存使用率和性能两个方面的优化。

Windows编程

Windows内存体系(4)--内存对齐

一、内存为什么要对齐虽然所有的变量都是保存在特定地址的内存中,但最好还是按照内存对齐的要求来存储。这主要出于两个方面的原因考虑: 平台原因:不是所有的硬件平台(特别是嵌入式系统中使用的低端处理器)都能访问任意地址上的任意数据,某些硬件平台只能访问对齐的地址,否则会出现硬件异常。 性能原因:如果数据存放在未对齐的内存空间中,则处理器访问变量时需要进行两次内存访问才能完整读取该变量的值,而对齐的内存访问仅需一次访问。

Windows编程

Windows内存体系(3)--内存映射文件

一、为什么需要内存映射“内存映射文件”可以将硬盘上的文件映射到虚拟地址空间,这样就不需要将所有东西都放入到页交换文件中,比如系统有许多程序同时运行时,如果将这些程序文件都加载到页交换文件中,页交换文件将会变得非常大。事实上,Windows 也并没有将硬盘上的程序文件复制到页交换文件中,因为这样不仅会让页交换文件将会变得非常大,也会浪费很多时间,特别是可执行程序非常大的时候。 当用户要求执行一个应用程序时,系统会打开该应用程序的.exe文件,并计算出应用程序的代码和数据的大小,然后系统会在进程的虚拟地址空间预定一块地址空间,并注明与该区域相关联的物理存储器就是.exe文件本身。 当把一个位于硬盘上的文件(可以是.exe,.dll也可以是普通文件)映像用作地址空间区域对应的物理存储器时,我们称这个文件映像为“内存映射文件”。

Windows编程

Windows内存体系(2)--虚拟内存

一、页交换文件虚拟地址空间只是操作系统为进程“虚拟”出来的一块地址区域,并不代表任何实际的空间。而“页交换文件”却对应了实际的空间,这个空间一般是磁盘上名为“pagefile.sys”的文件。 “页交换文件”的大小和位置可以在系统设置(系统属性 -> 高级 -> 性能 -> 设置 -> 高级 )中进行设置: 从微软的官方文档来看,“虚拟内存”等于“物理内存”+“分页文件”总和。可以把“虚拟内存”理解为 Windows 的一种内存管理机制。

Windows编程

Windows内存体系(1)--虚拟地址空间

一、实模式下内存分配机制在 8086 或者 80186 以前,程序运行时,操作系统会把程序全都装入内存,程序都是直接运行在物理内存上的。也就是说程序中访问的内存地址都是实际的物理内存地址。当计算机同时运行多个程序时,必须保证这些程序用到的内存总量要小于计算机实际物理内存的大小。 例如某台计算机总的内存大小是128M ,现在同时运行两个程序 A 和 B ,A 需占用内存10M , B 需占用内存110M 。计算机在给程序分配内存时会采取这样的方法:先将内存中的前10M分配给程序 A ,接着再从内存中剩余的118M中划分出 110M分配给程序 B 。这种分配方法虽然可以保证程序 A 和程序 B 都能运行,但是这种简单的内存分配策略会导致很多问题:

Windows编程
123