Jump to content
Sign in to follow this  
Chimp

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

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

Share this post


Link to post
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

Share this post


Link to post
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


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

Share this post


Link to post
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

Share this post


Link to post
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.


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

Share this post


Link to post
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

Share this post


Link to post
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.

Share this post


Link to post
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

Share this post


Link to post
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


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

Share this post


Link to post
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

Share this post


Link to post
Share on other sites

As I understood, that line can be deleted, in case there is only Default subkey, aSubKeys is not an array and the entire For...Next loop generates an error

Share this post


Link to post
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

Share this post


Link to post
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

Share this post


Link to post
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

Share this post


Link to post
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

Share this post


Link to post
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

Share this post


Link to post
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

Share this post


Link to post
Share on other sites

BrewManNH,

The last one is kinda cool. It looks like a "conversion" bug.

MsgBox(0, '', '' = '')
MsgBox(0, '', '' = 0)
MsgBox(0, '', '' < 1)
MsgBox(0, '', '' > -1)
MsgBox(0, '', '' / 0)

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

Share this post


Link to post
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

Share this post


Link to post
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
Sign in to follow this  

  • Similar Content

    • By Dwalfware
      HI
      Another head scratched
      Anyone solve how to get the IPV6 from WMI?
      I followed the usual SELECT * FROM Win32_NetworkAdapter WHERE NetConnectionID='" & GUICtrlRead($cboAdapters) & "'
      get the index 
      port it to 
      Local $query = $objWMIService.ExecQuery("SELECT * FROM Win32_NetworkAdapterConfiguration WHERE Index = " & _GetSelectedNIC(), "WQL", 0x30 )
      All i can see is IPv4 addresses
      My question is is there another place the IPv6 information is hiding? I configured my LAN with IPV6 and my wireless with IPv4 so I can see what shows.
      Thanks in Advance.
      PS. I did try google
       
    • By Dwalfware
      Hi Folks
      Can not get my head around this one.
      This function gets the DNS object s
      If you have two DNS entries fine. but if you have only one! Trouble
      $objItem.DNSServerSearchOrder[0] = Primary DNS
      $objItem.DNSServerSearchOrder[1] = Secondry DNS not always there. I need a way to return 0 if not there or the IP if its there.
      Or is there a way to tell how many objects there are in the "[?]"
      I'm terrible at WMI errors, thanks for help in advance.
      Func _GETcurrentNICinfo2() $oErrors = ObjEvent("AutoIt.Error", "Error_Handle") Local $DnsSecondry Local $objWMIService = ObjGet( "winmgmts:\\" & @ComputerName & "\root\CIMV2" ) Local $query = $objWMIService.ExecQuery("SELECT DNSServerSearchOrder FROM Win32_NetworkAdapterConfiguration WHERE Index = " & _GetSelectedNIC(), "WQL", 0x30 ) If @error Then Return 0 If NOT IsObj($query) Then Return 0 Else For $objItem In $query Return $objItem.DNSServerSearchOrder[1] next Endif EndFunc  
    • By copyleft
      I've looked at a bunch of SetACL examples on this site and none seem to be able to convert this batch script into a working AutoIt script.
      BATCH
      @echo off "%~dp0setacl.exe" -on "HKEY_CLASSES_ROOT\CLSID\{9C60DE1E-E5FC-40f4-A487-460851A8D915}\DefaultIcon" -ot reg -actn setowner -ownr n:administrators >nul 2>nul "%~dp0setacl.exe" -on "HKEY_CLASSES_ROOT\CLSID\{9C60DE1E-E5FC-40f4-A487-460851A8D915}\DefaultIcon" -ot reg -actn ace -ace "n:administrators;p:full" >nul 2>nul Reg.exe add "HKCR\CLSID\{9C60DE1E-E5FC-40f4-A487-460851A8D915}\DefaultIcon" /ve /t REG_EXPAND_SZ /d "C:\My.ico" /f NON-WORKING AUTOIT
      RunWait('setacl.exe "HKCR64\CLSID\{9C60DE1E-E5FC-40f4-A487-460851A8D915}\DefaultIcon" -ot reg -actn setowner -ownr "n:administrators"') RunWait('setacl.exe "HKCR64\CLSID\{9C60DE1E-E5FC-40f4-A487-460851A8D915}\DefaultIcon" -ot reg -actn setowner -ownr "n:administrators;p:full"') RegWrite('HKCR64\CLSID\{9C60DE1E-E5FC-40f4-A487-460851A8D915}\DefaultIcon', '','REG_EXPAND_SZ','C:\Windows\My.ico') Any ideas on what I'm doing wrong?
       
    • By GeorgeB
      I'm writing a little applet that basically tells you when Windows was installed.  There is a REG_DWORD in Windows that gives you this. It's basically a value that is the # of seconds from 1970.
      The location is:  "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\InstallDate"
      So if I run this in AutoIT, I should get the value displayed within the msgbox:
      MsgBox($MB_SYSTEMMODAL, "InstallDate Test", RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion", "InstallDate"))
      However, what happens is it always returns a value of "0"  I tried this on several machines (Windows 8, Windows 8.1 and Windows 10). 
      Am I missing something?  If I manually view this REG_DWORD with RegEdit, it shows me the HEX value, or I can view the Decimal value. I don't care which value AutoIT reads, as I can always convert back and forth, but I just don't see why it can't read a value from this REG_DWORD.  As a test, I've read other REG_DWORD values, and with most it doesn't return any value, not even a 0.
      Please, even if you guys have some other (perhaps better) way to read the Windows install date, I would still like to find a resolution to this problem, because I want to understand why I am having so much difficulty with reading REG_DWORD values from the Windows Registry with AutoIT.
      Thanks for any help!
       
       
       
       
       
    • By leomoon
      Hello,
      I'm having trouble getting information from Win32_Processor:
      https://docs.microsoft.com/en-us/windows/desktop/CIMWin32Prov/win32-processor
      How does this WMI Query work? Let's say I need to query VMMonitorModeExtensions, Level, ProcessorId, and ProcessorType.
      How would this work?
      Thanks.
×
×
  • Create New...