Jump to content

issue reading "default key" from registry with WMI


Recommended Posts

thanks to the template kindly provided by UEZ in >this post, I can read KeyValues from the registry using WMI.
In short, to read the value contained in a KeyValue of the registry you have to use the appropriate method according to the KeyType of the Key  that you have to read.
to know the KeyType, must be used the EnumValues method that returns 2 arrays, one  with KeyNames and the other with KeyTypes.

Here is the issue that I do not know how to solve:
according to what is written in the remarks provided about the EnumValues method of the StdRegProv class:
"This method returns a null value for the array when the default value is the only one present."
so, the problem is: how to read the value of a the default KeyValue when it's the only one present since you can not know the KeyType of that key?

the following listing can be used to arise the problem by changing the value of the $sKeyPath variable to a path in your registry that only contains the default KeyValue

Thanks for any help

#include <array.au3>

Global Const $oErrorHandler = ObjEvent("AutoIt.Error", "ObjErrorHandler")
Global $sHost = @ComputerName
Global $sHIVE = "HKEY_CURRENT_USER"
Global $sKeyPath = "SYSTEM\Software" ; <-- change this to a keypath that has only the default KeyValue
Global $sKeyValue = "" ; use a blank string to read the default keyValue
Global $sUser = ""
Global $sPass = ""

$result = WMI_GetRemoteRegVal($sHost, $sHIVE, $sKeyPath, $sKeyValue, $sUser, $sPass)
Local $error = @error
If Not $error Then
    If IsArray($result) Then
        _ArrayDisplay($result)
    Else
        MsgBox(0, "Test", "Value in the Key " & $sKeyValue & " is: " & $result)
    EndIf
Else
    MsgBox(0, "Error", "Error " & $error)
EndIf

Func WMI_GetRemoteRegVal($sHost, $sPrefix, $sRegKeyPath, $sSearchValue, $sUser, $sPass) ;coded by UEZ build 2014-07-06
    If $sHost = "." Then $sHost = "localhost"
    Local $iPing = Ping($sHost, 250)
    If @error Then Return SetError(1, 0, "")
    Local $objWMILocator = ObjCreate("WbemScripting.SWbemLocator")
    Local $objWMIService = $objWMILocator.ConnectServer($sHost, "\\.\root\default", $sUser, $sPass, "", "", 128)
    If @error Then Return SetError(2, @error, "")
    Local $objReg = $objWMIService.Get("StdRegProv") ;http://msdn.microsoft.com/en-us/library/aa393664(v=vs.85).aspx
    If @error Then Return SetError(3, @error, "")
    Local Const $wbemImpersonationLevelImpersonate = 3, $wbemAuthenticationLevelPktPrivacy = 6
    $objReg.Security_.ImpersonationLevel = $wbemImpersonationLevelImpersonate
    $objReg.Security_.AuthenticationLevel = $wbemAuthenticationLevelPktPrivacy

    ; transform Hive name in Hive Hex numeric code
    Local $nHKEY
    Select
        Case $sPrefix = "HKEY_CLASSES_ROOT" Or $sPrefix = "HKCR"
            $nHKEY = 0x80000000
        Case $sPrefix = "HKEY_CURRENT_USER" Or $sPrefix = "HKCU"
            $nHKEY = 0x80000001
        Case $sPrefix = "HKEY_LOCAL_MACHINE" Or $sPrefix = "HKLM"
            $nHKEY = 0x80000002
        Case $sPrefix = "HKEY_USERS" Or $sPrefix = "HKU"
            $nHKEY = 0x80000003
        Case $sPrefix = "HKEY_CURRENT_CONFIG" Or $sPrefix = "HKCC"
            $nHKEY = 0x80000005
        Case Else
            Return SetError(4, 0, "") ; specified Hive not found
    EndSelect

    Local $aSubKeys, $aTypes
    $objReg.EnumValues($nHKEY, $sRegKeyPath, $aSubKeys, $aTypes)
;   the above methos should return 2 arrays ($aSubKeys and $aTypes)
;   but when the KeyPath to read contains only the default KeyValue
;   then it returns an empty string intead of the 2 arrays
;   so HOW TO KNOW THE KEYTYPE OF THE DEFAULT KEYVALUE

    If @error Then Return SetError(6, @error, "")
    Local Enum $iREG_SZ = 1, $iREG_EXPAND_SZ, $iREG_BINARY, $iREG_DWORD, $iREG_DWORD_BIG_ENDIAN, $iREG_LINK, $iREG_MULTI_SZ, $iREG_RESOURCE_LIST, $iREG_FULL_RESOURCE_DESCRIPTOR, $iREG_RESOURCE_REQUIREMENTS_LIST, $iREG_QWORD
    Local $i, $return

    For $i = 0 To UBound($aSubKeys) - 1
        If $aSubKeys[$i] = $sSearchValue Then
            Switch $aTypes[$i]
                Case $iREG_SZ
                    $objReg.GetStringValue($nHKEY, $sRegKeyPath, $sSearchValue, $return)
                    Return  $return
                Case $iREG_EXPAND_SZ
                    $objReg.GetExpandedStringValue($nHKEY, $sRegKeyPath, $sSearchValue, $return)
                    Return  $return
                Case $iREG_BINARY
                    $objReg.GetBinaryValue($nHKEY, $sRegKeyPath, $sSearchValue, $return)
                    Return  $return
                Case $iREG_DWORD
                    $objReg.GetDWORDValue($nHKEY, $sRegKeyPath, $sSearchValue, $return)
                    Return  $return
                Case $iREG_MULTI_SZ
                    $objReg.GetMultiStringValue($nHKEY, $sRegKeyPath, $sSearchValue, $return)
                    Return  $return
                Case $iREG_QWORD
                    $objReg.GetQWORDValue($nHKEY, $sRegKeyPath, $sSearchValue, $return)
                    Return  $return
            EndSwitch
        EndIf
    Next
    Return SetError(7, 0, "")
EndFunc   ;==>WMI_GetRemoteRegVal

Func ObjErrorHandler()
    ConsoleWrite("A COM Error has occured!" & @CRLF & @CRLF & _
            "err.description is: " & @TAB & $oErrorHandler.description & @CRLF & _
            "err.windescription:" & @TAB & $oErrorHandler & @CRLF & _
            "err.number is: " & @TAB & Hex($oErrorHandler.number, 8) & @CRLF & _
            "err.lastdllerror is: " & @TAB & $oErrorHandler.lastdllerror & @CRLF & _
            "err.scriptline is: " & @TAB & $oErrorHandler.scriptline & @CRLF & _
            "err.source is: " & @TAB & $oErrorHandler.source & @CRLF & _
            "err.helpfile is: " & @TAB & $oErrorHandler.helpfile & @CRLF & _
            "err.helpcontext is: " & @TAB & $oErrorHandler.helpcontext & @CRLF _
            )
EndFunc   ;==>ObjErrorHandler
Edited by Chimp

 

image.jpeg.9f1a974c98e9f77d824b358729b089b0.jpeg Chimp

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Link to comment
Share on other sites

Switch $aTypes[$i]
    Case Null

You can:

1 Add a dummy subkey, repeat EnumValues method (in this case the Default Type isn't NULL) and then delete the dummy subkey

Return RegRead($sPrefix & "\" & $sRegKeyPath, "")
Edited by j0kky
Link to comment
Share on other sites

Switch $aTypes[$i]
    Case Null

You can:

1 Add a dummy subkey, repeat EnumValues method (in this case the Default Type isn't NULL) and then delete the dummy subkey

Return RegRead($sPrefix & "\" & $sRegKeyPath, "")

 

Hi j0kky, thanks for your replies

 

Switch $aTypes[$i]
    Case Null
  •  this doesn't because the returned var $aTypes is not an array in that problematic case (this is my problem)

You can:

1 Add a dummy subkey, repeat EnumValues method (in this case the Default Type isn't NULL) and then delete the dummy subkey

  • this could be a workaround, but I would prefer a more "direct" method  (way) to get the data, also because if the "reader" of the registry has only read permissions and not write permission, then this way will fail.
Return RegRead($sPrefix & "\" & $sRegKeyPath, "")
  • this is the native AutoIt function, I have already used in other time,  but I can not use it in this case but I must use WMI way because it allows access to remote registry with different credentials in the way as shown here by >this nice template provided by UEZ

 

...anyway, appreciated yours three solutions proposed :)

thanks again

 

image.jpeg.9f1a974c98e9f77d824b358729b089b0.jpeg Chimp

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Link to comment
Share on other sites

• this doesn't because the returned var $aTypes is not an array in that problematic case (this is my problem)

Are you sure? Documentation says: "Returns null if only the default value is available" just referring to Types parameter...

Unfortunately I don't see other simple solutions that uses only WMI

Edited by j0kky
Link to comment
Share on other sites

Are you sure? Documentation says: "Returns null if only the default value is available" just referring to Types parameter...

Unfortunately I don't see other simple solutions that uses only WMI

 

Already checked with VarGetType()

normally it returns an Array, In the "problem" case it returns a blank string instead.

 

image.jpeg.9f1a974c98e9f77d824b358729b089b0.jpeg Chimp

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Link to comment
Share on other sites

 This method returns a null value for the array when the default value is the only one present. When writing scripts, be sure to check for the null value (using IsNull); this is a good practice before accessing any VBScript variant

You're right! I didn't read this part... So, you can check if the variable is Null before listing all the array cases... But I don't know hot to get its value only with WMI...

Edited by j0kky
Link to comment
Share on other sites

this is the native AutoIt function, I have already used in other time,  but I can not use it in this case but I must use WMI way because it allows access to remote registry with different credentials in the way as shown here by >this nice template provided by UEZ

In that case call LogonUser and ImpersonateLoggedOnUser before using built-in function.

♡♡♡

.

eMyvnE

Link to comment
Share on other sites

Line 56

$i is automatically declared at the For Loop.

Line 58

If $aSubKeys[$i] == $sSearchValue Then

If blank = blank then blank = 0

If blank == blank then blank = blank

blankity blank blank...

"The mediocre teacher tells. The Good teacher explains. The superior teacher demonstrates. The great teacher inspires." -William Arthur Ward

Link to comment
Share on other sites

In that case call LogonUser and ImpersonateLoggedOnUser before using built-in function.

 

Hi trancexx, thanks for your post

it sounds interesting.

Looks not difficult, (but it's not easy.... :unsure:)

I will try and look into the matter and will report here results....

Thanks again

 

image.jpeg.9f1a974c98e9f77d824b358729b089b0.jpeg Chimp

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Link to comment
Share on other sites

Line 56

$i is automatically declared at the For Loop.

Line 58

If $aSubKeys[$i] == $sSearchValue Then
If blank = blank then blank = 0

If blank == blank then blank = blank

blankity blank blank...

 

That's wrong, "" is only converted if comparing it to a number, if compared against "" they'd be equivalent.

== is used to do a case sensitive comparison of strings.

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Link to comment
Share on other sites

That's wrong, "" is only converted if comparing it to a number, if compared against "" they'd be equivalent.

== is used to do a case sensitive comparison of strings.

Thats assuming that default is blank and not something else.

"The mediocre teacher tells. The Good teacher explains. The superior teacher demonstrates. The great teacher inspires." -William Arthur Ward

Link to comment
Share on other sites

If Not IsArray($aSubKeys) Then Return ''

If Default is the only Valuename in the key, then no array is given. (most of the time)

If you write another Valuename in the key, then it will return the value of Default.

A bug in WMI for sure.

"The mediocre teacher tells. The Good teacher explains. The superior teacher demonstrates. The great teacher inspires." -William Arthur Ward

Link to comment
Share on other sites

@ripdad: Before returning, Chimp needs to know Default value, this is the issue.

Yes, I gave a dirty work-around for it.

1. Write another Valuename.

2. Get the value of (Default).

3. Delete the Valuename that was written.

4. Return the value of (Default).

"The mediocre teacher tells. The Good teacher explains. The superior teacher demonstrates. The great teacher inspires." -William Arthur Ward

Link to comment
Share on other sites

Thats assuming that default is blank and not something else.

That makes no sense, if it's empty then comparing it to and empty string is equal no matter which comparator you use. Which is what I said above, I'm not assuming anything, I'm just telling you that an empty string compared to an empty string is equal.

If it's not an empty string and a number is returned instead,  then the empty string will get converted to a number.You'd be better off just forcing everything to strings if you want to compare strings.

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Link to comment
Share on other sites

As far as I'm concerned, no conversion is necessary nor wanted.

Others have a different opinion -- though the logic escapes me.

Thats okay, I will adapt.

"The mediocre teacher tells. The Good teacher explains. The superior teacher demonstrates. The great teacher inspires." -William Arthur Ward

Link to comment
Share on other sites

$objReg.SetStringValue($nHKEY, $sRegKeyPath, 'TEST001', '0')
Local $aSubKeys, $aTypes
$objReg.EnumValues($nHKEY, $sRegKeyPath, $aSubKeys,$aTypes)
$objReg.DeleteValue($nHKEY, $sRegKeyPath, 'TEST001')

Assume @error -7 is no value, if no value is present in (Default).

Another bug -- or perhaps part of the same one.

It should return blank, no matter what.

It doesn't show up in the array.

In any case, if there is a value in (Default), then the

above code should work.

-edit-

That is, assuming you have write privilege.

Edited by ripdad

"The mediocre teacher tells. The Good teacher explains. The superior teacher demonstrates. The great teacher inspires." -William Arthur Ward

Link to comment
Share on other sites

Not a bug that I can see, it's converting the string to a number and trying to divide by 0. Whenever AutoIt does math, it assumes that what you're doing the math on is numeric, so it converts it to a number.

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...