WIN32汇编语言教程:第13章 进程控制 · 13.1 环境变量和命令行参数(1)
13.1.1 环境变量
1. 什么是环境变量
环境变量就是在命令提示符下键入“Set”命令后列出来的内容,它的定义格式以XXX=YYY的形式来表示,其中的XXX是环境变量的名称,YYY是环境变量的值,下面的例子是笔者使用的计算机中列出的部分环境变量:
ALLUSERSPROFILE=C:\Documents and Settings\All Users
APPDATA=C:\Documents and Settings\Administrator\Application Data
BLASTER=A220 I7 D1 H7 P330 T6
SBPCI=C:\SBPCI
COMPUTERNAME=WORKGROU-86NSVP
ComSpec=C:\WINDOWS\system32\cmd.exe
SystemDrive=C:
SystemRoot=C:\WINDOWS
HOMEDRIVE=C:
ProgramFiles=C:\Program Files
HOMEPATH=\Documents and Settings\Administrator
LOGONSERVER=\\WORKGROU-86NSVP
OS=Windows_NT
Path=C:\WINDOWS\system32;C:\WINDOWS;c\tools;C:\WIN98\Twain_32\Nuscan
NUMBER_OF_PROCESSORS=1
PROCESSOR_ARCHITECTURE=x86
PROCESSOR_IDENTIFIER=x86 Family 6 Model 6 Stepping 0, GenuineIntel
PROCESSOR_LEVEL=6
PROCESSOR_REVISION=0600
PROMPT=$P$G
TEMP=C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp
TMP=C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp
USERDOMAIN=WORKGROU-86NSVP
USERNAME=Administrator
windir=C:\WINDOWS
环境变量按照用途可以分为3大类:
● 与系统运行相关的环境变量——这些变量的值和系统的正常运行息息相关。如PATH变量定义的是可执行文件的搜索路径,它直接影响系统搜寻可执行文件的位置和先后顺序;而TEMP和TMP变量将影响系统创建临时文件的位置;ComSpec变量定义命令行管理器的文件名,在DOS操作系统下,如果这个变量的定义错误,就会导致系统无法装入Command.com而挂起。
● 反映系统状态的环境变量——如NUMBER_OF_PROCESSORS,PROCESSOR_LEVEL和PROCESSOR_IDENTIFIER等是操作系统根据当前的硬件定义的;COMPUTERNAME,USERNAME和USERDOMAIN等变量是操作系统根据当前的机器名、登录用户等定义的;OS,HOMEDRIVE和ProgramFiles等则定义了操作系统的名称和安装位置。通过检测这些变量,应用程序可以了解系统的配置情况和其他一些重要信息。
● 应用程序自定义的环境变量——如上面列出的BLASTER和SBPCI是创新声卡自定义的变量。在本书例子程序的编译环境中,也定义了一些编译器和链接器使用的变量,如Include与Lib等,这些变量是应用程序根据自己的需要自定义的。
2. 对环境变量进行操作
在命令提示符窗口中,可以通过“Set 变量=内容”格式的命令来设置环境变量的值,也可以通过“Set 变量=”命令来删除某个环境变量。如果需要在程序中对环境变量进行操作,可以使用Win32中的几个API。
如果想获取一个环境变量的值,可以使用GetEnvironmentVariable函数:
invoke GetEnvironmentVariable,lpVarName,lpBuffer,dwSize
lpVarName指向一个以0结尾的字符串,用来指定需要获取的环境变量名,lpBuffer指向用来接收变量值的缓冲区,dwSize参数指定缓冲区的大小。如果函数执行成功,返回值是返回到缓冲区中的字符数量(不包括结束的0字符);如果环境变量不存在,返回值是0;如果缓冲区太小以至于放不下环境变量内容,那么缓存区中不会返回任何内容,这时函数的返回值是需要的缓存区的大小,这就意味着,如果返回值比缓冲区的大小要大,那么必须扩大缓冲区后再次调用。
下面的代码演示了如何将PATH变量的值获取到szBuffer缓冲区中:
.data
szBuffer db 200 dup (?)
szVarName db 'PATH',0
.code
invoke GetEnvironmentVariable,addr szVarName,\
addr szBuffer,sizeof szBuffer
GetEnvironmentVariable函数只能用来获取已知名称的环境变量,如果需要枚举所有的环境变量,可以使用GetEnvironmentStrings函数。这个函数返回一个内存块指针,内存块中包含了所有的环境变量定义,通过扫描整个内存块就可以获得所有的环境变量定义。该函数没有输入参数:
invoke GetEnvironmentStrings
mov lpVar,eax
内存块中环境变量存放格式为“变量1=内容1”,0,“变量2=内容2”,0,......“变量N=内容N”,0,0,即每个定义字符串以0结束,然后开始下一个变量定义字符串,全部定义字符串的最后再以一个附加的0结束。
GetEnvironmentStrings函数返回的内存块是系统申请的,当不需要再使用的时候,需要将它释放,释放这个内存块并不等于删除全部环境变量,而仅是释放这份拷贝而已。释放使用的函数是FreeEnvironmentStrings:
invoke FreeEnvironmentStrings,lpVar
函数的输入参数lpVar就是GetEnvironmentStrings函数返回的内存块指针。
如果需要改变现存环境变量的值,设置新的环境变量或者删除某个环境变量,可以使用SetEnvironmentVariable函数:
invoke SetEnvironmentVariable,lpVarName,lpValue
lpVarName指向环境变量的名称,lpValue指向一个以0结尾的字符串,用来指定环境变量的新值。
当lpVarName指定的环境变量已经存在且lpValue指向一个空串时,这个变量将被删除;如果lpValue指向的不是一个空串,那么环境变量的值将被改为这个新的字符串;如果lpVarName指定的环境变量不存在且lpValue指向的不是一个空串,那么系统将建立新的环境变量。
SetEnvironmentVariable函数的运行结果仅改变本进程的环境变量,并不会影响其他进程。比如打开一个命令提示符窗口,在其中改变某些环境变量的设置,然后再打开另一个命令提示符窗口查看,就会发现这个窗口的环境变量并没有改变。
但是环境变量的值可以被子进程继承,如果在一个程序中创建了另一个进程,那么可以让这个子进程“看到”改动以后的环境变量,这就是在一个命令提示符窗口中改变了环境变量的设置,然后用命令行方式运行一些程序,改变的环境变量对这些程序都有效的原因。
上页:第12章 多线程 · 12.4 线程间的同步(4) 下页:第13章 进程控制 · 13.1 环境变量和命令行参数(2)