Solved

Function is not returning non-integer values and ubound error

Posted on 2010-11-09
13
536 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
More Than Just A Video Library

Train for your certification. Learn the latest DevOps tools. Grow your skillset to do better work.

At Linux Academy, we release new training modules every week so you'll always be up to date on the latest tech.

 
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

The Orion Papers

Are you interested in becoming an AWS Certified Solutions Architect?

Discover a new interactive way of training for the exam.

Question has a verified solution.

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

Background Still having to process all these year-end "csv" files received from all these sources (including Government entities), sometimes we have the need to examine the contents due to data error, etc... As a "Unix" shop, our only readily …
In threads here at EE, each comment has a unique Identifier (ID). It is easy to get the full path for an ID via the right-click context menu. However, we often want to post a short link within a thread rather than the full link. This article shows a…
Learn how to match and substitute tagged data using PHP regular expressions. Demonstrated on Windows 7, but also applies to other operating systems. Demonstrated technique applies to PHP (all versions) and Firefox, but very similar techniques will w…
The viewer will learn how to dynamically set the form action using jQuery.

627 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