Programmversionen installierter Programme

    • Offizieller Beitrag

    Hi,
    ich wollte mal eben die Programmversionen aller installierten Programme ermitteln und habe festgestellt, dass sich da kein Softwarehersteller an feste Regeln hält.
    Bei einem Großteil wird die Versionsnummer im Schlüssel "HKLM\ Software\ Microsoft\ Windows\ CurrentVersion\ Uninstall\ SOFTWARENAME\ DisplayVersion" hinterlegt. Das ist prima.
    Bei den anderen (Autoit gehört auch dazu :( ) ist teilweise die Versionsnummer im Namen enthalten oder in einem anderen Registryschlüssel, der von Programm zu Programm variiert, hinterlegt.
    Es gibt aber auch Spezialisten, die die Versionsnr. gar nicht in der Registry hinterlegen - da hilft dann nur Pfad suchen und mit FileGetVersion( ) nachsehen.

    Hat evtl. jemand eine zündende Idee, wie man da eine automatisierte Abfrage hinbekommt?

    Hier könnt ihr mal selber schauen, wieviel Progs sich sauber eintragen und wieviele nicht (unbenommen derer, die gar nicht im Uninstall-Schlüssel stehen):

    Spoiler anzeigen
    [autoit]

    #include <GUIConstants.au3>
    #include <GuiListView.au3>
    #include <array.au3>

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

    Dim $RegKey = "HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall\"
    Dim $Wert, $Fehler=0, $i=0, $str
    Dim $ar_SubKeys[1], $ar_Progs[1], $ar_Progs_oVer[1]
    $ar_SubKeys[0] = 0
    $ar_Progs[0] = 0
    $ar_Progs_oVer[0] = 0

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

    ; == GUI generated with Koda ==
    $Form1 = GUICreate("AForm1", 622, 670, -1, -1)
    $List1 = GUICtrlCreateListView("Programm|Version", 24, 30, 577, 300, $LVSCW_AUTOSIZE)
    _GUICtrlListViewSetColumnWidth(-1, 0, 320)
    _GUICtrlListViewSetColumnWidth(-1, 1, 230)
    $List2 = GUICtrlCreateList("", 24, 360, 577, 300)
    GUICtrlCreateLabel("Programme mit Reg-Key 'DisplayVersion'", 200, 10)
    GUICtrlCreateLabel("Programme ohne Reg-Key 'DisplayVersion'", 200, 340)
    GUISetState(@SW_SHOW)

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

    _ReadInstalledProg()

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

    ; Progs mit Key "DisplayVersion"
    For $i = 1 To $ar_Progs[0]
    $var = StringSplit($ar_Progs[$i], "\")
    _GUICtrlListViewInsertItem($List1, -1, $var[1] & "|" & $var[2])
    Next

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

    ; Progs ohne Key "DisplayVersion"
    For $i = 1 To $ar_Progs_oVer[0]
    GUICtrlSetData($List2, $ar_Progs_oVer[$i])
    Next

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

    While 1
    $msg = GuiGetMsg()
    Select
    Case $msg = $GUI_EVENT_CLOSE
    ExitLoop
    Case Else
    ;;;;;;;
    EndSelect
    WEnd
    Exit

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

    Func _ReadInstalledProg()
    Do
    $i+=1
    $Wert=RegEnumKey($RegKey, $i)
    $Fehler=@Error
    If $Fehler=0 Then
    _ArrayAdd($ar_SubKeys, $Wert)
    $ar_SubKeys[0] += 1
    EndIf
    Until $Fehler<>0
    For $i = 1 To $ar_SubKeys[0]
    $valName = RegRead($RegKey & $ar_SubKeys[$i], "DisplayName")
    $valVer = RegRead($RegKey & $ar_SubKeys[$i], "DisplayVersion")
    If $valName <> "" Then
    Select
    Case $valVer = ""
    $str = $valName
    _ArrayAdd($ar_Progs_oVer, $str)
    $ar_Progs_oVer[0] += 1
    Case Else
    $str = $valName & "\" & $valVer
    _ArrayAdd($ar_Progs, $str)
    $ar_Progs[0] += 1
    EndSelect
    EndIf
    Next
    EndFunc

    [/autoit]
    • Offizieller Beitrag

    Letztlich geht es darum die Versionen abzugleichen mit Versionen einer Installroutine in einem Script und bei Bedarf, dann die neuere Version zu installieren.

    Da es allgemeingültig sein soll, kann ich den Ordner Programme eh vergessen. Ich installiere dorthin ausschließlich Systemkomponenten. Programme liegen bei mir auf einer eigenen Partition.
    Und ich muß davon ausgehen, dass nicht nur ich eine andere Ordnung wähle.

    Ich hatte schon überlegt, alle Partitionen rekursiv nach EXE zu durchsuchen und die Version zu checken.
    Hat aber auch 2 Nachteile. Zum einen dauert es ewig und zum anderen müssen die gefundenen EXE-dateien nicht zwangsweise installiert sein, sondern können irgendwelche Downloads sein.

    Also bleibt eigtl. nur die Registry.

    Ich werd mir nun doch die Mühe machen und bei allen Programmen, die zur Installation zur Verfügung stehen, nachsehen wo sie sich in der Registry eingraben. Dann kann ich ganz gezielt abfragen.

    • Offizieller Beitrag

    HI,

    sprich du willst ein eigenes Software-Verteilverfahren in Autoit schreiben.

    Das
    1. Software installieren
    2. Software updaten
    3. Software deinstallieren

    kann.

    Die Logik legst du komplett ins Programm? Keine User-Interaktion? Sprich ich wähle aus, welche Programme ich haben will, oder ich will erst deinstallieren, bevor ich die neue Version installieren lassen. ...

    Wenn du "nur" ein paar definierte Programme einbinden willst, dann würde ich die installierte Version anzeigen und die verfügbare und der User kann dann wählen, ob er installieren möchte.

    Klickt er eine Software an, bekommt er die Optionen : Deinstallieren, Update, Neuinstallation

    So long,

    Mega

  • Hallo zusammen,

    ich bin auf diesen interessanten Beitrag gestossen.
    Gibt es dazu schon eine konkrete Lösung?
    Ich habe mir IOM schonmal angeschaut - finde ich ganz interessant, aber solch eine
    Prüfung auf bereits installierte Versionen wäre schon sehr hilfreich.

    Ich bin auch auf einen recht interessanten Ansatz gestoßen den ich hier
    mal reinstelle - hier fehlt halt noch die Prüfroutine.

    Spoiler anzeigen
    [autoit][/autoit] [autoit][/autoit] [autoit]

    $Form = GUICreate("Bitte auswaehlen", 350, 360) ; will create a dialog box that when displayed is centered

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

    GUICtrlCreateLabel("Programme:", 10, 10, 120, 20)
    $check1 = GUICtrlCreateCheckbox("Firefox 2.0", 10, 30, 120, 20)
    $check2 = GUICtrlCreateCheckbox("7 Zip", 10, 50, 120, 20)
    $check3 = GUICtrlCreateCheckbox("CCleaner", 10, 70, 120, 20)
    $check4 = GUICtrlCreateCheckbox("FreePDF", 10, 90, 120, 20)
    $check5 = GUICtrlCreateCheckbox("Acrobat Reader 7.0.8", 10, 110, 120, 20)
    $check6 = GUICtrlCreateCheckbox("FreeUndelete", 10, 130, 120, 20)
    $check7 = GUICtrlCreateCheckbox("Open Office 2.0.4", 10, 150, 120, 20)
    $check8 = GUICtrlCreateCheckbox("Ad-Aware", 10, 170, 120, 20)
    $check9 = GUICtrlCreateCheckbox("WinRAR", 10, 190, 120, 20)
    $check10 = GUICtrlCreateCheckbox("RegCleaner", 10, 210, 120, 20)
    $check11 = GUICtrlCreateCheckbox("Total Commander 6.0", 10, 230, 120, 20)
    $check12 = GUICtrlCreateCheckbox("BurnerXP Pro 3", 10, 250, 120, 20)

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

    GUICtrlCreateLabel("Installierte Version:", 200, 10)

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

    ;~ $msgbutton = GUICtrlCreateButton("msgbox", 10, 330)

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

    GUISetState() ; will display an dialog box with checkbox

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

    $file = GUICtrlCreateInput(@ProgramFilesDir, 10, 270, 170, 20)

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

    $ok = GUICtrlCreateButton("Installieren", 10, 300)

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

    $checkver = GUICtrlCreateButton("Installierte Versionen prüfen", 200, 300)

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

    ; Run the GUI until the dialog is closed
    While 1
    $msg = GUIGetMsg()

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

    Switch $msg

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

    Case $ok

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

    $pfad = GUICtrlRead($file)

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

    FileDelete(@StartupCommonDir & "\installmenue.exe")

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

    If GUICtrlRead($check1) = $GUI_CHECKED Then
    BlockInput(1)
    $ID = Run("Firefox20.exe")

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

    BlockInput(0)
    ProcessWaitClose($ID)
    GUICtrlCreateLabel("Done", 150, 30, 50) ; first cell 50 width
    GUICtrlCreateLabel("C:\Programme", 200, 30, 150) ; first cell 50 width
    EndIf

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

    If GUICtrlRead($check2) = $GUI_CHECKED Then
    $ID = RunWait($_path &"\" & $_soft & "\" & "Tools\Packer\7-Zip\" & "7z457.exe /S")
    ;Installationsscript
    ProcessWaitClose($ID)
    GUICtrlCreateLabel("Done", 150, 50, 50) ; first cell 50 width
    GUICtrlCreateLabel(FileGetVersion (@ProgramFilesDir & "\7-zip\7z.exe"), 200, 50, 150) ; first cell 50 width
    EndIf

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

    If GUICtrlRead($check3) = $GUI_CHECKED Then
    $ID = ShellExecuteWait($_soft & "\" & "CCleaner.cmd")
    ;Installationsscript
    EndIf

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

    If GUICtrlRead($check4) = $GUI_CHECKED Then
    $ID = Run("gs853w32.exe")
    BlockInput(1)
    ;Installationsscript
    BlockInput(0)
    ProcessWaitClose($ID2)
    GUICtrlCreateLabel("Done", 150, 90, 50) ; first cell 50 width
    GUICtrlCreateLabel("C:\ghostskript", 200, 90, 150) ; first cell 50 width
    EndIf

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

    If GUICtrlRead($check5) = $GUI_CHECKED Then
    BlockInput(1)
    $ID = Run("Ar708de.exe /S /v/qb")
    ;Installationsscript
    BlockInput(0)
    ProcessWaitClose($ID)
    GUICtrlCreateLabel("Done", 150, 110, 50) ; first cell 50 width
    GUICtrlCreateLabel("C:\Programme", 200, 110, 150) ; first cell 50 width
    EndIf

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

    If GUICtrlRead($check6) = $GUI_CHECKED Then
    $ID = Run("freeundelete.exe")
    BlockInput(1)
    ;Installationsscript
    BlockInput(0)
    ProcessWaitClose($ID)
    GUICtrlCreateLabel("Done", 150, 130, 50) ; first cell 50 width
    GUICtrlCreateLabel($pfad, 200, 130, 150) ; first cell 50 width
    EndIf

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

    If GUICtrlRead($check7) = $GUI_CHECKED Then
    BlockInput(1)
    $ID = RunWait("OO204.exe /S /D=" $pfad & "\Open Office""")
    ;Installationsscript
    BlockInput(0)
    ProcessWaitClose($ID)
    GUICtrlCreateLabel("Done", 150, 150, 50) ; first cell 50 width
    GUICtrlCreateLabel($pfad, 200, 150, 150) ; first cell 50 width
    EndIf

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

    If GUICtrlRead($check8) = $GUI_CHECKED Then
    BlockInput(1)
    $ID = Run("aawsepersonal.exe")
    ;Installationsscript
    BlockInput(0)
    ProcessWaitClose($ID)
    GUICtrlCreateLabel("Done", 150, 170, 50) ; first cell 50 width
    GUICtrlCreateLabel($pfad, 200, 170, 150) ; first cell 50 width
    EndIf

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

    If GUICtrlRead($check9) = $GUI_CHECKED Then
    BlockInput(1)
    $ID = Run("wrar361.exe")
    ;Installationsscript
    BlockInput(0)
    ProcessWaitClose($ID)
    GUICtrlCreateLabel("Done", 150, 190, 50) ; first cell 50 width
    GUICtrlCreateLabel($pfad, 200, 190, 150) ; first cell 50 width
    EndIf

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

    If GUICtrlRead($check10) = $GUI_CHECKED Then
    BlockInput(1)
    $ID = Run("RegCleaner.exe")
    ;Installationsscript
    BlockInput(0)
    ProcessWaitClose($ID)
    GUICtrlCreateLabel("Done", 150, 210, 50) ; first cell 50 width
    GUICtrlCreateLabel($pfad, 200, 210, 150) ; first cell 50 width
    EndIf

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

    If GUICtrlRead($check11) = $GUI_CHECKED Then
    BlockInput(1)
    $ID = Run("totalcommander60.exe")
    ;Installationsscript
    BlockInput(0)
    ProcessWaitClose($ID)
    GUICtrlCreateLabel("Done", 150, 230, 50) ; first cell 50 width
    GUICtrlCreateLabel($pfad, 200, 230, 150) ; first cell 50 width
    EndIf

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

    If GUICtrlRead($check12) = $GUI_CHECKED Then
    $ID = Run("xpburner.exe")
    BlockInput(1)
    ;Installationsscript
    BlockInput(0)
    ProcessWaitClose($ID)
    GUICtrlCreateLabel("Done", 150, 250, 50) ; first cell 50 width
    GUICtrlCreateLabel($pfad, 200, 250, 150) ; first cell 50 width
    EndIf

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

    Case $GUI_EVENT_CLOSE
    ExitLoop

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

    ;~ Case $msgbutton
    $output = ''

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

    For $x = 1 To 11 Step 1
    If GUICtrlRead(Eval("check" & $x)) = $GUI_CHECKED Then $output = $output & ControlGetText($Form, '', Eval("check" & $x)) & @CRLF
    Next
    msgbox(0,"",$output)
    EndSwitch
    WEnd

    [/autoit]
  • Du musst eben für jedes Programm den Regisrty-Schlüssel mit der installierten Versionsnummer kennen. Den kannst du dann prüfen:
    a) installiert: ja/nein
    b) Version :)

    //Edit: Pass dir halt IOM an :)