您好,脚本专家!

您好,脚本专家!

欢迎来到本 TechNet 专栏,在这里,Microsoft 脚本专家将为您解答与系统管理脚本编写有关的各种常见问题。遇到了系统管理脚本编写方面的问题?请将电子邮件发送到 scripter@microsoft.com。我们不能保证回答收到的所有问题,但是我们将尽最大的努力。

同时,不要忘了查看您好,脚本专家!存档

今日问题:如何在计算机上检索 Program Files 文件夹的路径?


如何在计算机上检索 Program Files 文件夹的路径?

问:

您好,脚本专家!如何在计算机上检索 Program Files 文件夹的路径?

-- CC

答:

您好,CC。您如何在计算机上检索 Program Files 文件夹的路径?喔,说老实话,您执行起来可能并不像我们想像的那样简单。如果您尝试在本地计算机上检索 Program Files 路径,那么这很容易;但在远程计算机上检索 Program Files 路径就有点困难了。但我们确实找到了行之有效的方法。

让我们首先看一下这个容易实现的操作的方案。下面的脚本使用 Shell 对象在本地计算机上检索 Program Files 文件夹的路径:

Const PROGRAM_FILES = &H26&

Set objShell = CreateObject("Shell.Application")
Set objFolder = objShell.Namespace(PROGRAM_FILES)
Set objFolderItem = objFolder.Self
Wscript.Echo objFolderItem.Path

该脚本首先定义一个名为 PROGRAM_FILES 的常量,并将其值设定为 &H26&;我们将利用此常量将我们想要使用的“特定文件夹”指示给脚本。(我们还有其他特定文件夹可以使用吗?当然有,“脚本中心”Script Repository(英文)有许多用于显示如何执行此类操作的脚本。)我们创建一个 Shell.Application 对象实例,然后使用 Namespace 方法绑定到 Program Files 文件夹(注意,我们将常量 PROGRAM_FILES 传递给 Namespace 方法):

Set objShell = CreateObject("Shell.Application")
Set objFolder = objShell.Namespace(PROGRAM_FILES)

现在我们遇到了 Shell 对象的少数几个特性中的一个特性。尽管已将我们自己绑定到了代表 Program Files 文件夹的 Folder 对象,但我们无法直接检索该文件夹的路径。而是必须为该文件夹创建 FolderItemObject;可利用 Self 方法来执行此操作(该方法主要只是将该文件夹绑定到自身):

Set objFolderItem = objFolder.Self

不可思议的是,一旦有了 FolderItemObject,便可以回显 Path 属性的值了:

Wscript.Echo objFolderItem.Path

正如您所料,Path 属性的值即为 Program Files 文件夹的路径。

这可太棒了!不过,前提是尝试在本地计算机上找到 Program Files 文件夹。如果尝试在远程计算机上确定 Program Files 文件夹的路径,那就是另外一回事了:那是因为 Shell 对象不会在远程计算机上运行。此外,我们找不到可用于检索路径的 WMI 方法或属性。(我们认为肯定有这样的属性,但是 …。)并且,虽然有一个 %programfiles% 环境变量,但还是不能很容易地从远程计算机检索该环境变量的值。换言之,我们不能使用 Shell 对象,不能使用 WMI,也不能使用 %programfiles% 环境变量。太糟糕了。

对此我们只能说,“多亏了注册表”。(虽然我们也从未想过会这样说。)事实证明,Program Files 文件夹的路径存储在以下注册表值中:

HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\ProgramFilesDir

这意味着我们可以利用 WMI 读取远程计算机上的注册表,然后返回路径:

HKEY_LOCAL_MACHINE = &H80000002

strComputer = "atl-ws-01"
Set objReg = GetObject("winmgmts:\\" & strComputer & "\root\default:StdRegProv")

strKeyPath = "SOFTWARE\Microsoft\Windows\CurrentVersion"
ValueName = "ProgramFilesDir"

objReg.GetStringValue HKEY_LOCAL_MACHINE, strKeyPath, ValueName, strValue
Wscript.Echo strValue

那么,我们将使用上述脚本干什么呢?嗯,我们首先定义一个名为 HKEY_LOCAL_MACHINE 的常量,并将其值设定为 &H80000002;这会将所要使用的注册表配置单元指示给脚本。然后,使用以下两行代码连接至远程计算机 atl-ws-01 上的 WMI 服务:

strComputer = "atl-ws-01"
Set objReg = GetObject("winmgmts:\\" & strComputer & "\root\default:StdRegProv")

仍在看吗?好的。接下来我们为 strKeyPath 和 ValueName 两个变量赋值:

strKeyPath = "SOFTWARE\Microsoft\Windows\CurrentVersion"
ValueName = "ProgramFilesDir"

果然不出所料,strKeyPath 代表 HKLM 注册表配置单元内的路径,而 ValueName 代表我们要读取的注册表值的名称 (ProgramFilesDir)。

现在,我们准备调用 GetStringValue 方法,然后读取注册表:

objReg.GetStringValue HKEY_LOCAL_MACHINE, strKeyPath, ValueName, strValue

请注意,我们向 GetStringValue 传递了四个参数:HKEY_LOCAL_MACHINE、strKey、ValueName 和 strValue。前三个参数是我们先前定义的一个常量和两个变量。但 strValue 到底是什么呢?

唔,strValue 是一个“输出参数”。我们并不为输出参数指定值,而是由方法为其提供值。将 strValue 视为所谓的容器;我们将该容器交给 GetStringValue,随后 GetStringValue 会用其从注册表中读取的信息来填充该容器。换句话说,我们当前问题的答案,即 Program Files 文件夹的路径将被存储在输出参数 strValue 中。

这意味着现在我们必须要做的就是回显该值:

Wscript.Echo strValue

至此您已实现了您的目的。它可能不是获取 Program Files 文件夹路径的最明显、最直观的方法,可是,嗨,这也是没有办法的办法,对吗?


更多信息

欢迎访问您好,脚本专家!- 存档

返回页首返回页首