AutoHotkey Homepage AutoHotkey Community
Let's help each other out
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

SplitPath for Registry values and improved RegRead

 
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Wish List
View previous topic :: View next topic  
Author Message
pajenn



Joined: 07 Feb 2009
Posts: 345

PostPosted: Sun May 03, 2009 2:12 pm    Post subject: SplitPath for Registry values and improved RegRead Reply with quote

I think AHK would benefit from an expanded SplitPath function or a separate SplitValue function that could automatically split a registry path into: root key, sub key, value name and value.

Also, I hope RegRead can be improved to 1) keep spaces in REG_BINARY values, and 2) retrieve REG_DWORD values in hexadecimal format (with all zeroes included).

Note: Using "SetFormat, IntegerFast, H" is not enough for 2) because it drops some of the zeroes. For example, 0x00000000 would be read as 0x0, which throws off any comparison checks, etc.

I wrote the following function to convert AHK regread output, into the format that I see when look at values with regedit or another registry editor. I'm sure the function is not efficient, in fact, I only used a reg loop to be able to get A_LoopRegType for a specific value per loop, but I'm attaching to clarify what I mean.

Code:
RegValConvert(root="",sub="",vname="")
{
  Loop, %root%, %sub%
  {
    If A_LoopRegName = %vname%
    {
      If A_LoopRegType = REG_DWORD
      {
        SetFormat, IntegerFast, H
        RegRead, valNow2, %root%, %sub%, %vname%
        If SubStr(valNow2,1,2) = "0x"
        {
          If StrLen(valNow2) != 10
          {
            SetFormat, IntegerFast, D
            valNow:= "0x"
            loop, % 10-StrLen(valNow2)
            {
              valNow.= "0"
            }
            valNow.= SubStr(valNow2, 3)
            valNow2=
          }
        }
      }
      Else If A_LoopRegType = REG_BINARY
      {
        RegRead, valNow, %root%, %sub%, %vname%
        loop, parse, valNow  ;  correct how RegRead gets the data
        {
          If (A_Index = 1)
            valNow =
          valNow .= A_LoopField
          If !Mod(A_Index,2)
            valNow .=  " "
        }
        If SubStr(valNow,0,1) = " "
          StringLeft,valNow,valNow,% StrLen(valNow)-1
      }
      Else
        RegRead, valNow, %root%, %sub%, %vname%
      Break
    }
  }
  Return valNow
}


p.s. kudos to jenn for the mod2 piece of code.
_________________
Hardware: 1.8 GHz laptop with 4 GB ram
Software: Windows XP/SP3, Rising Antivirus, Online Armor firewall, Dragon NaturallySpeaking Pro + Natlink (with Vocola/Unimacro) and AHK for macro support.
Back to top
View user's profile Send private message
pajenn



Joined: 07 Feb 2009
Posts: 345

PostPosted: Sun May 03, 2009 2:40 pm    Post subject: Reply with quote

also, fwiw, here the function i wrote to split registry value paths, though I assume it's not very well written:

Code:
RegEntrySplit(RegString="")
{
  bslash:= InStr(RegString, "\" )
  global root:= SubStr(RegString, 1, bslash-1), sub:= SubStr(RegString, bslash+1)
  If colon:= InStr(sub, ":" )
  {
    global val:= SubStr(sub, colon+2),valNow:=""
    If SubStr(val,1,1) = """" && SubStr(val, 0,1) = """"
      StringMid,val,val,2,% StrLen(val)-2  ;remove excess "
       
    sub:= SubStr(sub, 1, colon-1)
    bslash:= InStr(sub,"\",false,0)
       
    global vname:= SubStr(sub, bslash+1)
    sub:= SubStr(sub, 1, bslash-1)
       
    RegRead, valNow, %root%, %sub%, %vname%
    If !valNow
      Return 0
    Else
      Return root "\" sub "\" vname ": " val "`n" valNow
  }
  Else
  {
    Loop %root%, %sub%, 1, 1  ; checks if key exists
      keycount++
    If (keycount > 0)
      Return root "`n" sub
    Else
      Return 0
  }
}


p.s. do all REG_DWORD hex values start with 0x?
_________________
Hardware: 1.8 GHz laptop with 4 GB ram
Software: Windows XP/SP3, Rising Antivirus, Online Armor firewall, Dragon NaturallySpeaking Pro + Natlink (with Vocola/Unimacro) and AHK for macro support.
Back to top
View user's profile Send private message
Lexikos



Joined: 17 Oct 2006
Posts: 4367
Location: Qld, Australia

PostPosted: Mon May 04, 2009 10:28 am    Post subject: Re: SplitPath for Registry values and improved RegRead Reply with quote

pajenn wrote:
Also, I hope RegRead can be improved to 1) keep spaces in REG_BINARY values, and 2) retrieve REG_DWORD values in hexadecimal format (with all zeroes included).
AutoHotkey represents binary values as strings of hexadecimal digits. The spaces shown in regedit are purely for display purposes and are not stored in the registry, so they cannot be "kept". Similarly, REG_DWORD values are 32-bit unsigned integers (i.e. double-words), which are purely numbers with no formatting information.
Quote:
Note: Using "SetFormat, IntegerFast, H" is not enough for 2) because it drops some of the zeroes. For example, 0x00000000 would be read as 0x0, which throws off any comparison checks, etc.
What sort of comparison checks? Format is not relevant for numerical comparisons such as regvalue != 0x1 or regvalue > 123. The expression (0 = 0x0000) is always true.

There are ways to do what you want without looping:
Code:
regvalue := "0x0123"

; Format integer as hexadecimal, padding with 0 up to 8 digits.
VarSetCapacity(display,20)
DllCall("msvcrt\sprintf", "str", display, "str", "0x%08x", "uint", regvalue)
MsgBox % display

; Alternate method.
SetFormat, IntegerFast, H
MsgBox % "0x" SubStr("00000000" SubStr(regvalue+0, 3), -7)
Code:
regvalue := "ABCDEF"
; Insert a space every two characters (except at the end).
MsgBox % RegExReplace(regvalue, "..(?=.)", "$0 ")
Back to top
View user's profile Send private message Visit poster's website
pajenn



Joined: 07 Feb 2009
Posts: 345

PostPosted: Mon May 04, 2009 12:57 pm    Post subject: Re: SplitPath for Registry values and improved RegRead Reply with quote

Lexikos wrote:
What sort of comparison checks? Format is not relevant for numerical comparisons such as regvalue != 0x1 or regvalue > 123. The expression (0 = 0x0000) is always true.


I take a pre- and post-installation snapshot with RegShot, and after uninstalling a program I go over the log using AHK. My script checks if the log entries (files or registry values) still exist, and if so whether they are the same as in the log. The log shows these values the way they appear in regedit, so comparisons for REG_BINARIES and REG_DWORD entries fail unless I first adjust RegRead (or RegShot) output.

Quote:
There are ways to do what you want without looping:


The loop is to get the type (a_LoopRegType) for the value. That's how AHK's help file example (for RegRead) suggests to determine the type for a registry entry.

edit1: sorry, the 'redundant' loop i referred to in my original post was the reg loop that loops through a key to get type for one value, but i realized the loop you referred to was different, and your method's definately better - thanks for the improvement.

From help file:

Code:
RegKeyType(RootKey, SubKey, ValueName)  ; This function returns the type of the specified value.
{
    Loop, %RootKey%, %SubKey%
        if (A_LoopRegName = ValueName)
            return A_LoopRegType
    return "Error"
}


Thank you for the code. The alternate method was three times faster (in a single benchmark I ran), so I replaced my original code with it:

Code:
regvalue := "0x0123"

; Format integer as hexadecimal, padding with 0 up to 8 digits.
VarSetCapacity(display,20)
DllCall("msvcrt\sprintf", "str", display, "str", "0x%08x", "uint", regvalue)
MsgBox % display

; Alternate method.
SetFormat, IntegerFast, H
MsgBox % "0x" SubStr("00000000" SubStr(regvalue+0, 3), -7)


This method doesn't appear to work for longer strings.<snip>

edit2: works great, sorry, my bad applying the code initially. Thanks again.

Code:
;regvalue := "ABCDEF"
; Insert a space every two characters (except at the end).
MsgBox % RegExReplace(regvalue, "..(?=.)", "$0 ")


To your overall point though: I suppose I was too quick to judge AHK's RegRead format. I thought RegShot logs were more correct because that's how the registry values appear (visually) in regedit, but I suppose I need to change my If-statements to compare the underlying values of each representation rather than their forms.
_________________
Hardware: 1.8 GHz laptop with 4 GB ram
Software: Windows XP/SP3, Rising Antivirus, Online Armor firewall, Dragon NaturallySpeaking Pro + Natlink (with Vocola/Unimacro) and AHK for macro support.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Wish List All times are GMT
Page 1 of 1

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum


Powered by phpBB © 2001, 2005 phpBB Group