Vbscript 为什么不存在的注册表值返回为";1“;而不是空?
我不愿意承认我浪费了大量时间试图调整返回已安装程序列表的VB脚本,我正试图理解我哪里出错了 我遇到的问题是,我在网上找到的每一个“列表程序”类型的脚本都会用每个具有“DisplayName”字段的键填充一个文本文件。尽管进行了大量查找,但我找不到只返回填充add/remove或appwiz.cpl的列表的。这是我找到的“抓取一切”类型脚本的一个示例:Vbscript 为什么不存在的注册表值返回为";1“;而不是空?,vbscript,Vbscript,我不愿意承认我浪费了大量时间试图调整返回已安装程序列表的VB脚本,我正试图理解我哪里出错了 我遇到的问题是,我在网上找到的每一个“列表程序”类型的脚本都会用每个具有“DisplayName”字段的键填充一个文本文件。尽管进行了大量查找,但我找不到只返回填充add/remove或appwiz.cpl的列表的。这是我找到的“抓取一切”类型脚本的一个示例: Const HKLM = &H80000002 'HKEY_LOCAL_MACHINE Set objFSO = CreateObject
Const HKLM = &H80000002 'HKEY_LOCAL_MACHINE
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set oShell = CreateObject( "WScript.Shell" )
temp=oShell.ExpandEnvironmentStrings("%temp%")
Set objTextFile = objFSO.CreateTextFile(temp & "\software.txt", True)
strComputer = "."
strKey = "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\"
strKey2 = "SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\"
strEntry1a = "DisplayName"
strEntry1b = "QuietDisplayName"
Set objReg = GetObject("winmgmts://" & strComputer & _
"/root/default:StdRegProv")
objReg.EnumKey HKLM, strKey, arrSubkeys
For Each strSubkey In arrSubkeys
intRet1 = objReg.GetStringValue(HKLM, strKey & strSubkey, _
strEntry1a, strValue1)
If intRet1 <> 0 Then
objReg.GetStringValue HKLM, strKey & strSubkey, _
strEntry1b, strValue1
End If
If strValue1 <> "" Then
objTextFile.WriteLine strValue1
End If
Next
objtextfile.close
Set objTextFile = objFSO.CreateTextFile(temp & "\software.txt", True)
objReg.EnumKey HKLM, strKey2, arrSubkeys
For Each strSubkey In arrSubkeys
intRet1 = objReg.GetStringValue(HKLM, strKey2 & strSubkey, _
strEntry1a, strValue1)
If intRet1 <> 0 Then
objReg.GetStringValue HKLM, strKey & strSubkey, _
strEntry1b, strValue1
End If
If strValue1 <> "" Then
objTextFile.WriteLine strValue1
End If
Next
objtextfile.close
我不太清楚你的问题是什么。您希望哪个值为
Null
(或非Null
)?从注册表读取的值或用于读取注册表值的函数的返回值?这两种价值观具有完全不同的含义
此外,上一个代码段中的函数调用并不完全正确(尽管它可以工作)
您使用参数hDefKey
、sSubkeyName
和sValueName
调用函数,但忽略了实际值(uValue
)的out参数。但是,函数的返回值不是注册表值SystemComponent
的数据,但是一个整数状态代码,指示操作是否成功。从注册表值读取的数据通常存储在函数的第4个参数中。由于缺少此参数,因此它默认为Null
,即运行时环境将函数调用扩展为:
Check = objReg.GetDWORDValue(HKLM, strKey & strSubkey, strEntry1c, Null)
根据strKey&strSubkey
和/或strengtry1c
是否存在,检查的值将为0(成功读取值)、1(值不存在)或2(键不存在)。但是,从注册表读取的任何内容都将被删除,因为没有变量来保存数据(第四个参数是Null
)。因此,条件IsNull(Check)
的计算结果总是False
,并且从不调用GetStringValue
如果将实际变量作为第四个参数添加到函数调用中:
Check = objReg.GetDWORDValue(HKLM, strKey & strSubkey, strEntry1c, val)
该变量的值要么是从注册表读取的值(Check=0
),要么是无法读取的值(Check 0
)
如果要在DWORD值不存在时调用GetStringValue
,则还必须将条件从IsNull(Check)
更改为Check 0
或IsNull(val)
。
@安斯加给出了这么好的解释(+1)
user1691832仍在使用空检查进行实验
文档倾向于避免谈论返回值和可能的错误
一些代码显示您应该检查数字返回值以及如何执行该操作:
Option Explicit
Const HKLM = &H80000002 ' HKEY_LOCAL_MACHINE
Const BAD = &H80000010 ' BAD HIVE
Dim oReg : Set oReg = GetObject("winmgmts://./root/default:StdRegProv")
Dim aParms : aParms = Array( _
Array(HKLM, "SYSTEM\CurrentControlSet\Control\CrashControl", "AutoReboot") _
, Array(HKLM, "SYSTEM\CurrentControlSet\Control\CrashControl", "YYYYYYYYYY") _
, Array(HKLM, "SYSTEM\CurrentControlSet\Control\XXXXXXXXXXXX", "AutoReboot") _
, Array(HKLM, "SYSTEM\CurrentControlSet\Control\XXXXXXXXXXXX", "YYYYYYYYYY") _
, Array(HKLM, "SYSTEM\CurrentControlSet\Control\CrashControl", "AutoReboot") _
, Array(BAD , "SYSTEM\CurrentControlSet\Control\CrashControl", "AutoReboot") _
)
Dim lValue ' 'dwValue' is type prefix fraud
Dim aParm
For Each aParm In aParms
WScript.Echo "try to get long Value from:", Join(aParm, "\")
Dim iRet : iRet = oReg.GetDWORDValue(aParm(0), aParm(1), aParm(2), lValue)
If 0 = iRet Then
WScript.Echo " got:", iRet, TypeName(lValue), lValue
Else
WScript.Echo " got:", iRet, "won't try to display", TypeName(lValue)
End If
Next
输出:
cscript 14794473.vbs
try to get long Value from: -2147483646\SYSTEM\CurrentControlSet\Control\CrashControl\AutoReboot
got: 0 Long 1
try to get long Value from: -2147483646\SYSTEM\CurrentControlSet\Control\CrashControl\YYYYYYYYYY
got: 1 won't try to display Null
try to get long Value from: -2147483646\SYSTEM\CurrentControlSet\Control\XXXXXXXXXXXX\AutoReboot
got: 2 won't try to display Null
try to get long Value from: -2147483646\SYSTEM\CurrentControlSet\Control\XXXXXXXXXXXX\YYYYYYYYYY
got: 2 won't try to display Null
try to get long Value from: -2147483646\SYSTEM\CurrentControlSet\Control\CrashControl\AutoReboot
got: 0 Long 1
try to get long Value from: -2147483632\SYSTEM\CurrentControlSet\Control\CrashControl\AutoReboot
got: 6 won't try to display Null
strValue1可能没有在循环中重新初始化它的值?@SpectralGhost否,strValue1
总是在调用GetStringValue
时重新初始化。这很好地解释了这一点,出于某种原因,我认为“Check”应该包含键的实际值。我可能弄错了,但我很确定我尝试的第一件事是:strEntry1c=“SystemComponent”Check=objReg.GetDWORDValue(HKLM,strKey&strSubkey,strEntry1c,Chk1)如果为null(Chk1),那么intRet1=objReg.GetStringValue(HKLM,strKey&strSubkey,stry1a,strValue1)
出于某种原因,这也不起作用,但也许我做错了什么。
Check = objReg.GetDWORDValue(HKLM, strKey & strSubkey, strEntry1c, val)
Option Explicit
Const HKLM = &H80000002 ' HKEY_LOCAL_MACHINE
Const BAD = &H80000010 ' BAD HIVE
Dim oReg : Set oReg = GetObject("winmgmts://./root/default:StdRegProv")
Dim aParms : aParms = Array( _
Array(HKLM, "SYSTEM\CurrentControlSet\Control\CrashControl", "AutoReboot") _
, Array(HKLM, "SYSTEM\CurrentControlSet\Control\CrashControl", "YYYYYYYYYY") _
, Array(HKLM, "SYSTEM\CurrentControlSet\Control\XXXXXXXXXXXX", "AutoReboot") _
, Array(HKLM, "SYSTEM\CurrentControlSet\Control\XXXXXXXXXXXX", "YYYYYYYYYY") _
, Array(HKLM, "SYSTEM\CurrentControlSet\Control\CrashControl", "AutoReboot") _
, Array(BAD , "SYSTEM\CurrentControlSet\Control\CrashControl", "AutoReboot") _
)
Dim lValue ' 'dwValue' is type prefix fraud
Dim aParm
For Each aParm In aParms
WScript.Echo "try to get long Value from:", Join(aParm, "\")
Dim iRet : iRet = oReg.GetDWORDValue(aParm(0), aParm(1), aParm(2), lValue)
If 0 = iRet Then
WScript.Echo " got:", iRet, TypeName(lValue), lValue
Else
WScript.Echo " got:", iRet, "won't try to display", TypeName(lValue)
End If
Next
cscript 14794473.vbs
try to get long Value from: -2147483646\SYSTEM\CurrentControlSet\Control\CrashControl\AutoReboot
got: 0 Long 1
try to get long Value from: -2147483646\SYSTEM\CurrentControlSet\Control\CrashControl\YYYYYYYYYY
got: 1 won't try to display Null
try to get long Value from: -2147483646\SYSTEM\CurrentControlSet\Control\XXXXXXXXXXXX\AutoReboot
got: 2 won't try to display Null
try to get long Value from: -2147483646\SYSTEM\CurrentControlSet\Control\XXXXXXXXXXXX\YYYYYYYYYY
got: 2 won't try to display Null
try to get long Value from: -2147483646\SYSTEM\CurrentControlSet\Control\CrashControl\AutoReboot
got: 0 Long 1
try to get long Value from: -2147483632\SYSTEM\CurrentControlSet\Control\CrashControl\AutoReboot
got: 6 won't try to display Null