创建多个环境变量时,不会扩展引用

时间:2015-02-27 13:09:22

标签: vbscript

使用VBS按顺序创建多个环境变量时,在以后的变量中引用时,先前的变量永远不会扩展。

Set wshUserEnv = objShell.Environment( "USER" )
wshUserEnv("A") = "a"
wshUserEnv("b") = "%A%\b"

然后,

objShell.ExpandEnvironmentStrings(GetEnvVariable("b"))

不会给出\ b的值,而是保留为%A%\ b

此外,列出命令行中的值会打印相同的值。但是,一旦从“系统属性”对话框中编辑变量(轻微编辑,如添加分号),变量就会扩展。

GetEnvVariable是一个辅助函数:

Function GetEnvVariable (EnvVariable)
    Dim wshUserEnv
    Set wshUserEnv = objShell.Environment( "USER" )
    GetEnvVariable=wshUserEnv(EnvVariable)
End Function

1 个答案:

答案 0 :(得分:0)

关于.ExpandEnvironmentStrings()行为:

运行下面的第一个脚本:

Set objShell = CreateObject("WScript.Shell")

' set values to variables
objShell.Environment("user")("user___var") = "user___value"
objShell.Environment("process")("process___var") = "process___value"
objShell.Environment("system")("system___var") = "system___value"
objShell.Environment("volatile")("volatile___var") = "volatile___value"

s = "check accessibility within running script process" & vbCrLf
s = s & objShell.ExpandEnvironmentStrings("%user___var%") & vbCrLf
s = s & objShell.ExpandEnvironmentStrings("%process___var%") & vbCrLf
s = s & objShell.ExpandEnvironmentStrings("%system___var%") & vbCrLf
s = s & objShell.ExpandEnvironmentStrings("%volatile___var%") & vbCrLf
WScript.Echo(s)

objShell.Run "cmd.exe /k echo check accessibility within child process & echo %user___var% & echo %process___var% & echo %system___var% & echo %volatile___var%"

WScript.Echocmd.exe /k echo的输出结果相同:

%user___var%
process___value
%system___var%
%volatile___var%

之后运行第二个脚本:

Set objShell = CreateObject("WScript.Shell")

s = "check accessibility via another script process" & vbCrLf
s = s & objShell.ExpandEnvironmentStrings("%user___var%") & vbCrLf
s = s & objShell.ExpandEnvironmentStrings("%process___var%") & vbCrLf
s = s & objShell.ExpandEnvironmentStrings("%system___var%") & vbCrLf
s = s & objShell.ExpandEnvironmentStrings("%volatile___var%") & vbCrLf
WScript.Echo(s)

objShell.Run "cmd.exe /k echo check accessibility via another script process & echo %user___var% & echo %process___var% & echo %system___var% & echo %volatile___var%"

输出将是:

user___value
%process___var%
system___value
volatile___value

我检查过Win7 x64和VirtualBox WinXP上的行为。如您所见,process环境只能在正在运行的进程中通过.ExpandEnvironmentStrings()访问,或者通过子进程访问,第一个脚本显示。在完成运行脚本(设置了变量)之前,.ExpandEnvironmentStrings()无法访问其他环境。当您运行第二个脚本时,您可以通过.ExpandEnvironmentStrings()读取所有环境变量,但进程除外。

我希望这种解释有助于让您的代码正常运行。

您展示的代码objShell.ExpandEnvironmentStrings(GetEnvVariable("b"))会向您%A%\b提供GetEnvVariable("b"),因为%A%\b会返回.Environment()(函数中实现的user方法可以访问%A%环境和所有其他环境,但它不会将包含.ExpandEnvironmentStrings()作为变量语句处理,如.ExpandEnvironmentStrings("%A%\b")所做的那样),然后A返回值而不进行任何更改(该方法没有访问user环境中的{{1}}变量,直到脚本终止。)