Solved

Function is not returning non-integer values and ubound error

Posted on 2010-11-09
13
533 Views
Last Modified: 2012-05-10
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

0
Comment
Question by:adamshields
  • 7
  • 6
13 Comments
 
LVL 37

Expert Comment

by:TommySzalapski
ID: 34099278
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
 
LVL 3

Author Comment

by:adamshields
ID: 34100914
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
 
LVL 37

Expert Comment

by:TommySzalapski
ID: 34101825
Sorry, I guess it's not resetting put
Err.number = 0
Right before the line that causes the error.
0
MIM Survival Guide for Service Desk Managers

Major incidents can send mastered service desk processes into disorder. Systems and tools produce the data needed to resolve these incidents, but your challenge is getting that information to the right people fast. Check out the Survival Guide and begin bringing order to chaos.

 
LVL 3

Author Comment

by:adamshields
ID: 34101848
It's not causing an error, it's just not providing the string value.
0
 
LVL 37

Expert Comment

by:TommySzalapski
ID: 34101902
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
 
LVL 3

Author Comment

by:adamshields
ID: 34102110
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
 
LVL 37

Expert Comment

by:TommySzalapski
ID: 34102448
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
 
LVL 37

Expert Comment

by:TommySzalapski
ID: 34102798
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
 
LVL 3

Author Comment

by:adamshields
ID: 34103012
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
 
LVL 37

Expert Comment

by:TommySzalapski
ID: 34103191
Oh good. Mine does the same thing.
Change the if line to this:
If errCode = 0 and Not arrValueNames = null Then
0
 
LVL 3

Author Comment

by:adamshields
ID: 34103275
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
 
LVL 37

Accepted Solution

by:
TommySzalapski earned 500 total points
ID: 34103824
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
 
LVL 3

Author Closing Comment

by:adamshields
ID: 34105311
Thanks for helping out!
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article is meant to give a basic understanding of how to use R Sweave as a way to merge LaTeX and R code seamlessly into one presentable document.
The Windows functions GetTickCount and timeGetTime retrieve the number of milliseconds since the system was started. However, the value is stored in a DWORD, which means that it wraps around to zero every 49.7 days. This article shows how to solve t…
Learn the basics of modules and packages in Python. Every Python file is a module, ending in the suffix: .py: Modules are a collection of functions and variables.: Packages are a collection of modules.: Module functions and variables are accessed us…
In this fifth video of the Xpdf series, we discuss and demonstrate the PDFdetach utility, which is able to list and, more importantly, extract attachments that are embedded in PDF files. It does this via a command line interface, making it suitable …

685 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question