Jump to content

help using RegEnumKey


dcoggie
 Share

Recommended Posts

I have combined $iIsInstalled and $aOFDPrograms

Programs are :
CCleaner ---is installed and up to date
DeFraggler ---is installed but out of date
Opera ---is not installed.

The printout is wrong. It includes "DeFraggler" twice. How can I get rid of the extra name for all the out of date programs?

CCleaner (version 5.13)
Defraggler
Defraggler (version 2.19) is *out of Date*

 

#include <Misc.au3>
#Include <Date.au3>

$File = FileOpen("text.txt", 2)

; #EXAMPLE ======================================================================================================================
Local $aApps = [["CCleaner", "5.13", 0], ["Defraggler", "3", 0], ["Opera", "34", 0]]
Local $iIsInstalled, $sUTP
Local $aOFDPrograms
For $i = 0 To UBound($aApps) - 1
    $iIsInstalled = _IsInstalled($aApps[$i][0], $aApps[$i][1], $aApps[$i][2])
    If $iIsInstalled Then
    $sRes =  ""
       Switch @extended
            Case -1
                $sUTP = $aOFDPrograms
            Case 1
                $sUTP = " (version " & $aApps[$i][1] & ")"
            Case 0
                $sUTP = " (version " & $aApps[$i][1] & ")"
        EndSwitch
Else
        $sRes = " is not installed."
        EndIf
        If $sRes = " is not installed." Then
        $NoProgram = ($aApps[$i][0] & $sRes & $sUTP & @CRLF)
 Else
 FileWrite($File, $aApps[$i][0] & $sRes & $sUTP & @CRLF)
EndIf
 Next

; ===============================================================================================================================

; #FUNCTION# ====================================================================================================================
; Name ..........: _IsInstalled
; Description ...: Checks if an application is installed on the local computer.
; Syntax ........: _IsInstalled($sAppname[, $sMinVersion = 0[, $iSearchMode = 0]])
; Parameters ....: $sAppname            - Application name or partial name (depending of $iSearchMode value).
;                  $sMinVersion         - [optional] Minimum version to check. Default is 0 (don't check for the version).
;                  $iSearchMode         - [optional] Search mode. Default is 0.
;                                            0 : Match string from the start.
;                                            1 : Match any substring.
;                                            2 : Exact string match.
;                                            3 : $sAppname is a regular expression
; Return values .: Success  - 1
;                  Failure  - 0
; Author ........: jguinch
; Remarks .......: on success, @extended is set to:
;                      0   - The specified version is installed (or no version checked if $sMinVersion^= 0)
;                      1   - A newer version is installed
;                     -1   - An older version is installed
; ===============================================================================================================================
Func _IsInstalled($sAppname, $sMinVersion, $iSearchMode = 0)

   Local $aAppList = _UninstallList("DisplayName", $sAppname, "DisplayVersion", $iSearchMode)
    If Not $aAppList[0][0] Then Return 0
    Local $iExtended = -1

    For $i = 1 To $aAppList[0][0]
        $sAppName = $aAppList[$i][2]
        $sVersion = $aAppList[$i][4]

        If StringRegExp($sAppName, "\d+\h*(\.\d+)+$") Then
            $aAppInfo = StringRegExp($sAppName, "(.+?)\h*(\d+(?:\.\d+)+)$", 1)
            $sAppName = $aAppInfo[0]
            If $sVersion = "" Then $sVersion = $aAppInfo[1]
        EndIf

        If $sMinVersion Then
            $iVersionComp = _VersionCompare($sVersion, $sMinVersion )
            If $iVersionComp = 0 And $iExtended = -1 Then $iExtended = 0
            If $iVersionComp = 1 And $iExtended <= 0 Then $iExtended = 1
        Else
            $iExtended = 0
        EndIf
    Next
    Return SetError(0, $iExtended, 1)

EndFunc

Local $aOFDPrograms
For $i = 0 To UBound($aApps) - 1
    $aOFDPrograms = _GetOutOfDatePrograms($aApps[$i][0], $aApps[$i][1], $aApps[$i][2])
    If Not @error Then
    For $n = 0 To UBound($aOFDPrograms) - 1
            FileWrite($File, $aOFDPrograms[$n][0] & " (version " & $aOFDPrograms[$n][1] & ")"  & " " & "is *out of Date*")
        Next
    EndIf
Next

Func _GetOutOfDatePrograms($sAppname, $sMinVersion, $iSearchMode = 0)
    Local $aAppList = _UninstallList("DisplayName", $sAppname, "DisplayVersion", $iSearchMode)
    If Not $aAppList[0][0] Then Return 0
    Local $iExtended = -1
    Local $aRet[ $aAppList[0][0]  ][2], $n = 0

    For $i = 1 To $aAppList[0][0]
        $sAppName = $aAppList[$i][2]
        $sVersion = $aAppList[$i][4]

        If StringRegExp($sAppName, "\d+\h*(\.\d+)+$") Then
            $aAppInfo = StringRegExp($sAppName, "(.+?)\h*(\d+(?:\.\d+)+)$", 1)
            $sAppName = $aAppInfo[0]
            If $sVersion = "" Then $sVersion = $aAppInfo[1]
        EndIf

        $iVersionComp = _VersionCompare($sVersion, $sMinVersion )
        If $iVersionComp = -1 Then
            $aRet[$n][0] = $sAppName
            $aRet[$n][1] = $sVersion
            $n += 1
        EndIf
    Next

    If $n = 0 Then Return SetError(1, 0, 0)
    ReDim $aRet[$n][2]
    Return $aRet

EndFunc

; #FUNCTION# ====================================================================================================================
; Name ..........: _UninstallList
; Description ...: Returns an array of matching uninstall keys from registry, with an optional filter
; Syntax ........: _UninstallList([$sValueName = ""[, $sFilter = ""[, $sCols = ""[, $iSearchMode = 0[,$ iArch = 3]]]]]])
; Parameters ....: $sValueName       - [optional] Registry value used for the filter.
;                                          Default is all keys ($sFilter do not operates).
;                  $sFilter          - [optional] String to search in $sValueName. Filter is not case sensitive.
;                  $sCols            - [optional] Additional values to retrieve. Use "|" to separate each value.
;                                          Each value adds a column in the returned array
;                  $iSearchMode      - [optional] Search mode. Default is 0.
;                                          0 : Match string from the start.
;                                          1 : Match any substring.
;                                          2 : Exact string match.
;                                          3 : $sFilter is a regular expression
;                  $iArch            - [optional] Registry keys to search in. Default is 3.
;                                          1 : x86 registry keys only
;                                          2 : x64 registry keys only
;                                          3 : both x86 and x64 registry keys
; Return values .: Returns a 2D array of registry keys and values :
;                      $array[0][0] : Number of keys
;                      $array[n][0] : Registry key path
;                      $array[n][1] : Registry subkey
;                      $array[n][2] : Display name
;                      $array[n][3] : Installation date (YYYYMMDD format)
;                      $array[n][4] : 1st additional value specified in $sCols (only if $sCols is set)
;                      $array[n][5] : 2nd additional value specified in $sCols (only if $sCols contains at least 2 entries)
;                      $array[n][x] : Nth additional value ...
; Author ........: jguinch
; ===============================================================================================================================
Func _UninstallList($sValueName = "", $sFilter = "", $sCols = "", $iSearchMode = 0, $iArch = 3)
    Local $sHKLMx86, $sHKLM64, $sHKCU = "HKCU\Software\Microsoft\Windows\CurrentVersion\Uninstall"
    Local $aKeys[1] = [ $sHKCU ]
    Local $sDisplayName, $sSubKey, $sKeyDate, $sDate, $sValue, $iFound, $n, $aResult[1][4], $iCol
    Local $aCols[1] = [0]

    If NOT IsInt($iArch) OR $iArch < 0 OR $iArch > 3 Then Return SetError(1, 0, 0)
    If NOT IsInt($iSearchMode) OR $iSearchMode < 0 OR $iSearchMode > 3 Then Return SetError(1, 0, 0)

    $sCols = StringRegExpReplace( StringRegExpReplace($sCols, "(?i)(DisplayName|InstallDate)\|?", ""), "\|$", "")
    If $sCols <> "" Then $aCols = StringSplit($sCols, "|")

    If @OSArch = "X86" Then
        $iArch = 1
        $sHKLMx86 = "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
    Else
        If @AutoitX64 Then
            $sHKLMx86 = "HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
            $sHKLM64 = "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
        Else
            $sHKLMx86 = "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
            $sHKLM64 = "HKLM64\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
        EndIf
    EndIf

    If BitAND($iArch, 1) Then
        Redim $aKeys[ UBound($aKeys) + 1]
        $aKeys [ UBound($aKeys) - 1] = $sHKLMx86
    EndIf

    If BitAND($iArch, 2) Then
        Redim $aKeys[ UBound($aKeys) + 1]
        $aKeys [ UBound($aKeys) - 1] = $sHKLM64
    EndIf


    For $i = 0 To UBound($aKeys) - 1
        $n = 1
        While 1
            $iFound = 1
            $aSubKey = _RegEnumKeyEx($aKeys[$i], $n)
            If @error Then ExitLoop

            $sSubKey = $aSubKey[0]
            $sKeyDate = StringRegExpReplace($aSubKey[1], "^(\d{4})/(\d{2})/(\d{2}).+", "$1$2$3")
            $sDisplayName = RegRead($aKeys[$i] & "\" & $sSubKey, "DisplayName")
            $sDate = RegRead($aKeys[$i] & "\" & $sSubKey, "InstallDate")
            If $sDate = "" Then $sDate = $sKeyDate

            If $sDisplayName <> "" Then
                 If $sValueName <> "" Then
                    $iFound = 0
                    $sValue = RegRead( $aKeys[$i] & "\" & $sSubKey, $sValueName)
                    If ( $iSearchMode = 0 AND StringInStr($sValue, $sFilter) = 1 ) OR _
                       ( $iSearchMode = 1 AND StringInStr($sValue, $sFilter) ) OR _
                       ( $iSearchMode = 2 AND $sValue = $sFilter ) OR _
                       ( $iSearchMode = 3 AND StringRegExp($sValue, "(?i)" & $sFilter) ) Then
                            $iFound = 1
                    EndIf
                EndIf

                If $iFound Then
                    Redim $aResult[ UBound($aResult) + 1][ 4 + $aCols[0] ]
                    $aResult[ UBound($aResult) - 1][0] = $aKeys[$i]
                    $aResult[ UBound($aResult) - 1][1] = $sSubKey
                    $aResult[ UBound($aResult) - 1][2] = $sDisplayName
                    $aResult[ UBound($aResult) - 1][3] = $sDate

                    For $iCol = 1 To $aCols[0]
                        $aResult[ UBound($aResult) - 1][3 + $iCol] = RegRead( $aKeys[$i] & "\" & $sSubKey, $aCols[$iCol])
                    Next
                EndIf
            EndIf

            $n += 1
        WEnd
    Next

    $aResult[0][0] = UBound($aResult) - 1
    Return $aResult
EndFunc




; #FUNCTION# ====================================================================================================================
; Name ..........: _RegEnumKeyEx
; Description ...: Enumerates the subkeys of the specified open registry key. The function retrieves information about one subkey
;                  each time it is called.
; Syntax ........: _RegEnumKeyEx($sKey, $iInstance)
; Parameters ....: $sKey                - The registry key to read.
;                  $iInstance           - The 1-based key instance to retrieve.
; Return values .: Success              - A 1D array :
;                                          $aArray[0] = subkey name
;                                          $aArray[1] = time at which the enumerated subkey was last written
;                  Failure               - Returns 0 and set @eror to non-zero value
; Author ........: jguinch
; ===============================================================================================================================
Func _RegEnumKeyEx($sKey, $iInstance)
    If NOT IsDeclared("KEY_WOW64_32KEY") Then Local Const $KEY_WOW64_32KEY = 0x0200
    If NOT IsDeclared("KEY_WOW64_64KEY") Then Local Const $KEY_WOW64_64KEY = 0x0100
    If NOT IsDeclared("KEY_ENUMERATE_SUB_KEYS") Then Local Const $KEY_ENUMERATE_SUB_KEYS = 0x0008

    If NOT IsDeclared("tagFILETIME") Then Local Const $tagFILETIME = "struct;dword Lo;dword Hi;endstruct"

    Local $iSamDesired = $KEY_ENUMERATE_SUB_KEYS

    Local $iX64Key = 0, $sRootKey, $aResult[2]

    Local $sRoot = StringRegExpReplace($sKey, "\\.+", "")
    Local $sSubkey = StringRegExpReplace($sKey, "^[^\\]+\\", "")

    $sRoot = StringReplace($sRoot, "64", "")
    If @extended Then $iX64Key = 1

    If NOT IsInt($iInstance) OR $iInstance < 1 Then Return SetError(2, 0, 0)

    Switch $sRoot
        Case "HKCR", "HKEY_CLASSES_ROOT"
            $sRootKey = 0x80000000
        Case "HKLM", "HKEY_LOCAL_MACHINE"
            $sRootKey = 0x80000002
        Case "HKCU", "HKEY_CURRENT_USER"
            $sRootKey = 0x80000001
        Case "HKU", "HKEY_USERS"
            $sRootKey = 0x80000003
        Case  "HKCC", "HKEY_CURRENT_CONFIG"
            $sRootKey = 0x80000005
        Case Else
            Return SetError(1, 0, 0)
    EndSwitch

    If StringRegExp(@OSArch, "64$") Then
        If @AutoItX64 OR $iX64Key Then
            $iSamDesired = BitOR($iSamDesired, $KEY_WOW64_64KEY)
        Else
            $iSamDesired = BitOR($iSamDesired, $KEY_WOW64_32KEY)
        EndIf
    EndIf

    Local $aRetOPen = DllCall('advapi32.dll', 'long', 'RegOpenKeyExW', 'handle', $sRootKey, 'wstr', $sSubKey, 'dword', 0, 'dword', $iSamDesired, 'ulong_ptr*', 0)
    If @error Then Return SetError(@error, @extended, 0)
    If $aRetOPen[0] Then Return SetError(10, $aRetOPen[0], 0)

    Local $hKey = $aRetOPen[5]

    Local $tFILETIME = DllStructCreate($tagFILETIME)
    Local $lpftLastWriteTime = DllStructGetPtr($tFILETIME)

    Local $aRetEnum = DllCall('Advapi32.dll', 'long', 'RegEnumKeyExW', 'long', $hKey, 'dword', $iInstance - 1, 'wstr', "", 'dword*', 255, 'dword', "", 'ptr', "", 'dword', "", 'ptr', $lpftLastWriteTime)
    If Not IsArray($aRetEnum) OR $aRetEnum[0] <> 0 Then Return SetError( 3, 0, 1)

    Local $tFILETIME2 = _Date_Time_FileTimeToLocalFileTime($lpftLastWriteTime)
    Local $localtime = _Date_Time_FileTimeToStr($tFILETIME2, 1)

    $aResult[0] = $aRetEnum[3]
    $aResult[1] = $localtime

    Return $aResult
EndFunc

 

Edited by dcoggie
Link to comment
Share on other sites

  • Replies 44
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

I am querying the registry to see if windows firewall is enabled or not. Some users who have other firewalls enabled are still getting the windows firewall printed out as enabled. Does anyone know why windows firewall is still showing as enabled?

Local $FW = RegRead("HKLM\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile", "EnableFirewall")
If $FW <> 0 Then
    $FW = "Enabled!"
Else
    $FW = "*Disabled*"
EndIf

 

Link to comment
Share on other sites

  • 2 months later...


This script works fine, but there are 2 problems. Both Java and Firefox have 2 different versions.

Firefox is: Mozilla Firefox 45
and
Mozilla Firefox 38.5.2 ESR

I'm not sure how to allow for them. Take them out of the Apps list and create a separate function for each?

#include <Misc.au3>
#Include <Date.au3>


$file = fileopen("text.txt", 2)


; #EXAMPLE ======================================================================================================================
Local $aApps = [["Adobe Flash Player 21 ActiveX", "21.0.0.197", 0], ["Adobe Reader XI", "11.0.0.15", 0], ["CCleaner", "5.16", 0], ["Defraggler", "2.21", 0], ["Google Chrome", "49", 0], ["HijackThis", "2.0.5", 0], ["HitmanPro", "3", 0], ["IncrediMail", "2.5", 0], ["Java.+?\d+ Update \d", "8.0.77.3", 3], ["Malwarebytes Anti-Exploit", "1.8.1.1189", 0], ["Malwarebytes Anti-Malware", "2.2.1.1043", 0], ["Microsoft Security Essentials", 0, 0], ["Microsoft Silverlight", "5", 0], ["Mozilla Firefox", "45", 0], ["Norton Ghost", "15", 0], ["Opera", "36", 0], ["Pale Moon", "26", 0], ["Safari", "5.1", 0], ["Spybot - Search & Destroy", "2.4", 0], ["SpywareBlaster", "5.4", 0], ["SUPERAntiSpyware", "6", 0], ["ThreatFire", "4.7", 0], ["Thunderbird", "38.5", 0], ["Windows Live Essentials", "16.4", 0], ["WinPatrol", "33.6", 0]]
Local $iIsInstalled, $sRes, $sUTP
For $i = 0 To UBound($aApps) - 1
    $iIsInstalled = _IsInstalled($aApps[$i][0], $aApps[$i][1], $aApps[$i][2])
    If $iIsInstalled Then
        $sRes = ""
        Switch @extended
            Case -1
                $sUTP = " An older version than '" & $aApps[$i][1] & "' is installed."
            Case 1
                $sUTP = " (version " & $aApps[$i][1] & ")"

            Case 0
                $sUTP = " (version " & $aApps[$i][1] & ")"

        EndSwitch
    Else
        $sRes = " is not installed."
    EndIf
     If $sRes = " is not installed."  Then
        $NoProgram =($aApps[$i][0] & $sRes & $sUTP & @CRLF)
ElseIf $aApps[$i][0] = "Adobe Flash Player 21 ActiveX" Then
FileWrite($File, "Adobe Flash Player ActiveX" & $sRes & $sUTP & @CRLF)
ElseIf $aApps[$i][0] = "Java.+?\d+ Update \d" Then
FileWrite($File, "Java" & $sRes & $sUTP & @CRLF)
Else
FileWrite($File, $aApps[$i][0] & $sRes & $sUTP & @CRLF)
EndIf
Next
FileWrite($File, @CRLF)
; ===============================================================================================================================

; #FUNCTION# ====================================================================================================================
; Name ..........: _IsInstalled
; Description ...: Checks if an application is installed on the local computer.
; Syntax ........: _IsInstalled($sAppname[, $sMinVersion = 0[, $iSearchMode = 0]])
; Parameters ....: $sAppname            - Application name or partial name (depending of $iSearchMode value).
;                  $sMinVersion         - [optional] Minimum version to check. Default is 0 (don't check for the version).
;                  $iSearchMode         - [optional] Search mode. Default is 0.
;                                            0 : Match string from the start.
;                                            1 : Match any substring.
;                                            2 : Exact string match.
;                                            3 : $sAppname is a regular expression
; Return values .: Success  - 1
;                  Failure  - 0
; Author ........: jguinch
; Remarks .......: on success, @extended is set to:
;                      0   - The specified version is installed (or no version checked if $sMinVersion^= 0)
;                      1   - A newer version is installed
;                     -1   - An older version is installed
; ===============================================================================================================================
Func _IsInstalled($sAppname, $sMinVersion = 0, $iSearchMode = 0)
    Local $aAppList = _UninstallList("DisplayName", $sAppname, "DisplayVersion", $iSearchMode)
    If Not $aAppList[0][0] Then Return 0
    Local $iExtended = -1

    For $i = 1 To $aAppList[0][0]
        $sAppName = $aAppList[$i][2]
        $sVersion = $aAppList[$i][4]

        If StringRegExp($sAppName, "\d+\h*(\.\d+)+$") Then
            $aAppInfo = StringRegExp($sAppName, "(.+?)\h*(\d+(?:\.\d+)+)$", 1)
            $sAppName = $aAppInfo[0]
            If $sVersion = "" Then $sVersion = $aAppInfo[1]
        EndIf

        If $sMinVersion Then
            $iVersionComp = _VersionCompare($sVersion, $sMinVersion )
            If $iVersionComp = 0 And $iExtended = -1 Then $iExtended = 0
            If $iVersionComp = 1 And $iExtended <= 0 Then $iExtended = 1
        Else
            $iExtended = 0
        EndIf
    Next
    Return SetError(0, $iExtended, 1)

EndFunc


Local $aOFDPrograms

For $i = 0 To UBound($aApps) - 1
    $aOFDPrograms = _GetOutOfDatePrograms($aApps[$i][0], $aApps[$i][1], $aApps[$i][2])
    If Not @error Then
        For $n = 0 To UBound($aOFDPrograms) - 1
            FileWrite($File, $aOFDPrograms[$n][0] & " (version " & $aOFDPrograms[$n][1] & ")" & " is *out of Date*" & @CRLF)
        Next
    EndIf
Next


Func _GetOutOfDatePrograms($sAppname, $sMinVersion, $iSearchMode = 0)
    Local $aAppList = _UninstallList("DisplayName", $sAppname, "DisplayVersion", $iSearchMode)
    If Not $aAppList[0][0] Then Return 0
    Local $iExtended = -1
    Local $aRet[ $aAppList[0][0]  ][2], $n = 0

    For $i = 1 To $aAppList[0][0]
        $sAppName = $aAppList[$i][2]
        $sVersion = $aAppList[$i][4]

        If StringRegExp($sAppName, "\d+\h*(\.\d+)+$") Then
            $aAppInfo = StringRegExp($sAppName, "(.+?)\h*(\d+(?:\.\d+)+)$", 1)
            $sAppName = $aAppInfo[0]
            If $sVersion = "" Then $sVersion = $aAppInfo[1]
        EndIf

        $iVersionComp = _VersionCompare($sVersion, $sMinVersion )
        If $iVersionComp = -1 Then
            $aRet[$n][0] = $sAppName
            $aRet[$n][1] = $sVersion
            $n += 1
        EndIf
    Next

    If $n = 0 Then Return SetError(1, 0, 0)
    ReDim $aRet[$n][2]
    Return $aRet

EndFunc


; #FUNCTION# ====================================================================================================================
; Name ..........: _UninstallList
; Description ...: Returns an array of matching uninstall keys from registry, with an optional filter
; Syntax ........: _UninstallList([$sValueName = ""[, $sFilter = ""[, $sCols = ""[, $iSearchMode = 0[,$ iArch = 3]]]]]])
; Parameters ....: $sValueName       - [optional] Registry value used for the filter.
;                                          Default is all keys ($sFilter do not operates).
;                  $sFilter          - [optional] String to search in $sValueName. Filter is not case sensitive.
;                  $sCols            - [optional] Additional values to retrieve. Use "|" to separate each value.
;                                          Each value adds a column in the returned array
;                  $iSearchMode      - [optional] Search mode. Default is 0.
;                                          0 : Match string from the start.
;                                          1 : Match any substring.
;                                          2 : Exact string match.
;                                          3 : $sFilter is a regular expression
;                  $iArch            - [optional] Registry keys to search in. Default is 3.
;                                          1 : x86 registry keys only
;                                          2 : x64 registry keys only
;                                          3 : both x86 and x64 registry keys
; Return values .: Returns a 2D array of registry keys and values :
;                      $array[0][0] : Number of keys
;                      $array[n][0] : Registry key path
;                      $array[n][1] : Registry subkey
;                      $array[n][2] : Display name
;                      $array[n][3] : Installation date (YYYYMMDD format)
;                      $array[n][4] : 1st additional value specified in $sCols (only if $sCols is set)
;                      $array[n][5] : 2nd additional value specified in $sCols (only if $sCols contains at least 2 entries)
;                      $array[n][x] : Nth additional value ...
; Author ........: jguinch
; ===============================================================================================================================
Func _UninstallList($sValueName = "", $sFilter = "", $sCols = "", $iSearchMode = 0, $iArch = 3)
    Local $sHKLMx86, $sHKLM64, $sHKCU = "HKCU\Software\Microsoft\Windows\CurrentVersion\Uninstall"
    Local $aKeys[1] = [ $sHKCU ]
    Local $sDisplayName, $sSubKey, $sKeyDate, $sDate, $sValue, $iFound, $n, $aResult[1][4], $iCol
    Local $aCols[1] = [0]

    If NOT IsInt($iArch) OR $iArch < 0 OR $iArch > 3 Then Return SetError(1, 0, 0)
    If NOT IsInt($iSearchMode) OR $iSearchMode < 0 OR $iSearchMode > 3 Then Return SetError(1, 0, 0)

    $sCols = StringRegExpReplace( StringRegExpReplace($sCols, "(?i)(DisplayName|InstallDate)\|?", ""), "\|$", "")
    If $sCols <> "" Then $aCols = StringSplit($sCols, "|")

    If @OSArch = "X86" Then
        $iArch = 1
        $sHKLMx86 = "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
    Else
        If @AutoitX64 Then
            $sHKLMx86 = "HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
            $sHKLM64 = "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
        Else
            $sHKLMx86 = "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
            $sHKLM64 = "HKLM64\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
        EndIf
    EndIf

    If BitAND($iArch, 1) Then
        Redim $aKeys[ UBound($aKeys) + 1]
        $aKeys [ UBound($aKeys) - 1] = $sHKLMx86
    EndIf

    If BitAND($iArch, 2) Then
        Redim $aKeys[ UBound($aKeys) + 1]
        $aKeys [ UBound($aKeys) - 1] = $sHKLM64
    EndIf


    For $i = 0 To UBound($aKeys) - 1
        $n = 1
        While 1
            $iFound = 1
            $aSubKey = _RegEnumKeyEx($aKeys[$i], $n)
            If @error Then ExitLoop

            $sSubKey = $aSubKey[0]
            $sKeyDate = StringRegExpReplace($aSubKey[1], "^(\d{4})/(\d{2})/(\d{2}).+", "$1$2$3")
            $sDisplayName = RegRead($aKeys[$i] & "\" & $sSubKey, "DisplayName")
            $sDate = RegRead($aKeys[$i] & "\" & $sSubKey, "InstallDate")
            If $sDate = "" Then $sDate = $sKeyDate

            If $sDisplayName <> "" Then
                 If $sValueName <> "" Then
                    $iFound = 0
                    $sValue = RegRead( $aKeys[$i] & "\" & $sSubKey, $sValueName)
                    If ( $iSearchMode = 0 AND StringInStr($sValue, $sFilter) = 1 ) OR _
                       ( $iSearchMode = 1 AND StringInStr($sValue, $sFilter) ) OR _
                       ( $iSearchMode = 2 AND $sValue = $sFilter ) OR _
                       ( $iSearchMode = 3 AND StringRegExp($sValue, "(?i)" & $sFilter) ) Then
                            $iFound = 1
                    EndIf
                EndIf

                If $iFound Then
                    Redim $aResult[ UBound($aResult) + 1][ 4 + $aCols[0] ]
                    $aResult[ UBound($aResult) - 1][0] = $aKeys[$i]
                    $aResult[ UBound($aResult) - 1][1] = $sSubKey
                    $aResult[ UBound($aResult) - 1][2] = $sDisplayName
                    $aResult[ UBound($aResult) - 1][3] = $sDate

                    For $iCol = 1 To $aCols[0]
                        $aResult[ UBound($aResult) - 1][3 + $iCol] = RegRead( $aKeys[$i] & "\" & $sSubKey, $aCols[$iCol])
                    Next
                EndIf
            EndIf

            $n += 1
        WEnd
    Next

    $aResult[0][0] = UBound($aResult) - 1
    Return $aResult
EndFunc




; #FUNCTION# ====================================================================================================================
; Name ..........: _RegEnumKeyEx
; Description ...: Enumerates the subkeys of the specified open registry key. The function retrieves information about one subkey
;                  each time it is called.
; Syntax ........: _RegEnumKeyEx($sKey, $iInstance)
; Parameters ....: $sKey                - The registry key to read.
;                  $iInstance           - The 1-based key instance to retrieve.
; Return values .: Success              - A 1D array :
;                                          $aArray[0] = subkey name
;                                          $aArray[1] = time at which the enumerated subkey was last written
;                  Failure               - Returns 0 and set @eror to non-zero value
; Author ........: jguinch
; ===============================================================================================================================
Func _RegEnumKeyEx($sKey, $iInstance)
    If NOT IsDeclared("KEY_WOW64_32KEY") Then Local Const $KEY_WOW64_32KEY = 0x0200
    If NOT IsDeclared("KEY_WOW64_64KEY") Then Local Const $KEY_WOW64_64KEY = 0x0100
    If NOT IsDeclared("KEY_ENUMERATE_SUB_KEYS") Then Local Const $KEY_ENUMERATE_SUB_KEYS = 0x0008

    If NOT IsDeclared("tagFILETIME") Then Local Const $tagFILETIME = "struct;dword Lo;dword Hi;endstruct"

    Local $iSamDesired = $KEY_ENUMERATE_SUB_KEYS

    Local $iX64Key = 0, $sRootKey, $aResult[2]

    Local $sRoot = StringRegExpReplace($sKey, "\\.+", "")
    Local $sSubkey = StringRegExpReplace($sKey, "^[^\\]+\\", "")

    $sRoot = StringReplace($sRoot, "64", "")
    If @extended Then $iX64Key = 1

    If NOT IsInt($iInstance) OR $iInstance < 1 Then Return SetError(2, 0, 0)

    Switch $sRoot
        Case "HKCR", "HKEY_CLASSES_ROOT"
            $sRootKey = 0x80000000
        Case "HKLM", "HKEY_LOCAL_MACHINE"
            $sRootKey = 0x80000002
        Case "HKCU", "HKEY_CURRENT_USER"
            $sRootKey = 0x80000001
        Case "HKU", "HKEY_USERS"
            $sRootKey = 0x80000003
        Case  "HKCC", "HKEY_CURRENT_CONFIG"
            $sRootKey = 0x80000005
        Case Else
            Return SetError(1, 0, 0)
    EndSwitch

    If StringRegExp(@OSArch, "64$") Then
        If @AutoItX64 OR $iX64Key Then
            $iSamDesired = BitOR($iSamDesired, $KEY_WOW64_64KEY)
        Else
            $iSamDesired = BitOR($iSamDesired, $KEY_WOW64_32KEY)
        EndIf
    EndIf

    Local $aRetOPen = DllCall('advapi32.dll', 'long', 'RegOpenKeyExW', 'handle', $sRootKey, 'wstr', $sSubKey, 'dword', 0, 'dword', $iSamDesired, 'ulong_ptr*', 0)
    If @error Then Return SetError(@error, @extended, 0)
    If $aRetOPen[0] Then Return SetError(10, $aRetOPen[0], 0)

    Local $hKey = $aRetOPen[5]

    Local $tFILETIME = DllStructCreate($tagFILETIME)
    Local $lpftLastWriteTime = DllStructGetPtr($tFILETIME)

    Local $aRetEnum = DllCall('Advapi32.dll', 'long', 'RegEnumKeyExW', 'long', $hKey, 'dword', $iInstance - 1, 'wstr', "", 'dword*', 255, 'dword', "", 'ptr', "", 'dword', "", 'ptr', $lpftLastWriteTime)
    If Not IsArray($aRetEnum) OR $aRetEnum[0] <> 0 Then Return SetError( 3, 0, 1)

    Local $tFILETIME2 = _Date_Time_FileTimeToLocalFileTime($lpftLastWriteTime)
    Local $localtime = _Date_Time_FileTimeToStr($tFILETIME2, 1)

    $aResult[0] = $aRetEnum[3]
    $aResult[1] = $localtime

    Return $aResult
EndFunc

 

Link to comment
Share on other sites

  • 4 months later...


I have a script for installed programs. It works correctly for all programs except Java. It doesn't enumerate Java correctly. Up to this time I have been running Java as a separate function. I would like to incorporate it into this script.
    NOTE: version 8.101.13 is NOT out of date.
    

 
    
#include <Misc.au3>
#Include <Date.au3>
    $File = FileOpen("text.txt", 2)
    ; #EXAMPLE ======================================================================================================================
Local $aApps = [["Java.+?\d+ Update \d", "8.101.13", 3]]
    Local $iIsInstalled, $sUTP
Local $aOFDPrograms
For $i = 0 To UBound($aApps) - 1
    $iIsInstalled = _IsInstalled($aApps[$i][0], $aApps[$i][1], $aApps[$i][2])
    If $iIsInstalled Then
    $sRes =  ""
       Switch @extended
            Case -1
                $sUTP = $aOFDPrograms
            Case 1
                $sUTP = " (version " & $aApps[$i][1] & ")"
            Case 0
                $sUTP = " (version " & $aApps[$i][1] & ")"
        EndSwitch
Else
        $sRes = " is not installed."
        EndIf
        If $sRes = " is not installed." Then
        $NoProgram = ($aApps[$i][0] & $sRes & $sUTP & @CRLF)
        ElseIf $aApps[$i][0] = "Adobe Flash Player 22 ActiveX" Then
        FileWrite($File, "Adobe Flash Player ActiveX" & $sRes & $sUTP & @CRLF)
        ElseIf $sUTP =  $aOFDPrograms Then
        ConsoleWrite($aApps[$i][0] & $sRes & $sUTP & @CRLF)
Else
        FileWrite($File, $aApps[$i][0] & $sRes & $sUTP & @CRLF)
EndIf
 Next
; ===============================================================================================================================
    ; #FUNCTION# ====================================================================================================================
; Name ..........: _IsInstalled
; Description ...: Checks if an application is installed on the local computer.
; Syntax ........: _IsInstalled($sAppname[, $sMinVersion = 0[, $iSearchMode = 0]])
; Parameters ....: $sAppname            - Application name or partial name (depending of $iSearchMode value).
;                  $sMinVersion         - [optional] Minimum version to check. Default is 0 (don't check for the version).
;                  $iSearchMode         - [optional] Search mode. Default is 0.
;                                            0 : Match string from the start.
;                                            1 : Match any substring.
;                                            2 : Exact string match.
;                                            3 : $sAppname is a regular expression
; Return values .: Success  - 1
;                  Failure  - 0
; Author ........: jguinch
; Remarks .......: on success, @extended is set to:
;                      0   - The specified version is installed (or no version checked if $sMinVersion^= 0)
;                      1   - A newer version is installed
;                     -1   - An older version is installed
; ===============================================================================================================================
Func _IsInstalled($sAppname, $sMinVersion, $iSearchMode = 0)
       Local $aAppList = _UninstallList("DisplayName", $sAppname, "DisplayVersion", $iSearchMode)
    If Not $aAppList[0][0] Then Return 0
    Local $iExtended = -1
        For $i = 1 To $aAppList[0][0]
        $sAppName = $aAppList[$i][2]
        $sVersion = $aAppList[$i][4]
            If StringRegExp($sAppName, "\d+\h*(\.\d+)+$") Then
            $aAppInfo = StringRegExp($sAppName, "(.+?)\h*(\d+(?:\.\d+)+)$", 1)
            $sAppName = $aAppInfo[0]
            If $sVersion = "" Then $sVersion = $aAppInfo[1]
        EndIf
            If $sMinVersion Then
            $iVersionComp = _VersionCompare($sVersion, $sMinVersion )
            If $iVersionComp = 0 And $iExtended = -1 Then $iExtended = 0
            If $iVersionComp = 1 And $iExtended <= 0 Then $iExtended = 1
        Else
            $iExtended = 0
        EndIf
    Next
    Return SetError(0, $iExtended, 1)
    EndFunc
    Local $aOFDPrograms
For $i = 0 To UBound($aApps) - 1
    $aOFDPrograms = _GetOutOfDatePrograms($aApps[$i][0], $aApps[$i][1], $aApps[$i][2])
   If Not @error Then
    For $n = 0 To UBound($aOFDPrograms) - 1
        If $aApps[$i][0] = "Adobe Reader XI" Then
        FileWrite($File, "Adobe Reader XI" & " (version " & $aOFDPrograms[$n][1] & ")"  & " " & "is *out of Date*" & @CRLF)
        Else
            FileWrite($File, $aOFDPrograms[$n][0] & " (version " & $aOFDPrograms[$n][1] & ")"  & " " & "is *out of Date*" & @CRLF)
        EndIf
        Next
    EndIf
Next
     Func _GetOutOfDatePrograms($sAppname, $sMinVersion, $iSearchMode = 0)
    Local $aAppList = _UninstallList("DisplayName", $sAppname, "DisplayVersion", $iSearchMode)
    If Not $aAppList[0][0] Then Return 0
    Local $iExtended = -1
    Local $aRet[ $aAppList[0][0]  ][2], $n = 0
        For $i = 1 To $aAppList[0][0]
        $sAppName = $aAppList[$i][2]
        $sVersion = $aAppList[$i][4]
            If StringRegExp($sAppName, "\d+\h*(\.\d+)+$") Then
            $aAppInfo = StringRegExp($sAppName, "(.+?)\h*(\d+(?:\.\d+)+)$", 1)
            $sAppName = $aAppInfo[0]
            If $sVersion = "" Then $sVersion = $aAppInfo[1]
        EndIf
            $iVersionComp = _VersionCompare($sVersion, $sMinVersion )
        If $iVersionComp = -1 Then
            $aRet[$n][0] = $sAppName
            $aRet[$n][1] = $sVersion
            $n += 1
        EndIf
    Next
        If $n = 0 Then Return SetError(1, 0, 0)
    ReDim $aRet[$n][2]
    Return $aRet
    EndFunc
    ; #FUNCTION# ====================================================================================================================
; Name ..........: _UninstallList
; Description ...: Returns an array of matching uninstall keys from registry, with an optional filter
; Syntax ........: _UninstallList([$sValueName = ""[, $sFilter = ""[, $sCols = ""[, $iSearchMode = 0[,$ iArch = 3]]]]]])
; Parameters ....: $sValueName       - [optional] Registry value used for the filter.
;                                          Default is all keys ($sFilter do not operates).
;                  $sFilter          - [optional] String to search in $sValueName. Filter is not case sensitive.
;                  $sCols            - [optional] Additional values to retrieve. Use "|" to separate each value.
;                                          Each value adds a column in the returned array
;                  $iSearchMode      - [optional] Search mode. Default is 0.
;                                          0 : Match string from the start.
;                                          1 : Match any substring.
;                                          2 : Exact string match.
;                                          3 : $sFilter is a regular expression
;                  $iArch            - [optional] Registry keys to search in. Default is 3.
;                                          1 : x86 registry keys only
;                                          2 : x64 registry keys only
;                                          3 : both x86 and x64 registry keys
; Return values .: Returns a 2D array of registry keys and values :
;                      $array[0][0] : Number of keys
;                      $array[n][0] : Registry key path
;                      $array[n][1] : Registry subkey
;                      $array[n][2] : Display name
;                      $array[n][3] : Installation date (YYYYMMDD format)
;                      $array[n][4] : 1st additional value specified in $sCols (only if $sCols is set)
;                      $array[n][5] : 2nd additional value specified in $sCols (only if $sCols contains at least 2 entries)
;                      $array[n][x] : Nth additional value ...
; Author ........: jguinch
; ===============================================================================================================================
Func _UninstallList($sValueName = "", $sFilter = "", $sCols = "", $iSearchMode = 0, $iArch = 3)
    Local $sHKLMx86, $sHKLM64, $sHKCU = "HKCU\Software\Microsoft\Windows\CurrentVersion\Uninstall"
    Local $aKeys[1] = [ $sHKCU ]
    Local $sDisplayName, $sSubKey, $sKeyDate, $sDate, $sValue, $iFound, $n, $aResult[1][4], $iCol
    Local $aCols[1] = [0]
        If NOT IsInt($iArch) OR $iArch < 0 OR $iArch > 3 Then Return SetError(1, 0, 0)
    If NOT IsInt($iSearchMode) OR $iSearchMode < 0 OR $iSearchMode > 3 Then Return SetError(1, 0, 0)
        $sCols = StringRegExpReplace( StringRegExpReplace($sCols, "(?i)(DisplayName|InstallDate)\|?", ""), "\|$", "")
    If $sCols <> "" Then $aCols = StringSplit($sCols, "|")
        If @OSArch = "X86" Then
        $iArch = 1
        $sHKLMx86 = "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
    Else
        If @AutoitX64 Then
            $sHKLMx86 = "HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
            $sHKLM64 = "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
        Else
            $sHKLMx86 = "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
            $sHKLM64 = "HKLM64\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
        EndIf
    EndIf
        If BitAND($iArch, 1) Then
        Redim $aKeys[ UBound($aKeys) + 1]
        $aKeys [ UBound($aKeys) - 1] = $sHKLMx86
    EndIf
        If BitAND($iArch, 2) Then
        Redim $aKeys[ UBound($aKeys) + 1]
        $aKeys [ UBound($aKeys) - 1] = $sHKLM64
    EndIf
    
    For $i = 0 To UBound($aKeys) - 1
        $n = 1
        While 1
            $iFound = 1
            $aSubKey = _RegEnumKeyEx($aKeys[$i], $n)
            If @error Then ExitLoop
                $sSubKey = $aSubKey[0]
            $sKeyDate = StringRegExpReplace($aSubKey[1], "^(\d{4})/(\d{2})/(\d{2}).+", "$1$2$3")
            $sDisplayName = RegRead($aKeys[$i] & "\" & $sSubKey, "DisplayName")
            $sDate = RegRead($aKeys[$i] & "\" & $sSubKey, "InstallDate")
            If $sDate = "" Then $sDate = $sKeyDate
                If $sDisplayName <> "" Then
                 If $sValueName <> "" Then
                    $iFound = 0
                    $sValue = RegRead( $aKeys[$i] & "\" & $sSubKey, $sValueName)
                    If ( $iSearchMode = 0 AND StringInStr($sValue, $sFilter) = 1 ) OR _
                       ( $iSearchMode = 1 AND StringInStr($sValue, $sFilter) ) OR _
                       ( $iSearchMode = 2 AND $sValue = $sFilter ) OR _
                       ( $iSearchMode = 3 AND StringRegExp($sValue, "(?i)" & $sFilter) ) Then
                            $iFound = 1
                    EndIf
                EndIf
                    If $iFound Then
                    Redim $aResult[ UBound($aResult) + 1][ 4 + $aCols[0] ]
                    $aResult[ UBound($aResult) - 1][0] = $aKeys[$i]
                    $aResult[ UBound($aResult) - 1][1] = $sSubKey
                    $aResult[ UBound($aResult) - 1][2] = $sDisplayName
                    $aResult[ UBound($aResult) - 1][3] = $sDate
                        For $iCol = 1 To $aCols[0]
                        $aResult[ UBound($aResult) - 1][3 + $iCol] = RegRead( $aKeys[$i] & "\" & $sSubKey, $aCols[$iCol])
                    Next
                EndIf
            EndIf
                $n += 1
        WEnd
    Next
        $aResult[0][0] = UBound($aResult) - 1
    Return $aResult
EndFunc
     
    
; #FUNCTION# ====================================================================================================================
; Name ..........: _RegEnumKeyEx
; Description ...: Enumerates the subkeys of the specified open registry key. The function retrieves information about one subkey
;                  each time it is called.
; Syntax ........: _RegEnumKeyEx($sKey, $iInstance)
; Parameters ....: $sKey                - The registry key to read.
;                  $iInstance           - The 1-based key instance to retrieve.
; Return values .: Success              - A 1D array :
;                                          $aArray[0] = subkey name
;                                          $aArray[1] = time at which the enumerated subkey was last written
;                  Failure               - Returns 0 and set @eror to non-zero value
; Author ........: jguinch
; ===============================================================================================================================
Func _RegEnumKeyEx($sKey, $iInstance)
    If NOT IsDeclared("KEY_WOW64_32KEY") Then Local Const $KEY_WOW64_32KEY = 0x0200
    If NOT IsDeclared("KEY_WOW64_64KEY") Then Local Const $KEY_WOW64_64KEY = 0x0100
    If NOT IsDeclared("KEY_ENUMERATE_SUB_KEYS") Then Local Const $KEY_ENUMERATE_SUB_KEYS = 0x0008
        If NOT IsDeclared("tagFILETIME") Then Local Const $tagFILETIME = "struct;dword Lo;dword Hi;endstruct"
        Local $iSamDesired = $KEY_ENUMERATE_SUB_KEYS
        Local $iX64Key = 0, $sRootKey, $aResult[2]
        Local $sRoot = StringRegExpReplace($sKey, "\\.+", "")
    Local $sSubkey = StringRegExpReplace($sKey, "^[^\\]+\\", "")
        $sRoot = StringReplace($sRoot, "64", "")
    If @extended Then $iX64Key = 1
        If NOT IsInt($iInstance) OR $iInstance < 1 Then Return SetError(2, 0, 0)
        Switch $sRoot
        Case "HKCR", "HKEY_CLASSES_ROOT"
            $sRootKey = 0x80000000
        Case "HKLM", "HKEY_LOCAL_MACHINE"
            $sRootKey = 0x80000002
        Case "HKCU", "HKEY_CURRENT_USER"
            $sRootKey = 0x80000001
        Case "HKU", "HKEY_USERS"
            $sRootKey = 0x80000003
        Case  "HKCC", "HKEY_CURRENT_CONFIG"
            $sRootKey = 0x80000005
        Case Else
            Return SetError(1, 0, 0)
    EndSwitch
        If StringRegExp(@OSArch, "64$") Then
        If @AutoItX64 OR $iX64Key Then
            $iSamDesired = BitOR($iSamDesired, $KEY_WOW64_64KEY)
        Else
            $iSamDesired = BitOR($iSamDesired, $KEY_WOW64_32KEY)
        EndIf
    EndIf
        Local $aRetOPen = DllCall('advapi32.dll', 'long', 'RegOpenKeyExW', 'handle', $sRootKey, 'wstr', $sSubKey, 'dword', 0, 'dword', $iSamDesired, 'ulong_ptr*', 0)
    If @error Then Return SetError(@error, @extended, 0)
    If $aRetOPen[0] Then Return SetError(10, $aRetOPen[0], 0)
        Local $hKey = $aRetOPen[5]
        Local $tFILETIME = DllStructCreate($tagFILETIME)
    Local $lpftLastWriteTime = DllStructGetPtr($tFILETIME)
        Local $aRetEnum = DllCall('Advapi32.dll', 'long', 'RegEnumKeyExW', 'long', $hKey, 'dword', $iInstance - 1, 'wstr', "", 'dword*', 255, 'dword', "", 'ptr', "", 'dword', "", 'ptr', $lpftLastWriteTime)
    If Not IsArray($aRetEnum) OR $aRetEnum[0] <> 0 Then Return SetError( 3, 0, 1)
        Local $tFILETIME2 = _Date_Time_FileTimeToLocalFileTime($lpftLastWriteTime)
    Local $localtime = _Date_Time_FileTimeToStr($tFILETIME2, 1)
        $aResult[0] = $aRetEnum[3]
    $aResult[1] = $localtime
        Return $aResult
EndFunc

Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...