使用VBScript检查注册表键是否存在

17

我本以为这很容易,但显然没有人这样做... 我想要检查一个注册表项是否存在。 我不关心它内部是否有任何值,例如(默认值)。

这是我一直在尝试的。

Set objRegistry = GetObject("winmgmts:\\.\root\default:StdRegProv")
objRegistry.GetStringValue &H80000003,".DEFAULT\Network","",regValue

If IsEmpty(regValue) Then
    Wscript.Echo "The registry key does not exist."
Else
    Wscript.Echo "The registry key exists."
End If

我只想知道HKEY_USERES\.DEFAULT\.Network是否存在。当我搜索时,大多数讨论的内容似乎都是关于操作这个键值,并且基本上假设该键值已经存在,因为如果不存在,它会自动创建。

7个回答

13

我找到了解决方案。

dim bExists
ssig="Unable to open registry key"

set wshShell= Wscript.CreateObject("WScript.Shell")
strKey = "HKEY_USERS\.Default\Software\Microsoft\Windows\CurrentVersion\Internet Settings\Digest\"
on error resume next
present = WshShell.RegRead(strKey)
if err.number<>0 then
    if right(strKey,1)="\" then    'strKey is a registry key
        if instr(1,err.description,ssig,1)<>0 then
            bExists=true
        else
            bExists=false
        end if
    else    'strKey is a registry valuename
        bExists=false
    end if
    err.clear
else
    bExists=true
end if
on error goto 0
if bExists=vbFalse then
    wscript.echo strKey & " does not exist."
else
    wscript.echo strKey & " exists."
end if

9
这里的第二种方法可以满足您的需求。在这个帖子中没有找到成功的方法后,我刚刚使用了这种方法,并且它对我有效。 http://yorch.org/2011/10/two-ways-to-check-if-a-registry-key-exists-using-vbscript/ 代码如下:
Const HKCR = &H80000000 'HKEY_CLASSES_ROOT
Const HKCU = &H80000001 'HKEY_CURRENT_USER
Const HKLM = &H80000002 'HKEY_LOCAL_MACHINE
Const HKUS = &H80000003 'HKEY_USERS
Const HKCC = &H80000005 'HKEY_CURRENT_CONFIG

Function KeyExists(Key, KeyPath)
    Dim oReg: Set oReg = GetObject("winmgmts:!root/default:StdRegProv")
    If oReg.EnumKey(Key, KeyPath, arrSubKeys) = 0 Then
        KeyExists = True
    Else
        KeyExists = False
   End If
End Function

1
对于好奇的人,上面的链接已经失效了,我找不到缓存页面;它的一个副本似乎在这里(http://linsong837.blogspot.com/2013/01/check-if-string-in-registry-exists.html),但另一种方法只是由@MTeck给出的答案。 - Kodithic
2
当我检查时,那个页面仍然是活动的。 - chris_k
是这样的。我可能在短暂的停机期间访问了它,抱歉。 - Kodithic

9

避免使用RegRead和错误处理技巧的最简单方法。 注册表可选友好常量:

Const HKEY_CLASSES_ROOT   = &H80000000
Const HKEY_CURRENT_USER   = &H80000001
Const HKEY_LOCAL_MACHINE  = &H80000002
Const HKEY_USERS          = &H80000003
Const HKEY_CURRENT_CONFIG = &H80000005

然后使用以下命令进行检查:

Set oReg = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv")

If oReg.EnumKey(HKEY_LOCAL_MACHINE, "SYSTEM\Example\Key\", "") = 0 Then
  MsgBox "Key Exists"
Else
  MsgBox "Key Not Found"
End If

以下是上述内容的重要说明:

  • 等于零表示该键已存在。
  • 键名后面的斜杠是可选的,不是必须的。

还有一个重要的提示:如果将HKEY_LOCAL_MACHINE作为第一个参数使用,请在IF语句之前设置一个常量,像这样:Const HKEY_LOCAL_MACHINE = &H80000002 - Beems
@Beems 很好的建议,已经添加了常量以避免任何混淆。 - WhoIsRich
有人可以解释一下第四个参数吗?谢谢。 - Safwan
1
根据微软的文档,没有第四个参数。我尝试使用一个变量作为第四个参数,但没有返回值。我还测试了添加第五个参数,代码运行没有任何错误,似乎你在末尾添加的任何额外参数都会被忽略。如果省略第三个参数,代码也可以正常工作。 - Safwan
很久以前发布了这个内容,可能是从一个旧教程中盲目重复的,因此已经删除了空的第四个参数以避免混淆。 - WhoIsRich

2

如果其他人也遇到了这个问题,我可以参考WhoIsRich的例子并稍作修改。在调用ReadReg时,我需要执行以下操作:ReadReg("App", "HKEY_CURRENT_USER\App\Version"),这样就能从注册表中读取版本号(如果存在)。我还使用了HKCU,因为它不需要管理员权限就可以写入。

Function ReadReg(RegKey, RegPath)
      Const HKEY_CURRENT_USER = &H80000001
      Dim objRegistry, oReg
      Set objRegistry = CreateObject("Wscript.shell")
      Set oReg = GetObject("winmgmts:!root\default:StdRegProv")

      if oReg.EnumKey(HKEY_CURRENT_USER, RegKey) = 0 Then
        ReadReg = objRegistry.RegRead(RegPath)
      else
        ReadReg = ""
      end if
End Function

1

编辑(抱歉我以为您需要VBA)。

每当您尝试从注册表中读取不存在的值时,就会返回一个Null值。因此,您只需要检查是否有Null值即可。

请使用IsNull而不是IsEmpty

Const HKEY_LOCAL_MACHINE = &H80000002

strComputer = "."
Set objRegistry = GetObject("winmgmts:\\" & _ 
    strComputer & "\root\default:StdRegProv")

strKeyPath = "SOFTWARE\Microsoft\Windows NT\CurrentVersion"
strValueName = "Test Value"
objRegistry.GetStringValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName,strValue

If IsNull(strValue) Then
    Wscript.Echo "The registry key does not exist."
Else
    Wscript.Echo "The registry key exists."
End If

与VBA相反,On Error Goto {label}在VBScript上不起作用,但您可以使用On Error Resume Next并通过err.Numbererr.Description读取err对象。 - AutomatedChaos
1
这并不能满足我的需求。我需要知道这个键是否存在,而不是值:数据对。测试默认值""就可以了。然而,你提供的复制/粘贴在搜索中很容易找到,但没有区分值是否存在、为空或为null。我只需要知道这个键是否存在。 - MTeck

0

查看 Scripting Guy! 博客:

如何判断注册表中是否存在某个值?

他们讨论了在远程计算机上进行检查,并展示了如果从键中读取字符串值,且该值为 Null(而不是 Empty),则该键不存在。

关于使用 RegRead 方法,如果术语“键”指的是存储注册表值的路径(或文件夹),并且如果该键中的叶子项称为“值”,则使用 WshShell.RegRead(strKey) 检测键的存在性(而不是值的存在性)请考虑以下内容(在 Windows XP 上观察到):

如果 strKey 名称不是现有注册表路径的名称,则 Err.Description 会显示“注册表键中的无效根”...,Err.Number 为 0x80070002。

如果strKey命名了一个存在但不包括尾随“\”的注册表路径,则RegRead方法似乎将strKey解释为路径\值引用而不是简单路径引用,并返回相同的Err.Number,但具有“无法打开注册表键”的Err.Description。错误消息中的术语“键”似乎意味着“值”。当strKey引用存在路径但不存在值的路径\值时,也会得到相同的结果。

0

被接受的答案太长了,其他答案对我没有用。我会把这个留下来以备将来参考。

Dim sKey, bFound
skey = "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run\SecurityHealth"

with CreateObject("WScript.Shell")
  on error resume next            ' turn off error trapping
    sValue = .regread(sKey)       ' read attempt
    bFound = (err.number = 0)     ' test for success
  on error goto 0                 ' restore error trapping
end with

If bFound Then
  MsgBox = "Registry Key Exist."
Else
  MsgBox = "Nope, it doesn't exist."
End If

这是注册表树的列表,请根据您当前的任务选择自己的基础。

HKCR = HKEY_CLASSES_ROOT
HKCU = HKEY_CURRENT_USER
HKLM = HKEY_LOCAL_MACHINE
HKUS = HKEY_USERS
HKCC = HKEY_CURRENT_CONFIG

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接