Registry auslesen, mit inhalt von txt-File vergleichen, alles löschen was nicht im textfile ist

  • Hallo zusammen

    Ich mache gerade meine erste Gehversuche mit autoit.

    Eckdaten: Das Programm sollte:

    - Registryhive auslesen z.B HKEY_CURRENT_USER\Software\Test

    - Ein Textfile auslesen, welches auch Registrywerte enthält

    - Beides Vergleichen

    - Alle Registrywerte löschen, welche nicht im Textfile enthalten sind

    Normalerweise würde ich den Registryhive einfach löschen, und mit den gewünschten Werten abfüllen, das kommt aber hier nicht in Frage, weil theoretisch die Möglichkeit besteht, dass die Registry abgefragt wird, während alles gelöscht ist. 8|

    Als Anfänger komme ich leider nicht weit :( Aber ich habe im Forum schonmal entdeckt, wie ich einen gewünschten Hive in die Registry in ein Array lade, und wie ich die Werte aus einem Textfile in ein Array lade:

    [autoit]

    #include <array.au3>
    #include <File.au3>
    ; #### Registry in ein Array einlesen
    Dim $arSubKey[1] = [0]
    $i = 1
    While 1
    $subkey = RegEnumKey('HKEY_CURRENT_USER\Software\test', $i)
    If @error Then ExitLoop
    $arSubKey[0] += 1
    ReDim $arSubKey[UBound($arSubKey)+1]
    $arSubKey[UBound($arSubKey)-1] = $subkey
    $i += 1
    WEnd
    ;_ArrayDisplay($arSubKey)
    ; #### Zeilen in Textfile in ein Array einlesen
    Local $aFile, $file = @ScriptDir & '\test.txt' ; der Dateipfad
    _FileReadToArray($file, $aFile)
    For $i = 1 To UBound($aFile) -1
    Next
    ;_ArrayDisplay($aFile)

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

    ; #### Nun die beiden Arrays vergleichen

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

    ; #### Werte in Registry löschen, die nicht im Textfile enthalten sind

    [/autoit]

    Wie vergleiche ich nun zwei Arrays, und wie lösche ich dann die entsprechend die Registry?

    Danke für eure Hilfe!

  • Hi eF_Hacks

    Vielen Dank für deinen input!

    Leider bekomme ich das so nicht zum laufen ;(

    Könntest Du das vielleicht in Scriptform posten?

    Das if(Array1[0]!=Array2[0]) RegDelete() müsste ja so gehen:

    $neuevariabel = Resultat aus Array1[0]!=Array2[0])

    Regdelete ($neuevariabel)

    Aber ich bekomme es nicht zum laufen, obwohl ich fleissig am einarbeiten bin :huh:

    So rein $neuevariabel =(Array1[0]!=Array2[0]) geht ja nicht :S

  • verwende statt
    if(Array1[0]!=Array2[0]) RegDelete()
    das:

    [autoit]

    if($Array1[0] <> $Array2[0]) RegDelete()

    [/autoit]

    den Operator != gibt es in AutoIt nicht ;)

    MfG Schnuffel

    "Sarkasmus ist die niedrigste Form des Witzes, aber die höchste Form der Intelligenz."
    Val McDermid

    ein paar Infos ...

    Wer mehr als "nur" Hilfe benötigt, kann sich gern im Forum "Programmieranfragen" an uns wenden. Wir helfen in allen Fällen, die die Forenregeln zulassen.

    Für schnelle Hilfe benötigen wir ein ! lauffähiges ! Script, dass wir als Demonstration des Problems testen können. Wer von uns erwartet ein Teilscript erstmal lauffähig zu bekommen, der hat
    1. keine wirkliche Not
    2. keinen Respekt vor Menschen die ihm in ihrer Freizeit Ihre Hilfe anbieten
    3. oder ist einfach nur faul und meint wir coden das für ihn

    In solchen Fällen erlaube ich mir, die Anfrage einfach zu ignorieren. ;)

  • Das Ziel wäre ja, die beiden Arrays zu vergleichen, und alle Einträge die nicht im Test.txt File - bzw im Array $afile enthalten sind dynamisch aus der Registry zu löschen.

    Dazu müsste ich die differenz aus $afile und $arsubkey in ein neues Array schreiben und mit Regdelete(_neuesArray) dann wie gewünscht cleanen...

    Könnt ihr mir da auf die sprünge helfen?

    [autoit]


    $test= ($aFile[0] <> $arSubKey[0])
    msgBox(4096, "Test", $test, 10)

    [/autoit]

    Führt zur Meldung "true" dh dass sie verschieden sind. Wie kann ich die Variabel $test mit der differenz abfüllen?

    *gespanntkugg*

    2 Mal editiert, zuletzt von Surfy (11. September 2009 um 18:52)

  • Omg sorry.. Da hab ich wohl au3 glatt mit C++ verwechselt xD Zummindest was den Operator angeht..
    C++ ---> !=
    au3 ---> If Not

    Also..

    [autoit]

    $Value1 = "www.autoit.de"
    $Value2 = RegRead("key", "value")
    ;if(value1!=value2) | c++
    ;If($Value1=Not $Value2) Then | au3
    If($Value1<>$Value2)Then
    ...
    EndIf

    [/autoit]

    So dacht ich mir das vorhin.

    Edit: Ich habs nicht ausprobiert, aber ungefähr so kannst Du es dir vorstellen.

    [autoit]

    #include <File.au3>
    #include <Array.au3>

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

    #cs Txt Aufbau
    --------------
    wert1
    wert2
    wert3
    --------------
    #ce Txt Aufbau

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

    $File = "Test.txt"
    $iLines = _FileCountLines($File)

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

    Dim $aR_File[1]
    $aR_File[0] = $iLines

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

    ;File-Lines in array einlesen
    $iLinecount = 1

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

    For $ctn = 1 To $iLines
    $s_Line = FileReadLine($File, $ctn)
    $iUbound = UBound($aR_File)
    ReDim $aR_File[$iUbound + 1]
    $aR_File[$ctn] = $s_Line
    $iLinecount += 1
    Next
    $aR_File[0] = UBound($aR_File)

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

    ;_ArrayDisplay($aR_File)

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

    Dim $aR_Registry[1]
    $aR_Registry[0] = ""

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

    ;werte aus registry in array einlesen
    $expander = 1

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

    For $reg = 1 To $iLines
    $s_reg = RegEnumVal("HKEY_LOCAL_MACHINE\SOFTWARE\AutoIt v3\Autoit", $reg)
    $iUbound = UBound($aR_Registry)
    ReDim $aR_Registry[$iUbound + 1]
    $aR_Registry[$reg] = $s_reg
    $expander += 1
    Next
    $aR_Registry[0] = UBound($aR_Registry)

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

    ;werte vergleichen
    If $aR_File[0] <> $aR_Registry[0] Then SetError(-1, 1, -1)
    If Not @error Then
    For $count = 1 To $aR_Registry[0]
    If $aR_File[$count] <> $aR_Registry[$count] Then
    ;RegDelete
    EndIf
    Next
    EndIf

    [/autoit]

    Einmal editiert, zuletzt von eF_Hacks (11. September 2009 um 19:18)

  • Herzlichen Dank für eure Tips!

    Besonders das mit den Schnittmengen - genau das was ich gesucht habe!

    Nur die Ergebnisse erstaunen mich, wieso bekomme ich in "Unterschiede 2" einfach alle Keys aufgelistet? Denke dass ist einfach noch bisschen zu hoch für mich ;(

    Im Attachement ist der Script, das Textfile sowie ein Sample-Regfile.

    Wünschenswert wäre hier gewesen, wenn ich in $diff2 alle Regkeys zum löschen erhhalten hätte.

    [autoit]

    #include <array.au3>
    #include <File.au3>
    ; #### Registry in ein Array einlesen
    Global $aFile
    Global $arSubKey
    Global $arSubKey2
    Dim $arSubKey[1] = [0]
    $i = 1
    While 1
    $subkey = RegEnumKey('HKEY_CURRENT_USER\Software\blubb', $i)
    If @error Then ExitLoop
    $arSubKey[0] += 1
    ReDim $arSubKey[UBound($arSubKey)+1]
    $arSubKey[UBound($arSubKey)-1] = $subkey
    $i += 1
    WEnd
    ;_ArrayDisplay($arSubKey)
    ; #### Zeilen in Textfile in ein Array einlesen
    Local $aFile, $file = @ScriptDir & '\test.txt' ; der Dateipfad
    _FileReadToArray($file, $aFile)
    For $i = 1 To UBound($aFile) -1
    Next
    ;_ArrayDisplay($aFile)

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

    ; #### Nun die beiden Arrays vergleichen

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

    $ret = _GetIntersection($aFile, $arSubKey, 0, '1')
    ;$ret = _GetIntersection($arSubKey, $aFile, 0, ' ')
    $diff1 = ''
    $diff2 = ''
    If Not @error Then
    For $i = 0 To UBound($ret) -1
    If $ret[$i][1] <> '' Then $diff1 &= $ret[$i][1] & ' ; '
    If $ret[$i][2] <> '' Then $diff2 &= $ret[$i][2] & ' ; '
    Next
    EndIf
    MsgBox(0, '', 'Unterschiede 1: ' & $diff1 & @LF & 'Unterschiede 2: ' & $diff2)

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

    ;==================================================================================================
    ; Function Name: _GetIntersection($Set1, $Set2 [, $GetAll=0 [, $Delim=Default]])
    ; Description:: Detect from 2 sets
    ; - Intersection (elements are contains in both sets)
    ; - Difference 1 (elements are contains only in $Set1)
    ; - Difference 2 (elements are contains only in $Set2)
    ; Parameter(s): $Set1 set 1 (1D-array or delimited string)
    ; $Set2 set 2 (1D-array or delimited string)
    ; optional: $GetAll 0 - only one occurence of every different element are shown (Default)
    ; 1 - all elements of differences are shown
    ; optional: $Delim Delimiter for strings (Default use the separator character set by Opt("GUIDataSeparatorChar") )
    ; Return Value(s): Succes 2D-array [i][0]=Intersection
    ; [i][1]=Difference 1
    ; [i][2]=Difference 2
    ; Failure -1 @error set, that was given as array, is'nt 1D-array
    ; Note: Comparison is case-sensitiv! - i.e. Number 9 is different to string '9'!
    ; Author(s): BugFix ([email='bugfix@autoit.de'][/email])
    ;==================================================================================================
    Func _GetIntersection(ByRef $Set1, ByRef $Set2, $GetAll=0, $Delim=Default)
    Local $o1 = ObjCreate("System.Collections.ArrayList")
    Local $o2 = ObjCreate("System.Collections.ArrayList")
    Local $oUnion = ObjCreate("System.Collections.ArrayList")
    Local $oDiff1 = ObjCreate("System.Collections.ArrayList")
    Local $oDiff2 = ObjCreate("System.Collections.ArrayList")
    Local $tmp, $i
    If $GetAll <> 1 Then $GetAll = 0
    If $Delim = Default Then $Delim = Opt("GUIDataSeparatorChar")
    If Not IsArray($Set1) Then
    If Not StringInStr($Set1, $Delim) Then
    $o1.Add($Set1)
    Else
    $tmp = StringSplit($Set1, $Delim)
    For $i = 1 To UBound($tmp) -1
    $o1.Add($tmp[$i])
    Next
    EndIf
    Else
    If UBound($Set1, 0) > 1 Then Return SetError(1,0,-1)
    For $i = 0 To UBound($Set1) -1
    $o1.Add($Set1[$i])
    Next
    EndIf
    If Not IsArray($Set2) Then
    If Not StringInStr($Set2, $Delim) Then
    $o2.Add($Set2)
    Else
    $tmp = StringSplit($Set2, $Delim)
    For $i = 1 To UBound($tmp) -1
    $o2.Add($tmp[$i])
    Next
    EndIf
    Else
    If UBound($Set2, 0) > 1 Then Return SetError(1,0,-1)
    For $i = 0 To UBound($Set2) -1
    $o2.Add($Set2[$i])
    Next
    EndIf
    For $tmp In $o1
    If $o2.Contains($tmp) And Not $oUnion.Contains($tmp) Then $oUnion.Add($tmp)
    Next
    For $tmp In $o2
    If $o1.Contains($tmp) And Not $oUnion.Contains($tmp) Then $oUnion.Add($tmp)
    Next
    For $tmp In $o1
    If $GetAll Then
    If Not $oUnion.Contains($tmp) Then $oDiff1.Add($tmp)
    Else
    If Not $oUnion.Contains($tmp) And Not $oDiff1.Contains($tmp) Then $oDiff1.Add($tmp)
    EndIf
    Next
    For $tmp In $o2
    If $GetAll Then
    If Not $oUnion.Contains($tmp) Then $oDiff2.Add($tmp)
    Else
    If Not $oUnion.Contains($tmp) And Not $oDiff2.Contains($tmp) Then $oDiff2.Add($tmp)
    EndIf
    Next
    Local $UBound[3] = [$oDiff1.Count,$oDiff2.Count,$oUnion.Count], $max = 1
    For $i = 0 To UBound($UBound) -1
    If $UBound[$i] > $max Then $max = $UBound[$i]
    Next
    Local $aOut[$max][3]
    If $oUnion.Count > 0 Then
    $i = 0
    For $tmp In $oUnion
    $aOut[$i][0] = $tmp
    $i += 1
    Next
    EndIf
    If $oDiff1.Count > 0 Then
    $i = 0
    For $tmp In $oDiff1
    $aOut[$i][1] = $tmp
    $i += 1
    Next
    EndIf
    If $oDiff2.Count > 0 Then
    $i = 0
    For $tmp In $oDiff2
    $aOut[$i][2] = $tmp
    $i += 1
    Next
    EndIf
    Return $aOut
    EndFunc ;==>_GetIntersection
    ; #### Werte in Registry löschen, die nicht im Textfile enthalten sind

    [/autoit]

    Vielleicht erkennt jemand ja auf einen blick, wie man das anpassen müsste, um eine variable mit allen zu löschenden Keys zu erhalten :huh:

    Das löschen müsste dann ja so gehen:

    For $i = 0 To UBound($diff2) -1
    $regDelete = RegDelete($diff2[$i])
    Next

    Einmal editiert, zuletzt von Surfy (14. September 2009 um 11:35)

  • Spoiler anzeigen
    [autoit]


    #include <array.au3>
    #include <File.au3>

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

    Global $aRegFile
    Global $aFile
    Global $aret

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

    ; #### Zeilen in Textfile in ein Array einlesen

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

    Global $regfile = @ScriptDir & '\test.txt' ; der Dateipfad zu meiner Textdatei, wären dann deine Regkey
    Global $file = @ScriptDir & '\test2.txt' ; der Dateipfad zu deiner Textdatei

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

    _FileReadToArray($regfile, $aRegFile)
    _FileReadToArray($file, $aFile)

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

    ; #### Nun die beiden Arrays vergleichen

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

    $aret = _GetIntersection($aRegFile, $afile, 1)

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

    Redim $aret[ubound($aret, 1)][ubound($aret, 2)] ;der Teil ist nur für die Beschriftung
    $aret[ubound($aret, 1)-1][0] = "Schnittmenge"
    $aret[ubound($aret, 1)-1][1] = "In Menge1 aber nicht in Menge2 enthalten"
    $aret[ubound($aret, 1)-1][2] = "In Menge2 aber nicht in Menge1 enthalten"
    _ArrayDisplay($aret)
    exit

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

    ;==================================================================================================
    ; Function Name: _GetIntersection($Set1, $Set2 [, $GetAll=0 [, $Delim=Default]])
    ; Description:: Detect from 2 sets
    ; - Intersection (elements are contains in both sets)
    ; - Difference 1 (elements are contains only in $Set1)
    ; - Difference 2 (elements are contains only in $Set2)
    ; Parameter(s): $Set1 set 1 (1D-array or delimited string)
    ; $Set2 set 2 (1D-array or delimited string)
    ; optional: $GetAll 0 - only one occurence of every different element are shown (Default)
    ; 1 - all elements of differences are shown
    ; optional: $Delim Delimiter for strings (Default use the separator character set by Opt("GUIDataSeparatorChar") )
    ; Return Value(s): Succes 2D-array [i][0]=Intersection
    ; [i][1]=Difference 1
    ; [i][2]=Difference 2
    ; Failure -1 @error set, that was given as array, is'nt 1D-array
    ; Note: Comparison is case-sensitiv! - i.e. Number 9 is different to string '9'!
    ; Author(s): BugFix ([email='bugfix@autoit.de'][/email])
    ;==================================================================================================

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

    Func _GetIntersection(ByRef $Set1, ByRef $Set2, $GetAll=0, $Delim=Default)
    Local $o1 = ObjCreate("System.Collections.ArrayList")
    Local $o2 = ObjCreate("System.Collections.ArrayList")
    Local $oUnion = ObjCreate("System.Collections.ArrayList")
    Local $oDiff1 = ObjCreate("System.Collections.ArrayList")
    Local $oDiff2 = ObjCreate("System.Collections.ArrayList")
    Local $tmp, $i
    If $GetAll <> 1 Then $GetAll = 0
    If $Delim = Default Then $Delim = Opt("GUIDataSeparatorChar")
    If Not IsArray($Set1) Then
    If Not StringInStr($Set1, $Delim) Then
    $o1.Add($Set1)
    Else
    $tmp = StringSplit($Set1, $Delim)
    For $i = 1 To UBound($tmp) -1
    $o1.Add($tmp[$i])
    Next
    EndIf
    Else
    If UBound($Set1, 0) > 1 Then Return SetError(1,0,-1)
    For $i = 0 To UBound($Set1) -1
    $o1.Add($Set1[$i])
    Next
    EndIf
    If Not IsArray($Set2) Then
    If Not StringInStr($Set2, $Delim) Then
    $o2.Add($Set2)
    Else
    $tmp = StringSplit($Set2, $Delim)
    For $i = 1 To UBound($tmp) -1
    $o2.Add($tmp[$i])
    Next
    EndIf
    Else
    If UBound($Set2, 0) > 1 Then Return SetError(1,0,-1)
    For $i = 0 To UBound($Set2) -1
    $o2.Add($Set2[$i])
    Next
    EndIf
    For $tmp In $o1
    If $o2.Contains($tmp) And Not $oUnion.Contains($tmp) Then $oUnion.Add($tmp)
    Next
    For $tmp In $o2
    If $o1.Contains($tmp) And Not $oUnion.Contains($tmp) Then $oUnion.Add($tmp)
    Next
    For $tmp In $o1
    If $GetAll Then
    If Not $oUnion.Contains($tmp) Then $oDiff1.Add($tmp)
    Else
    If Not $oUnion.Contains($tmp) And Not $oDiff1.Contains($tmp) Then $oDiff1.Add($tmp)
    EndIf
    Next
    For $tmp In $o2
    If $GetAll Then
    If Not $oUnion.Contains($tmp) Then $oDiff2.Add($tmp)
    Else
    If Not $oUnion.Contains($tmp) And Not $oDiff2.Contains($tmp) Then $oDiff2.Add($tmp)
    EndIf
    Next
    Local $UBound[3] = [$oDiff1.Count,$oDiff2.Count,$oUnion.Count], $max = 1
    For $i = 0 To UBound($UBound) -1
    If $UBound[$i] > $max Then $max = $UBound[$i]
    Next
    Local $aOut[$max][3]
    If $oUnion.Count > 0 Then
    $i = 0
    For $tmp In $oUnion
    $aOut[$i][0] = $tmp
    $i += 1
    Next
    EndIf
    If $oDiff1.Count > 0 Then
    $i = 0
    For $tmp In $oDiff1
    $aOut[$i][1] = $tmp
    $i += 1
    Next
    EndIf
    If $oDiff2.Count > 0 Then
    $i = 0
    For $tmp In $oDiff2
    $aOut[$i][2] = $tmp
    $i += 1
    Next
    EndIf
    Return $aOut
    EndFunc ;==>_GetIntersection

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

    ; #### Werte in Registry löschen, die nicht im Textfile enthalten sind

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


    Wird es damit klar? Auf Reg-Änderungen hatte ich jetzt keine Lust, erstell dir einfach zum testen eine zweite Testdatei (s. Skript).