Registry-Funktionen

  • Hallo Leute,

    was mache ich falsch? Wenn ich die Funktion "_GetRegValues($HKEY)" von BugFix "Registry-Funktionen per Objekt " nutze erhalte ich bei den meisten Einträgen keinen Wert. Hier der zusammengestrickter Code:

    Spoiler anzeigen
    [autoit]

    #include<Array.au3>
    Local $regpath = 'HKEY_CURRENT_USER\SOFTWARE\Microsoft\Office\Common\Smart Tag'
    ;~ Local $regpath = 'HKEY_CURRENT_USER\Software\AutoIt v3\Au3Info'

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ; Versuch 1
    Local $ar = _GetRegValues($regpath) ; Ermittelt alle Namen, Typen und Werte in einem gegebenen Schlüssel
    If IsArray($ar) Then
    _ArrayDisplay($ar, 'Values von ' & $regpath)
    Else
    MsgBox(0, '', 'Fehler')
    EndIf
    ; bringt fast keine Werte unter Col2
    ; --> was mache ich falsch?

    [/autoit] [autoit][/autoit] [autoit]

    ; Versuch 2
    $REV = RegEnumVal($regpath, 1)
    $RR = RegRead($regpath, $REV)
    If @error Then
    ConsoleWrite('Fehler: ' & @error & @LF)
    Else
    ConsoleWrite($REV & ':' & $RR & @LF)
    EndIf
    ; bringt nur den dezimalen Wert
    ; --> wie erhalte ich den hexadezimalen Wert?
    ; --> aus der Hilfe werde ich in diesem Fall nicht schlau

    [/autoit] [autoit][/autoit] [autoit]

    ; Versuch 3
    $REV = RegEnumVal($regpath, 1)
    $RRB = _RegReadBinary($regpath, $REV)

    [/autoit] [autoit][/autoit] [autoit]

    If @error Then
    ConsoleWrite('Fehler: ' & @error & @LF)
    Else
    ConsoleWrite($REV & ':' & $RRB & @LF)
    EndIf
    ; den Wert kann ich garnicht deuten
    ; --> auch hier möchte ich den hexadezimalen Wert wie ihn der Regiestrierungs-Editor ausgibt

    [/autoit] [autoit][/autoit] [autoit]

    ;========================================================================================
    ; Function Name: _GetRegSubKeys($HKEY)
    ; Description: Ermittelt die Unterschlüssel für den übergebenen Schlüssel
    ; Parameter(s): $HKEY der Registryschlüssel
    ; Return Value(s): Erfolg Array mit den Unterschlüsseln
    ; Fehler Leerstring (keine Unterschlüssel vorhanden oder Schlüssel existiert nicht)
    ; Author(s): BugFix ([email='bugfix@autoit.de'][/email])
    ;========================================================================================
    Func _GetRegSubKeys($HKEY)
    If StringInStr($HKEY, '\') Then
    If StringRight($HKEY, 1) = '\' Then
    $HKEY = StringTrimRight($HKEY, 1)
    Local $strKeyPath = ''
    Else
    Local $strKeyPath = StringRight($HKEY, StringLen($HKEY)-StringInStr($HKEY, '\') )
    $HKEY = StringLeft($HKEY, StringInStr($HKEY, '\')-1)
    EndIf
    Else
    Local $strKeyPath = ''
    EndIf
    Select
    Case $HKEY = "HKEY_LOCAL_MACHINE" Or $HKEY = "HKLM"
    $HKEY = 0x80000002
    Case $HKEY = "HKEY_USERS" Or $HKEY = "HKU"
    $HKEY = 0x80000003
    Case $HKEY = "HKEY_CURRENT_USER" Or $HKEY = "HKCU"
    $HKEY = 0x80000001
    Case $HKEY = "HKEY_CLASSES_ROOT" Or $HKEY = "HKCR"
    $HKEY = 0x80000000
    Case $HKEY = "HKEY_CURRENT_CONFIG" Or $HKEY = "HKCC"
    $HKEY = 0x80000005
    EndSelect
    Local $arrSubKeys = '', $subkey
    Local $oReg = ObjGet("winmgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv")
    $oReg.EnumKey ($HKEY, $strKeyPath, $arrSubKeys)
    Return $arrSubKeys
    EndFunc ;==>_GetRegSubKeys

    [/autoit] [autoit][/autoit] [autoit]

    ;========================================================================================
    ; Function Name: _GetRegRights($HKEY)
    ; Description: Ermittelt die Rechte des Abfragenden für den übergebenen Schlüssel
    ; Parameter(s): $HKEY der zu prüfende Registryschlüssel
    ; Return Value(s): String mit Auflistung der Rechte:
    ; Q Key Query Value
    ; S Key Set Value
    ; C Key Create Sub Key
    ; D Delete
    ; Author(s): BugFix ([email='bugfix@autoit.de'][/email])
    ;========================================================================================
    Func _GetRegRights($HKEY)
    Local $bHasAccessRight, $sRights = ''
    If StringInStr($HKEY, '\') Then
    If StringRight($HKEY, 1) = '\' Then
    $HKEY = StringTrimRight($HKEY, 1)
    Local $strKeyPath = ''
    Else
    Local $strKeyPath = StringRight($HKEY, StringLen($HKEY)-StringInStr($HKEY, '\') )
    $HKEY = StringLeft($HKEY, StringInStr($HKEY, '\')-1)
    EndIf
    Else
    Local $strKeyPath = ''
    EndIf
    Select
    Case $HKEY = "HKEY_LOCAL_MACHINE" Or $HKEY = "HKLM"
    $HKEY = 0x80000002
    Case $HKEY = "HKEY_USERS" Or $HKEY = "HKU"
    $HKEY = 0x80000003
    Case $HKEY = "HKEY_CURRENT_USER" Or $HKEY = "HKCU"
    $HKEY = 0x80000001
    Case $HKEY = "HKEY_CLASSES_ROOT" Or $HKEY = "HKCR"
    $HKEY = 0x80000000
    Case $HKEY = "HKEY_CURRENT_CONFIG" Or $HKEY = "HKCC"
    $HKEY = 0x80000005
    EndSelect
    Local $oReg = ObjGet("winmgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv")
    $oReg.CheckAccess($HKEY, $strKeyPath, 0x0001, $bHasAccessRight)
    If $bHasAccessRight = True Then $sRights &= 'Q'
    $oReg.CheckAccess($HKEY, $strKeyPath, 0x0002, $bHasAccessRight)
    If $bHasAccessRight = True Then $sRights &= 'S'
    $oReg.CheckAccess($HKEY, $strKeyPath, 0x0004, $bHasAccessRight)
    If $bHasAccessRight = True Then $sRights &= 'C'
    $oReg.CheckAccess($HKEY, $strKeyPath, 0x00010000, $bHasAccessRight)
    If $bHasAccessRight = True Then $sRights &= 'D'
    Return $sRights
    EndFunc ;==>_GetRegRights

    [/autoit] [autoit][/autoit] [autoit]

    ;========================================================================================
    ; Function Name: _GetRegValues($HKEY)
    ; Description: Ermittelt alle Namen, Typen und Werte in einem gegebenen Schlüssel
    ; Parameter(s): $HKEY der Registryschlüssel
    ; Return Value(s): Erfolg Array[i][0] = Name
    ; Array[i][1] = Typ
    ; Array[i][2] = Wert
    ; Fehler Leerstring (Schlüssel existiert nicht oder ist ohne Einträge)
    ; Author(s): BugFix ([email='bugfix@autoit.de'][/email])
    ;========================================================================================
    Func _GetRegValues($HKEY)
    Local $oMyError = ObjEvent("AutoIt.Error","MyErrFunc")
    If StringInStr($HKEY, '\') Then
    If StringRight($HKEY, 1) = '\' Then
    $HKEY = StringTrimRight($HKEY, 1)
    Local $strKeyPath = ''
    Else
    Local $strKeyPath = StringRight($HKEY, StringLen($HKEY)-StringInStr($HKEY, '\') )
    $HKEY = StringLeft($HKEY, StringInStr($HKEY, '\')-1)
    EndIf
    Else
    Local $strKeyPath = ''
    EndIf
    Select
    Case $HKEY = "HKEY_LOCAL_MACHINE" Or $HKEY = "HKLM"
    $HKEY = 0x80000002
    Case $HKEY = "HKEY_USERS" Or $HKEY = "HKU"
    $HKEY = 0x80000003
    Case $HKEY = "HKEY_CURRENT_USER" Or $HKEY = "HKCU"
    $HKEY = 0x80000001
    Case $HKEY = "HKEY_CLASSES_ROOT" Or $HKEY = "HKCR"
    $HKEY = 0x80000000
    Case $HKEY = "HKEY_CURRENT_CONFIG" Or $HKEY = "HKCC"
    $HKEY = 0x80000005
    EndSelect
    Local $oReg = ObjGet("winmgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv")
    Local $arrValueNames, $arrValueTypes, $strValue
    $oReg.EnumValues($HKEY, $strKeyPath, $arrValueNames, $arrValueTypes)
    $OEvent = ObjEvent($oReg, "EnumValues")
    If Not IsArray($arrValueNames) Then Return ''
    Local $arOut[UBound($arrValueNames)][3]
    For $i = 0 To UBound($arrValueNames) -1
    $arOut[$i][0] = $arrValueNames[$i]
    Switch $arrValueTypes[$i]
    Case 1
    $arOut[$i][1] = 'REG_SZ'
    $oReg.GetStringValue($HKEY, $strKeyPath, $arrValueNames[$i], $strValue)
    Case 2
    $arOut[$i][1] = 'REG_EXPAND_SZ'
    $oReg.GetExpandedStringValue($HKEY, $strKeyPath, $arrValueNames[$i], $strValue)
    Case 3
    $arOut[$i][1] = 'REG_BINARY'
    $oReg.GetBinaryValue($HKEY, $strKeyPath, $arrValueNames[$i], $strValue)
    Case 4
    $arOut[$i][1] = 'REG_DWORD'
    $oReg.GetStringValue($HKEY, $strKeyPath, $arrValueNames[$i], $strValue)
    Case 7
    $arOut[$i][1] = 'REG_MULTI_SZ'
    $oReg.GetMultiStringValue($HKEY, $strKeyPath, $arrValueNames[$i], $strValue)
    EndSwitch
    $arOut[$i][2] = $strValue
    Next
    Return $arOut
    EndFunc ;==>_GetRegValues

    [/autoit] [autoit][/autoit] [autoit]

    Func MyErrFunc()
    Return
    Endfunc

    [/autoit] [autoit][/autoit] [autoit]

    Func _RegReadBinary($KEY, $VALUE)
    If $KEY = '' Or $VALUE = '' Then Return SetError(4,0,1)
    Local $reg = RegRead($KEY, $VALUE)
    Local $err = @error, $ext = @extended
    If $err Then Return SetError($err,0,1)
    If $ext <> 3 Then Return $reg
    Local $val = ''
    For $i = 1 To StringLen($reg) - 2 Step 2
    $tmp = BinaryToString('0x' & StringMid($reg, $i, 2))
    If $tmp <> "" Then
    $val = $val & $tmp
    EndIf
    Next
    Return $val
    EndFunc ;==>_RegReadBinary

    [/autoit]


    Des weiteren habe ich mit den Standard-Functionen versucht weiter zu kommen, jedoch habe ich es bis jetzt nicht geschaft den hexadezimalen Wert zu erhalten. Auch mit der Function _RegReadBinary($KEY, $VALUE)von BugFix bin ich nicht weitergekommen. Zur Konntrolle, wass ich erwarte habe ich einen Export aus dem Registrierungs-Editor ausgeführt. Der Export sieht so aus:

    Spoiler anzeigen

    [HKEY_CURRENT_USER\Software\Microsoft\Office\Common\Smart Tag]
    "migratedBitValues"=hex:01,00,00,00

    Spoiler anzeigen

    [HKEY_CURRENT_USER\Software\AutoIt v3\AU3Info]
    "WinX"=dword:00000200
    "WinY"=dword:00000000
    "WinW"=dword:00000200
    "WinH"=dword:00000258
    "ColorMode"=dword:00000001
    "CoordMode"=dword:00000001
    "HighlightControls"=dword:00000000
    "Magnify"=dword:00000000
    "AlwaysOnTop"=dword:00000001
    "HighlightColor"=dword:00000000
    "LastTab"=dword:00000006

    MfG Jescho

    Jeder hat mal klein angefangen - aber nicht jeder kommt groß raus!

  • Moin,

    ?
    [autoit]

    #include <Array.au3>
    #include <Constants.au3>
    Global $RegPath1 = "HKEY_CURRENT_USER\SOFTWARE\Microsoft\Office\Common\Smart Tag"
    Global $RegPath2 = "HKEY_CURRENT_USER\Software\AutoIt v3\Au3Info"

    [/autoit] [autoit][/autoit] [autoit]

    $aReg = _EnumRegVal($RegPath1)
    _ArrayDisplay($aReg)
    $aReg = _EnumRegVal($RegPath2)
    _ArrayDisplay($aReg)
    Exit

    [/autoit] [autoit][/autoit] [autoit]

    Func _EnumRegVal($RegPath)
    Local $RegTypes[8] = ["REG_NONE", "REG_SZ", "REG_EXPAND_SZ", "REG_BINARY", "REG_DWORD", "", "", "REG_MULTI_SZ"]
    Local $RegValue = ""
    Local $Instance = 1
    Local $aResult[256][3] = [[0, 0, 0]]
    Local $Reg = ""
    Local $Ext = ""
    While True
    $RegValue = RegEnumVal($RegPath, $Instance)
    If @error Then ExitLoop
    $Reg = RegRead($RegPath, $RegValue)
    If @error Then ExitLoop
    $Ext = @extended
    If $Ext = $REG_BINARY Then
    $Reg = StringToBinary(BinaryToString($Reg))
    EndIf
    $aResult[0][0] = $Instance
    $aResult[$Instance][0] = $RegValue
    $aResult[$Instance][1] = $RegTypes[$Ext]
    $aResult[$Instance][2] = $Reg
    $Instance += 1
    WEnd
    ReDim $aResult[$Instance][3]
    Return $aResult
    EndFunc

    [/autoit]
  • :rock: Danke.

    Jedoch bleibt noch die Frage mit den hexadezimalen Wert. Warum wird im Export vom Regitrierungs-Editors überhaupt der hexadetimale Wert gespeichert? ?(

    MfG Jescho

    Jeder hat mal klein angefangen - aber nicht jeder kommt groß raus!

  • Moin,

    es gibt ja einen Grund für die verschiedenen Eintragstypen, sie beschreiben den Inhalt. Die "SZ"-Typen beinhalten Text. Ein "DWORD" enthält eine Zahl mit 4 Byte Länge, deshalb kann man es mit Regedit wahlweise dezimal oder hexadezimal eingeben. Der Inhalt von "BINARY"s ist dagegen nicht "typisiert", sie können einen beliebigen Inhalt variabler Länge haben und auch an beliebigen stellen Nullbytes enthalten. Sie können mit Regedit nur im Hexadezimalformat bearbeitet werden und werden deshalb auch in diesem Format exportiert. Es wäre auch recht schwierig, die Nullbytes anders darzustellen. ;)

    Deinen speziellen Problemwert hätte man allerdings auch als "DWORD" anlegen können, er enthält ja genau 4 Bytes. Warum es ein "BINARY" ist, weiß wohl nur der Programmierer.

  • Moin,

    auch wenn sich das System Registry sich mir noch nicht ganz erschlossen hat so ist doch etwas Licht ins Dunkle gelangt. Ich habe den Code auch schon erweitert, so dass er mir den kompletten Zweig ausliest. Vielen Dank erstmal. Was mich noch interressiert, ich möchte gerne einen kompletten Reg-Zweig als Datei sichern und auf anderen Rechnern wiederherstellen. Muss ich dabei beim auslesen/speichern/wiederherstellen etwas besonderes beachten?

    MfG Jescho

    Jeder hat mal klein angefangen - aber nicht jeder kommt groß raus!

  • Und warum nicht Fehlermeldung?

    Pfad angepasst, also mit Deinem gewünschten Pfad versucht?
    32/64Bit berücksichtigt?

    #requireadmin?

    regedit per GPO verboten?

    Das in einer Schleife zu exportieren ist auf jedenfall etwas langsamer und aufwendiger. :(
    Wie Du siehst Fragen über Fragen... und warum :)

    Also lass Dir helfen und antworte etwas ausführlilcher.

    Achtung Anfänger! :whistling:

    Betrachten des Quellcodes auf eigene Gefahr, bei Übelkeit,Erbrechen,Kopfschmerzen übernehme ich keine Haftung. 8o

  • Dietmar

    sorry, das Post war zu kurz. "geht leider nicht." bezog sich auf: Der Registrierung-Editor ist gesperrt. Aktueller Stand:

    Spoiler anzeigen
    [autoit]

    #include <Array.au3>
    #include <Constants.au3>
    #Include <String.au3>
    Local $RegPath1 = "HKEY_CURRENT_USER\SOFTWARE\Microsoft\Office\Common\Smart Tag"
    Local $save_file = 'D:\Sicherung\Test.dat'
    _EnumRegKey($RegPath1, 0, $save_file)

    [/autoit] [autoit][/autoit] [autoit]

    ;========================================================================================
    ; Function Name: _EnumRegKey($HKEY, $prm, [$file])
    ; Description: Ermittelt alle Namen, Typen und Werte in einem gegebenen Schlüssel
    ; Parameter(s): $HKEY der Registryschlüssel
    ; Parameter(s): 0 = Ausgabe auf Console
    ; 1 = Ausgabe in Datei
    ; nur bei 1 path der Sicherungsdatei
    ; Return Value(s): Ausgabe auf Console
    ; Ausgabe in Sicherungsdatei
    ; Author(s): JeScho ([email='jescho@autoit.de'][/email])
    ; Großvater (Unterst. im Forum)
    ;========================================================================================
    Func _EnumRegKey($RegPath, $prm ,$file)
    ;prm Gültigkeit prüfen
    If $prm = 0 Then
    ElseIf $prm = 1 And $file <> '' Then
    ConsoleWrite('richtige Prm,' & @LF)
    Else
    ConsoleWrite('Falscher Prm,' & @LF)
    Exit
    EndIf
    $aReg = _EnumRegVal($RegPath)
    If $prm = 0 Then ConsoleWrite(@LF)
    If $prm = 0 Then ConsoleWrite('[' & $RegPath & ']' & @LF)
    For $i = 1 To UBound($aReg) -1
    ;~ If $prm = 0 Then ConsoleWrite('"' & $aReg[$i][0] & '"=' & $aReg[$i][1] & $aReg[$i][2] & @LF)
    If $prm = 0 Then ConsoleWrite('"' & $aReg[$i][0] & '"=' & $aReg[$i][1] &':' & $aReg[$i][2] & @LF)
    Next
    $REK = RegEnumKey($RegPath,1)
    If $REK <> '' Then
    For $i = 1 To 100
    $REK = RegEnumKey($RegPath,$i)
    If @error Then ExitLoop
    _EnumRegKey($RegPath & '\' & $REK, 0, $save_file);recursiver Aufruf
    Next
    EndIf
    EndFunc ;==> _EnumRekKey
    Func _EnumRegVal($RegPath)
    ;~ Local $RegTypes[8] = ["REG_NONE", '', "REG_EXPAND_SZ", "hex:", "dword:", '', '', "REG_MULTI_SZ"]
    Local $RegTypes[8] = ['REG_NONE', 'REG_SZ', 'REG_EXPAND_SZ', 'REG_BINARY', 'REG_DWORD', '', '', 'REG_MULTI_SZ']
    Local $RegValue = ""
    Local $Instance = 1
    Local $aResult[256][3] = [[0, 0, 0]]
    Local $Reg = ""
    Local $Ext = ""
    While True
    $RegValue = RegEnumVal($RegPath, $Instance)
    If @error Then ExitLoop
    $Reg = RegRead($RegPath, $RegValue)
    If @error Then ExitLoop
    $Ext = @extended
    If $Ext = $REG_BINARY Then $Reg = StringToBinary(BinaryToString($Reg))
    $aResult[0][0] = $Instance
    $aResult[$Instance][0] = $RegValue
    $aResult[$Instance][1] = $RegTypes[$Ext]
    $aResult[$Instance][2] = $Reg
    $Instance += 1
    WEnd
    ReDim $aResult[$Instance][3]
    Return $aResult
    EndFunc

    [/autoit]

    Die Ausgabe auf die Console passt schon. Jetzt soll aber die Ausgabe in eine Datei gehen, und dann nach dem Userlogin synchronisiert werden.

    Du sagst mit einer Schleife ist es zu langsam - für Verbesserungen bin ich immer offen.

    Gruß Jescho

    MfG Jescho

    Jeder hat mal klein angefangen - aber nicht jeder kommt groß raus!

  • Nein ich sagte nicht, das es zu langsdam ist
    sondern das Du an das Tempo von regedit /e nicht rankommst ;)

    Schade wenn es gesperrt ist, dann hast Du ja keine andere Möglichkeit.
    wenn die einzelnen Elemete passen würde ich die erste Zeile so in die Datei schreiben.
    Und den Rest mit iniwrite, da das der exportierten Struktur (wie sie regedit liefern würde), schon sehr nah kommt.
    Danach umbenenen dann hast Du eine Regdatei, die dann mittels shellexecute aausrollen oder mit GPO wenn AD etc vorhanden.

    Achtung Anfänger! :whistling:

    Betrachten des Quellcodes auf eigene Gefahr, bei Übelkeit,Erbrechen,Kopfschmerzen übernehme ich keine Haftung. 8o