Function is not returning non-integer values and ubound error

The code below parse specific registry values and then prints them.

First it will only return integer value, the first key listed should return a data from a multi-string listing.

Secondly if the key is missing altogether on the system in the case of the second item the script dies with "Microsoft VBScript runtime error: Type mismatch: 'UBound'"

Any ideas? Thanks
Const HKEY_CURRENT_USER = &H80000001
Const HKEY_LOCAL_MACHINE = &H80000002
Const REG_SZ = 1
Const REG_EXPAND_SZ = 2
Const REG_BINARY = 3
Const REG_DWORD = 4
Const REG_MULTI_SZ = 7
 
strComputer = "."

strKeyPath = "System\CurrentControlSet\Control\Session Manager\SubSystems"
strValueName = "Optional"
strValue = ReadRegistryValue(HKEY_LOCAL_MACHINE, strKeyPath, strValueName)
Wscript.Echo strValueName & ": " & strValue

strKeyPath = "SYSTEM\CurrentControlSet\services\AFD\Parameters"
strValueName = "DynamicBacklogGrowthDelta"
strValue = ReadRegistryValue(HKEY_LOCAL_MACHINE, strKeyPath, strValueName)
Wscript.Echo strValueName & ": " & strValue


Function ReadRegistryValue(CONST_ROOT, strKeyPath, strValueName)
        strReturnValue = "VALUE NOT FOUND"
        Set oReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & _
            strComputer & "\root\default:StdRegProv")
        If oReg.EnumValues(CONST_ROOT, strKeyPath, arrValueNames, arrValueTypes) = 0 Then
                For intValue = 0 To UBound(arrValueNames)
                        If arrValueNames(intValue) = strValueName Then
                                Select Case arrValueTypes(intValue)
                                        Case REG_SZ
                                                oReg.GetStringValue CONST_ROOT, strKeyPath, arrValueNames(intValue), strValue
                                        Case REG_EXPAND_SZ
                                                oReg.GetExpandedStringValue CONST_ROOT, strKeyPath, arrValueNames(intValue), strValue
                                        Case REG_BINARY
                                                oReg.GetBinaryValue CONST_ROOT, strKeyPath, arrValueNames(intValue), strValue
                                        Case REG_DWORD
                                                oReg.GetDWordValue CONST_ROOT, strKeyPath, arrValueNames(intValue), strValue
                                        Case REG_MULTI_SZ
                                                oReg.GetMultiStringValue CONST_ROOT, strKeyPath, arrValueNames(intVal), arrValues
                                End Select                                
                                strReturnValue = strValue
                        End If
                Next
        Else
                strReturnValue = "KEY NOT FOUND"
        End If
        ReadRegistryValue = strReturnValue
End Function

Open in new window

LVL 3
adamshieldsAsked:
Who is Participating?
 
TommySzalapskiCommented:
Grr, nulls always act funny. Okay do it like this now.
Const HKEY_CURRENT_USER = &H80000001
Const HKEY_LOCAL_MACHINE = &H80000002
Const REG_SZ = 1
Const REG_EXPAND_SZ = 2
Const REG_BINARY = 3
Const REG_DWORD = 4
Const REG_MULTI_SZ = 7


 
strComputer = "."
 
strKeyPath = "Software\test key"
'strKeyPath =  "SYSTEM\CurrentControlSet\services\AFD\Parameters"
strValueName = "s"
strValue = ReadRegistryValue(HKEY_LOCAL_MACHINE, strKeyPath, strValueName)
Wscript.Echo strValueName & ": " & strValue

Function ReadRegistryValue(CONST_ROOT, strKeyPath, strValueName)

        strReturnValue = "VALUE NOT FOUND"
        Set oReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & _
            strComputer & "\root\default:StdRegProv")
        errCode = oReg.EnumValues(CONST_ROOT, strKeyPath, arrValueNames, arrValueTypes)

On Error Resume Next
If errCode = 0 and Not arrValueNames = null Then 
errCode = 0
Else
errCode = 1234 'Pick a number, any number
End If
On Error Goto 0
        If errCode = 0 Then
                For intValue = 0 To UBound(arrValueNames)
                        If arrValueNames(intValue) = strValueName Then
                                Select Case arrValueTypes(intValue)
                                        Case REG_SZ
                                                oReg.GetStringValue CONST_ROOT, strKeyPath, arrValueNames(intValue), strValue
                                        Case REG_EXPAND_SZ
                                                oReg.GetExpandedStringValue CONST_ROOT, strKeyPath, arrValueNames(intValue), strValue
                                        Case REG_BINARY
                                                oReg.GetBinaryValue CONST_ROOT, strKeyPath, arrValueNames(intValue), strValue
                                        Case REG_DWORD
                                                oReg.GetDWordValue CONST_ROOT, strKeyPath, arrValueNames(intValue), strValue
                                        Case REG_MULTI_SZ
                                                strValue = ""
                                                oReg.GetMultiStringValue CONST_ROOT, strKeyPath, arrValueNames(intValue), arrValues
                                                For Each v In arrValues
                                                strValue = strValue & v & "; "
                                                Next
                                End Select                              
                                strReturnValue = strValue
                        End If
                Next
        Else
                strReturnValue = "KEY NOT FOUND"
        End If
        ReadRegistryValue = strReturnValue
End Function

Open in new window

0
 
TommySzalapskiCommented:
Your first problem is because with the multistring case, you never use the returned value. You get the data into arrValue and then ignore it.

Try something like this.

Case REG_MULTI_SZ
  strValue = ""
  oReg.GetMultiStringValue CONST_ROOT, strKeyPath, arrValueNames(intVal), arrValues
  For Each v In arrValues
  strValue = strValue & v & " "
  Next

For the second issue, just handle the error.

Add this at the beginning of the function
On Error Resume Next

Then right before your For loop do
testVar = UBound(arrValueNames)
Replace your If oReg.EnumValues(CONST_ROOT, strKeyPath, arrValueNames, arrValueTypes) = 0 Then with the following
If Err.Number = 0 Then
For...Next
Else
strReturnValue = "KEY NOT FOUND"
End If

This way, when the error is thrown it will skip the whole loop.
0
 
adamshieldsAuthor Commented:
The script is no longer hanging on the missing keys though it's still having issues with displaying non-integers. Thanks


Const HKEY_CURRENT_USER = &H80000001
Const HKEY_LOCAL_MACHINE = &H80000002
Const REG_SZ = 1
Const REG_EXPAND_SZ = 2
Const REG_BINARY = 3
Const REG_DWORD = 4
Const REG_MULTI_SZ = 7
 
strComputer = "."
 
strKeyPath = "System\CurrentControlSet\Control\Session Manager\SubSystems"
strValueName = "Optional"
strValue = ReadRegistryValue(HKEY_LOCAL_MACHINE, strKeyPath, strValueName)
Wscript.Echo strValueName & ": " & strValue

Function ReadRegistryValue(CONST_ROOT, strKeyPath, strValueName)
				On Error Resume Next
        strReturnValue = "VALUE NOT FOUND"
        Set oReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & _
            strComputer & "\root\default:StdRegProv")
        'If oReg.EnumValues(CONST_ROOT, strKeyPath, arrValueNames, arrValueTypes) = 0 Then
        testVar = UBound(arrValueNames)
				If Err.Number = 0 Then
                For intValue = 0 To UBound(arrValueNames)
                        If arrValueNames(intValue) = strValueName Then
                                Select Case arrValueTypes(intValue)
                                        Case REG_SZ
                                                oReg.GetStringValue CONST_ROOT, strKeyPath, arrValueNames(intValue), strValue
                                        Case REG_EXPAND_SZ
                                                oReg.GetExpandedStringValue CONST_ROOT, strKeyPath, arrValueNames(intValue), strValue
                                        Case REG_BINARY
                                                oReg.GetBinaryValue CONST_ROOT, strKeyPath, arrValueNames(intValue), strValue
                                        Case REG_DWORD
                                                oReg.GetDWordValue CONST_ROOT, strKeyPath, arrValueNames(intValue), strValue
                                        Case REG_MULTI_SZ
  																							strValue = ""
  																							oReg.GetMultiStringValue CONST_ROOT, strKeyPath, arrValueNames(intVal), arrValues
  																							For Each v In arrValues
  																							strValue = strValue & v & " "
  																							Next
                                End Select                              
                                strReturnValue = strValue
                        End If
                Next
        Else
                strReturnValue = "KEY NOT FOUND"
        End If
        ReadRegistryValue = strReturnValue
End Function

Open in new window

0
Cloud Class® Course: CompTIA Healthcare IT Tech

This course will help prep you to earn the CompTIA Healthcare IT Technician certification showing that you have the knowledge and skills needed to succeed in installing, managing, and troubleshooting IT systems in medical and clinical settings.

 
TommySzalapskiCommented:
Sorry, I guess it's not resetting put
Err.number = 0
Right before the line that causes the error.
0
 
adamshieldsAuthor Commented:
It's not causing an error, it's just not providing the string value.
0
 
TommySzalapskiCommented:
Oops read that wrong sorry. My guess is the GetDWordValue function doesn't know how to handle a string as the output argument. So for each one, make a variable of the right type and convert it to a string later like this.
Case REG_DWORD
  oReg.GetDWordValue CONST_ROOT, strKeyPath, arrValueNames(intValue), someIntVariable
  strValue = someIntVariable

Open in new window

0
 
adamshieldsAuthor Commented:
Okay let me backup one step, could you try running the code that I last posted? It's now saying "key not found" for all of the inputs when run even though most would report something for the MultiStringValue.
0
 
TommySzalapskiCommented:
The reason the multi-strings are not working is because you used intVal instead of intValue there (intVal doesn't exist?)
I'll look into the other part. Hang on.
0
 
TommySzalapskiCommented:
Okay. Try it like this. It seems to work to put the return value in a variable and then use that.
Const HKEY_CURRENT_USER = &H80000001
Const HKEY_LOCAL_MACHINE = &H80000002
Const REG_SZ = 1
Const REG_EXPAND_SZ = 2
Const REG_BINARY = 3
Const REG_DWORD = 4
Const REG_MULTI_SZ = 7
 
strComputer = "."
 
strKeyPath = "System\CurrentControlSet\Control\Terminal Server"
strValueName = "RCDependentServices"
strValue = ReadRegistryValue(HKEY_LOCAL_MACHINE, strKeyPath, strValueName)
Wscript.Echo strValueName & ": " & strValue

Function ReadRegistryValue(CONST_ROOT, strKeyPath, strValueName)
        strReturnValue = "VALUE NOT FOUND"
        Set oReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & _
            strComputer & "\root\default:StdRegProv")
        errCode = oReg.EnumValues(CONST_ROOT, strKeyPath, arrValueNames, arrValueTypes)
        If errCode = 0 Then
                For intValue = 0 To UBound(arrValueNames)
                        If arrValueNames(intValue) = strValueName Then
                                Select Case arrValueTypes(intValue)
                                        Case REG_SZ
                                                oReg.GetStringValue CONST_ROOT, strKeyPath, arrValueNames(intValue), strValue
                                        Case REG_EXPAND_SZ
                                                oReg.GetExpandedStringValue CONST_ROOT, strKeyPath, arrValueNames(intValue), strValue
                                        Case REG_BINARY
                                                oReg.GetBinaryValue CONST_ROOT, strKeyPath, arrValueNames(intValue), strValue
                                        Case REG_DWORD
                                                oReg.GetDWordValue CONST_ROOT, strKeyPath, arrValueNames(intValue), strValue
                                        Case REG_MULTI_SZ
                                                strValue = ""
                                                oReg.GetMultiStringValue CONST_ROOT, strKeyPath, arrValueNames(intValue), arrValues
                                                For Each v In arrValues
                                                strValue = strValue & v & "; "
                                                Next
                                End Select                              
                                strReturnValue = strValue
                        End If
                Next
        Else
                strReturnValue = "KEY NOT FOUND"
        End If
        ReadRegistryValue = strReturnValue
End Function

Open in new window

0
 
adamshieldsAuthor Commented:
That's better but it still get's the ubound error with one of these as mentioned in the initial question:

[code]
strKeyPath = "SYSTEM\CurrentControlSet\services\AFD\Parameters"
strValueName = "DynamicBacklogGrowthDelta"
strValue = ReadRegistryValue(HKEY_LOCAL_MACHINE, strKeyPath, strValueName)
Wscript.Echo strValueName & ": " & strValue
[/code]
0
 
TommySzalapskiCommented:
Oh good. Mine does the same thing.
Change the if line to this:
If errCode = 0 and Not arrValueNames = null Then
0
 
adamshieldsAuthor Commented:
I get: Microsoft VBScript runtime error: Type mismatch
Function ReadRegistryValue(CONST_ROOT, strKeyPath, strValueName)
        strReturnValue = "VALUE NOT FOUND"
        Set oReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & _
            strComputer & "\root\default:StdRegProv")
        errCode = oReg.EnumValues(CONST_ROOT, strKeyPath, arrValueNames, arrValueTypes)
        If errCode = 0 and Not arrValueNames = null Then
                For intValue = 0 To UBound(arrValueNames)
                        If arrValueNames(intValue) = strValueName Then
                                Select Case arrValueTypes(intValue)
                                        Case REG_SZ
                                                oReg.GetStringValue CONST_ROOT, strKeyPath, arrValueNames(intValue), strValue
                                        Case REG_EXPAND_SZ
                                                oReg.GetExpandedStringValue CONST_ROOT, strKeyPath, arrValueNames(intValue), strValue
                                        Case REG_BINARY
                                                oReg.GetBinaryValue CONST_ROOT, strKeyPath, arrValueNames(intValue), strValue
                                        Case REG_DWORD
                                                oReg.GetDWordValue CONST_ROOT, strKeyPath, arrValueNames(intValue), strValue
                                        Case REG_MULTI_SZ
                                                strValue = ""
                                                oReg.GetMultiStringValue CONST_ROOT, strKeyPath, arrValueNames(intValue), arrValues
                                                For Each v In arrValues
                                                strValue = strValue & v & "; "
                                                Next
                                End Select                              
                                strReturnValue = strValue
                        End If
                Next
        Else
                strReturnValue = "KEY NOT FOUND"
        End If
        ReadRegistryValue = strReturnValue
End Function

Open in new window

0
 
adamshieldsAuthor Commented:
Thanks for helping out!
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.