Jump to content
Sign in to follow this  
LondonNDIB

Determine number of registry keys

Recommended Posts

LondonNDIB

Is there a faster, more direct way of determining the number of keys underneath a certain key? I've figured out this method:

Func _CountKeys ( $MainKey )
   For $i = 1 to 1000000
      RegEnumKey ( $MainKey, $i)
      If @ERROR <> 0 Then Return $i - 1
   Next
EndFunc

MsgBox ( "", "", "There are " & _CountKeys ( "HKEY_LOCAL_MACHINE\SOFTWARE" ) & " keys." )

And it works fine... I was just wondering if someone knew of a more direct way of doing it (ie. not having to resort to For $i = SomeGuessAtAnUpperBound)

LD

Edited by LondonNDIB

Share this post


Link to post
Share on other sites
GaryFrost

Is there a faster, more direct way of determining the number of keys underneath a certain key? I've figured out this method:

Func _CountKeys ( $MainKey )
   For $i = 1 to 1000000
      RegEnumKey ( $MainKey, $i)
      If @ERROR <> 0 Then Return $i - 1
   Next
EndFunc

MsgBox ( "", "", "There are " & _CountKeys ( "HKEY_LOCAL_MACHINE\SOFTWARE" ) & " keys." )

And it works fine... I was just wondering if someone knew of a more direct way of doing it (ie. not having to resort to For $i = SomeGuessAtAnUpperBound)

LD

Something to look at, no guessing at what limit to set a loop at.

http://www.autoitscript.com/forum/index.ph...st&p=220540


SciTE for AutoItDirections for Submitting Standard UDFs

 

Don't argue with an idiot; people watching may not be able to tell the difference.

 

Share this post


Link to post
Share on other sites
LondonNDIB

Thanks, but I'm afraid I don't follow what I'm supposed to be looking at. My eyes are going buggy looking at all that code.

I'm not a programmer :)

I think you're either suggesting I use that very long code to replace my relatively short code... or (more likely) you're saying there's something in there that will help me not have to use "For $i = 1 to 1000000"

But I can't follow your code well enough to figure out what that is.

I particularely get lost at :

Local $oReg = ObjGet("winmgmts:{impersonationLevel=impersonate}!\\" & $strComputer & "\root\default:StdRegProv")
    $oReg.EnumValues ($HKEY_LOCAL_MACHINE, $strKeyPath, $arrValueNames, $arrValueTypes)

where the help file for ObjGet is extremely ambiguous and there are no entries for "EnumValues" or even the code structure $var.SomeThing - which looks like it comes from a completely different language.

Thanks for helping though.

LD

Share this post


Link to post
Share on other sites
GaryFrost

Thanks, but I'm afraid I don't follow what I'm supposed to be looking at. My eyes are going buggy looking at all that code.

I'm not a programmer :)

I think you're either suggesting I use that very long code to replace my relatively short code... or (more likely) you're saying there's something in there that will help me not have to use "For $i = 1 to 1000000"

But I can't follow your code well enough to figure out what that is.

I particularely get lost at :

Local $oReg = ObjGet("winmgmts:{impersonationLevel=impersonate}!\\" & $strComputer & "\root\default:StdRegProv")
    $oReg.EnumValues ($HKEY_LOCAL_MACHINE, $strKeyPath, $arrValueNames, $arrValueTypes)

where the help file for ObjGet is extremely ambiguous and there are no entries for "EnumValues" or even the code structure $var.SomeThing - which looks like it comes from a completely different language.

Thanks for helping though.

LD

I realize this is longer, it was just something to look at, has error checking and also will let you type in the long path name or short path name.

Gary

ConsoleWrite(_RegEnumKeysCount("localhost", "HKLM", "Software") & @LF)

Func _RegEnumKeysCount($strComputer, $s_hDefKey, $strKeyPath)
    Local $hDefKey
    Enum $HKEY_CLASSES_ROOT = 0x80000000, $HKEY_CURRENT_USER, $HKEY_LOCAL_MACHINE, $HKEY_USERS, $HKEY_CURRENT_CONFIG = 0x80000005
    If $strComputer = "." Then $strComputer = @ComputerName
    Switch StringUpper($s_hDefKey)
        Case "HKEY_LOCAL_MACHINE", "HKLM"
            $hDefKey = $HKEY_LOCAL_MACHINE
        Case "HKEY_USERS", "HKU"
            $hDefKey = $HKEY_USERS
        Case "HKEY_CURRENT_USER", "HKCU"
            $hDefKey = $HKEY_CURRENT_USER
        Case "HKEY_CLASSES_ROOT", "HKCR"
            $hDefKey = $HKEY_CLASSES_ROOT
        Case "HKEY_CURRENT_CONFIG", "HKCC"
            $hDefKey = $HKEY_CURRENT_CONFIG
        Case Else
            Return SetError(1, 1, 0)
    EndSwitch
    Local $arrValueNames
    Local $oReg = ObjGet("winmgmts:{impersonationLevel=impersonate}!\\" & $strComputer & "\root\default:StdRegProv")
    $oReg.EnumKey ($hDefKey, $strKeyPath, $arrValueNames)
    If Not IsArray($arrValueNames) Then Return SetError(2, 2, 0)
    Return UBound($arrValueNames)
EndFunc   ;==>_RegEnumKeysCount

Edit: missed changing a variable name in the EnumKey function call

Edited by gafrost

SciTE for AutoItDirections for Submitting Standard UDFs

 

Don't argue with an idiot; people watching may not be able to tell the difference.

 

Share this post


Link to post
Share on other sites
LondonNDIB

Please realize my level of experience is no way NEAR what yours is :)

I appreciate the example.

How can I do what I'm trying to do (simply return the number of keys) without having to guess at the boundary?

I'm guess it has to do with your line with the term "enumKey" in it.

Am I correct in saying that your script is directly communicating with the Windows registry program to determine the number? Is "EnumKey" then a function that is available to the registry program, and not something within AutoIt? Is "winmgmts" the registry?

Thanks.

Share this post


Link to post
Share on other sites
GaryFrost

Please realize my level of experience is no way NEAR what yours is :)

I appreciate the example.

How can I do what I'm trying to do (simply return the number of keys) without having to guess at the boundary?

I'm guess it has to do with your line with the term "enumKey" in it.

Am I correct in saying that your script is directly communicating with the Windows registry program to determine the number? Is "EnumKey" then a function that is available to the registry program, and not something within AutoIt? Is "winmgmts" the registry?

Thanks.

Suggest running what I posted (I cleaned it up a bit, removed un-needed code).

It's wmi.

Forgot to mention, also will work with remote registry on systems that have wmi service.

Edited by gafrost

SciTE for AutoItDirections for Submitting Standard UDFs

 

Don't argue with an idiot; people watching may not be able to tell the difference.

 

Share this post


Link to post
Share on other sites
LondonNDIB

OOohhh... I see now, you created a _RegEnumKeysCount for me! Thank you! Sorry, I thought you had pasted your code from the linked thread. Wow, you're fast.

It works perfectly, thank you.

Now I'm going to spend the rest of the day reading up on WMI :)

LD

Share this post


Link to post
Share on other sites
LondonNDIB

Hmm... well, almost perfect :)

If I call it with HKCC (nothing else changed) it should return 2, but it returns 0

My function correctly returns 2 in that example.

I'm sure its something small.

Why use 0x80000000 (and increments thereafter) instead of the strings?

LD

Share this post


Link to post
Share on other sites
GaryFrost

Hmm... well, almost perfect :)

If I call it with HKCC (nothing else changed) it should return 2, but it returns 0

My function correctly returns 2 in that example.

I'm sure its something small.

Why use 0x80000000 (and increments thereafter) instead of the strings?

LD

I might have something wrong on that one, I tried "HKCU" and it worked with "Software"

I did that a long time ago, will have to research on it again.


SciTE for AutoItDirections for Submitting Standard UDFs

 

Don't argue with an idiot; people watching may not be able to tell the difference.

 

Share this post


Link to post
Share on other sites
GaryFrost

Enum $HKEY_CLASSES_ROOT = 0x80000000, $HKEY_CURRENT_USER, $HKEY_LOCAL_MACHINE, $HKEY_USERS, $HKEY_CURRENT_CONFIG = 0x80000005

http://msdn2.microsoft.com/en-us/library/aa393600.aspx

Edited by gafrost

SciTE for AutoItDirections for Submitting Standard UDFs

 

Don't argue with an idiot; people watching may not be able to tell the difference.

 

Share this post


Link to post
Share on other sites
LondonNDIB

I wonder why they skipped one.

Share this post


Link to post
Share on other sites
GaryFrost

I wonder why they skipped one.

Was wondering the same thing, but then it is MS......


SciTE for AutoItDirections for Submitting Standard UDFs

 

Don't argue with an idiot; people watching may not be able to tell the difference.

 

Share this post


Link to post
Share on other sites
LondonNDIB

Its probably the one bit of code obsurity that allows them to not be sued for copying Mac.

Share this post


Link to post
Share on other sites
PartyPooper

How about something like the following. One uses a WHILE loop, the other a DO loop. Neither require you to specify a particular number of keys to scan for but both will report the number of keys found under them.

$MainKey = "HKEY_CURRENT_USER\Software"
$i = 1
   While @error = 0
        $var = RegEnumKey ( $MainKey, $i)
        $i += 1
   WEnd

MsgBox(0,'','There are ' & $i-2 & ' keys under "' & $MainKey & '".' )

$MainKey = "HKEY_CURRENT_USER\Software"
$i = 1
    Do
        $var = RegEnumKey ( $MainKey, $i)
        $i += 1
    Until @error <> 0
MsgBox(0,'','There are ' & $i-2 & ' keys under "' & $MainKey & '".' )

Share this post


Link to post
Share on other sites
LondonNDIB

That's great PartyPooper! Thank you. Its a lot like what I came up with, but without the part I didn't like (guessing at the ubound)!

Share this post


Link to post
Share on other sites
PartyPooper

Glad to help.

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  

×