Jump to content
MarkBe

[SOLVED] Registry check function

Recommended Posts

MarkBe

Hi

I am trying to check a number of applications are up to date and install the update if required. This will run as a shutdown script, pushed out through Group Policy.

I am querying various registry keys to determine if

  1. The software is actually installed
  2. The software is at the correct version

Once the need for update is determined then it calls another function to run the update.

If the software is up to date or not installed, it moves down to the next software section which changes the registry key variables and calls the registry query function again

I have managed to get the function for (un)installs to work but I am having trouble with the registry query function

#NoTrayIcon
#include <AutoItConstants.au3>
#include <MsgBoxConstants.au3>
#include <FileConstants.au3>

; Here we go!
;##########################################################################################################

;Declare variables
Global $RegKey86, $RegKey64, $RegValueName, $RegValueData, $CheckVersion86, $CheckVersion64


; 7Zip
;##########################################################################################################
_7Zip_Function()
Func _7Zip_Function()

; Registry location and values that are checked for current software version
; Ensure the x64 key is preceeded with 'HKLM64'
$RegKey86="HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\7-Zip"
$RegKey64="HKLM64\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\7-Zip"
$RegValueName="DisplayVersion"
$RegValueData="16.04"

; Excecution
; ---------------------------------------------------------------------------------------------------------

If _CheckSW() = 1 Then
        _UninstallOldVer()
        _InstallSW()
    EndIf
EndFunc ;==>_7Zip_Function


; Functions
;##########################################################################################################
Func _CheckSW()
    $CheckVersion86=RegRead ($RegKey86, $RegValueName)
    $CheckVersion64=RegRead ($RegKey64, $RegValueName)
    If $CheckVersion86=$RegValueData Or $CheckVersion64=$RegValueData Then
        Return 0
    ElseIf $CheckVersion86="" And $CheckVersion64="" Then
        Return 0
    Else
        Return 1
    EndIf
EndFunc ;==>CheckSW

 

Edited by MarkBe
Solved

Share this post


Link to post
Share on other sites
Subz

What trouble are you having?  Personally I would use _VersionCompare something like:

#NoTrayIcon
#include <AutoItConstants.au3>
#include <MsgBoxConstants.au3>
#include <FileConstants.au3>
#include <Misc.au3>

; Here we go!
;##########################################################################################################

;Declare variables
Global $RegKey86, $RegKey64, $RegValueName, $RegValueData, $CheckVersion86, $CheckVersion64

; 7Zip
;##########################################################################################################
_7Zip_Function()
Func _7Zip_Function()

; Registry location and values that are checked for current software version
; Ensure the x64 key is preceeded with 'HKLM64'
    $RegKey86="HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\7-Zip"
    $RegKey64="HKLM64\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\7-Zip"
    $RegValueName="DisplayVersion"
    $RegValueData="16.04"

; Excecution
; ---------------------------------------------------------------------------------------------------------
    If _RegVersionCompare($RegKey64, $RegValueName, $RegValueData) = 1 Then
        _UninstallOldVer()
        _InstallSW()
    EndIf
EndFunc ;==>_7Zip_Function

; Functions
;##########################################################################################################
Func _RegVersionCompare($sRegHive, $sRegKey, $sRegValue)
    Local $iVersionCompare = _VersionCompare(RegRead($sRegHive, $sRegKey), $sRegValue)
    Switch $iVersionCompare
        Case 0
            Return 0
        Case 1
            Return 0
        Case -1
            Return 1
    EndSwitch
EndFunc ;==>CheckSW

 

  • Like 1

Share this post


Link to post
Share on other sites
MarkBe

Thanks Subz

This is very close. Once I had put in #include <Misc.au3> it runs the installer if the software is out of date and does not run the installer if it is current.

There is one scenario that isn't working quite right for me yet, if the software isn't installed at all, I don't want the installer to run. Do you have a suggestion for handling that?

Thanks

p.s. I like the fact that if someone has manually installed a newer version that the script you suggested doesn't roll it back

Edited by MarkBe
p.s.

Share this post


Link to post
Share on other sites
Subz

You could use the following:

Func _RegVersionCompare($sRegHive, $sRegKey, $sRegValue)
    If RegRead($sRegHive, $sRegKey) = "" Then Return 0
    Local $iVersionCompare = _VersionCompare(RegRead($sRegHive, $sRegKey), $sRegValue)
    Switch $iVersionCompare
        Case 0
            Return 0
        Case 1
            Return 0
        Case -1
            Return 1
    EndSwitch
EndFunc ;==>CheckSW

 

Share this post


Link to post
Share on other sites
MarkBe

Thanks Subz

You have pointed me in the right direction. Unfortunately the old version of 7Zip I am updating stores the version in a different hive ... I'll try and fix this new development myself and post back if I get stuck again

Now I just need to work out how to mark your reply as the answer ...

Share this post


Link to post
Share on other sites
Subz

They only have the Like this buttons on each post, if you want to mark the post as resolved, you can edit the first post which allows you to edit the title of the post.

Share this post


Link to post
Share on other sites
MarkBe

There's probably a more elegant way to do this but I ended up with the following:

#NoTrayIcon
#include <AutoItConstants.au3>
#include <MsgBoxConstants.au3>
#include <FileConstants.au3>
#include <Misc.au3>

; Here we go!
;##########################################################################################################

;Declare variables
Global $RegHive86, $RegHive64, $RegKey, $RegValue, $OldVerRegHive86, $OldVerRegHive64, $OldVerRegHive86on64, $OldVerRegVerString, $OldVerRegVerValue, $OldVerUninstallStringx86, $OldVerUninstallStringx64

; 7Zip
;##########################################################################################################
_7Zip_Function()
Func _7Zip_Function()

; Variables
; ---------------------------------------------------------------------------------------------------------
; Registry location and values that are checked for current software version. Don't use paths with hash values
; Ensure the x64 key is preceeded with 'HKLM64'
$RegHive86="HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\7-Zip"
$RegHive64="HKLM64\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\7-Zip"
$RegKey="DisplayVersion"
$RegValue="16.04"

; Reg keys and values that are checked for old versions
$OldVerRegHive86="HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{23170F69-40C1-2701-0920-000001000000}"
$OldVerRegHive64="HKLM64\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{23170F69-40C1-2702-0920-000001000000}"
$OldVerRegHive86on64="HKLM64\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{23170F69-40C1-2701-0920-000001000000}"

    If _RegVersionCompare($RegHive64, $RegHive86, $OldVerRegHive64, $OldVerRegHive86, $OldVerRegHive86on64, $RegKey, $RegValue) = 1 Then
        _UninstallOldVer()
        _InstallSW()
    EndIf
EndFunc ;==>_7Zip_Function


; Functions
;##########################################################################################################
Func _RegVersionCompare($sRegHive64, $sRegHive86, $sOldVerRegHive64, $sOldVerRegHive86, $sOldVerRegHive86on64, $sRegKey, $sRegValue)
    If Not RegRead($sRegHive64, $sRegKey) = "" Then
        Local $iVersionCompare = _VersionCompare(RegRead($sRegHive64, $sRegKey), $sRegValue)
        Switch $iVersionCompare
            Case 0
                Return 0
            Case 1
                Return 0
            Case -1
                Return 1
        EndSwitch
    ElseIf Not RegRead($sRegHive86, $sRegKey) = "" Then
        Local $iVersionCompare = _VersionCompare(RegRead($sRegHive86, $sRegKey), $sRegValue)
        Switch $iVersionCompare
            Case 0
                Return 0
            Case 1
                Return 0
            Case -1
                Return 1
        EndSwitch
    ElseIf Not RegRead($sOldVerRegHive64, $sRegKey) = "" Then
        Return 1
    ElseIf Not RegRead($sOldVerRegHive86, $sRegKey) = "" Then
        Return 1
    ElseIf Not RegRead($sOldVerRegHive86on64, $sRegKey) = "" Then
        Return 1
    Else
        Return 0
    EndIf
EndFunc ;==>_RegVersionCompare

 

Share this post


Link to post
Share on other sites
Subz

Couple of things to note:

$OldVerRegHive86 = $OldVerRegHive86on64
- HKLM on a x64 system accesses 32 bit hive i.e. HKLM\Software\Wow6432Node

Since x64 and x86 versions of 7-zip are different installers you should specify which version to install using @OSArch macro, you may also need to get the Guids for both x86/x64 to uninstall for example:

  • "{23170F69-40C1-2701-0920-000001000000}" ; 7-Zip 9.20 x86 Msi Version
  • "{23170F69-40C1-2702-0920-000001000000}" ; 7-Zip 9.20 x64 Msi Version
  • "{23170F69-40C1-2701-1604-000001000000}" ; 7-Zip 16.04 x86 Msi Version
  • "{23170F69-40C1-2702-1604-000001000000}" ; 7-Zip 16.04 x64 Msi Version

Share this post


Link to post
Share on other sites
MarkBe

Yes, discovered that the hard way - last time I deployed this using a batch script

What I have in that section for 7Zip is

#NoTrayIcon
#include <AutoItConstants.au3>
#include <MsgBoxConstants.au3>
#include <FileConstants.au3>
#include <Misc.au3>

$SoftwareName="7Zip Archiver"
$SoftwareVersion="16.04"
$InstallingUpdateMessage="Updating " & $SoftwareName & " to " & $SoftwareVersion & "."
$EndMessage="The current version of " & $SoftwareName & " is now installed."
$FailMessage=$SoftwareName & " update failed to install. Please report error to your local IT department."
$UninstallingOldMessage="Uninstalling old versions of " & $SoftwareName & "."

; Paths and files (Don't forget the "\" at the end of the path)==> \\Servername\Share\
$SourcePath="\\domain\dfsroot\share\7Zip\"
$WorkingDirectory="C:\InstallCache\7zip\"
$x86Installer="7z1604.exe"
$x64Installer="7z1604x64.exe"
$SWInstaller=((@OSArch = "X86") ? $x86Installer : $x64Installer)
$InstallerSwitches=" /S"

_InstallSW()
Func _InstallSW()
    MsgBox ($MB_ICONINFORMATION, "Installing", $InstallingUpdateMessage, 3)
    FileCopy ($SourcePath & $SWInstaller, $WorkingDirectory & $SWInstaller, $FC_OVERWRITE + $FC_CREATEPATH)
    If StringLower(StringRight($SWInstaller, 4))=".exe" Then
        RunWait (@ComSpec & ' /k START "' & $SoftwareName & ' Installer" /wait "' & $WorkingDirectory & $SWInstaller & '"' & $InstallerSwitches & ' && EXIT', @SystemDir, @SW_HIDE)
    Else
        RunWait ('msiexec /i "' & $WorkingDirectory & $SWInstaller & '"' & $InstallerSwitches, @SystemDir)
    EndIf
EndFunc ;==>InstallSW

 

Share this post


Link to post
Share on other sites
Subz

You should be able to run the install directly from the domain share, but if you wish to copy, I would probably place an "If FileExists" so that it doesn't copy down everytime, I would also use SplashTextOn function to display the progress of the install.  Not sure why you need cmd to run the exe you should be able to just run it directly from the Working directory using RunWait.  Lastly not sure what the last Runwait ('msiexe /i... is suppose to do :)

Share this post


Link to post
Share on other sites
MarkBe
2 minutes ago, Subz said:

You should be able to run the install directly from the domain share, but if you wish to copy, I would probably place an "If FileExists" so that it doesn't copy down everytime, I would also use SplashTextOn function to display the progress of the install.  Not sure why you need cmd to run the exe you should be able to just run it directly from the Working directory using RunWait.  Lastly not sure what the last Runwait ('msiexe /i... is suppose to do :)

I used to run the installers from the domain share but some remote users found that the script timed out before completion

I also decided to replace on copy because some users got a corrupted copy on the C:\ and so I needed the EXE to be replaced so it didn't fail repetitively! There are some awful network connections between the servers and some of my users - being addressed at the moment though :-)

SplashTextOn sounds good. I haven't discovered many of the cool features of AutoIT yet ... I'm a bit of a noob!

This was taken all from a RunAsWait so I needed to plug in credentials to elevate. Not sure why I used CMD ... think it was because I used to do all the grunt work with CMD and just use AutoIT to elevate. Ran into problems (x64 v x86 batch) so decided to learn AutoIT.

Lastly, I have the msiexec in the function so that if, in the next software section the installer is an MSI then I can still call the same _InstallSW() function and just pipe in different variables

Share this post


Link to post
Share on other sites
MarkBe

definitely cleaner:

Func _InstallSW()
    MsgBox ($MB_ICONINFORMATION, "Installing", $InstallingUpdateMessage, 3)
    FileCopy ($SourcePath & $SWInstaller, $WorkingDirectory & $SWInstaller, $FC_OVERWRITE + $FC_CREATEPATH)
    If StringLower(StringRight($SWInstaller, 4))=".exe" Then
        RunWait ('"' & $WorkingDirectory & $SWInstaller & '"' & $InstallerSwitches)
    Else
        RunWait ('msiexec /i "' & $WorkingDirectory & $SWInstaller & '"' & $InstallerSwitches)
    EndIf
EndFunc ;==>InstallSW

 

Share this post


Link to post
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

  • Similar Content

    • FrancescoDiMuro
      By FrancescoDiMuro
      Good evening everyone
      I was trying to insert function header to the functions of my script, but, in the SciTE console, this appears:
      Function or struct definition not found, unable to insert header. @Jos Any suggestion?
      Thanks in advance.

      Best Regards.
    • Rskm
      By Rskm
      Hi, I wrote the below code to learn user defined functions.. jam is the function which calculates summation and division of two numbers $a, $b.. I expect the $sum and $div receives the results $r and $s respectively from the function... but the msbox in the main program doesn't display results properly, while the one inside func shows it correclty. how do I pull the values in $r and $s to $sum and $div respectively.. thanks for all the help on this forum
       
      global $a,$b,$sum,$div
      $a=1
      $b=2 jam($a,$b,$sum,$div) msgbox(0,"results",$sum&" , "&$div)     func jam($p,$q,$r,$s )
       $r=$p+$q  $s = $p/$q msgbox(0,"results",$r&" , "&$s) EndFunc  
    • Amixg
      By Amixg
      Hi! I have another problem with AutoIT.  You see, I'm still the one who's just starting out with this great programming language. I have a problem with AutoIT, it seems not to recognize the "StringReplace" function even when it is by default. The code was made half in KODA and half of my own. It is a software programmed for the Italian language (I am Italian) and translate the SMS language into Italian correct. Would you help me? Thanks in advance.
       
      #include <ButtonConstants.au3> #include <EditConstants.au3> #include <GUIConstantsEx.au3> #include <StaticConstants.au3> #include <WindowsConstants.au3> $hull = "hello" StringReplace($hull, "hello", "hellx") $Form1 = GUICreate("Linguaggio SMS A Italiano", 507, 498, 192, 124) $Edit1 = GUICtrlCreateEdit("", 24, 40, 465, 177) GUICtrlSetData(-1, "") $Label1 = GUICtrlCreateLabel("Inserisci qui il testo che non riesci a capire:", 24, 8, 205, 17) $Label2 = GUICtrlCreateLabel("Ecco il testo tradotto(non toccare questo campo):", 27, 237, 237, 17) $Edit2 = GUICtrlCreateEdit("", 24, 264, 465, 137) GUICtrlSetData(-1, "") $Button1 = GUICtrlCreateButton("Traduci", 104, 424, 249, 49) GUISetState(@SW_SHOW) While 1 $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE Exit Case $Button1 StringReplace(GUICtrlGetData($Label1), "qlc", "qualcuno") StringReplace(GUICtrlGetData($Label1), "qls", "qualcosa") StringReplace(GUICtrlGetData($Label1), "ke", "che") StringReplace(GUICtrlGetData($Label1), "x", "per") StringReplace(GUICtrlGetData($Label1), "pls", "per favore") StringReplace(GUICtrlGetData($Label1), "tu6", "tu sei") StringReplace(GUICtrlGetData($Label1), "zzz", "mi fai dormire") StringReplace(GUICtrlGetData($Label1), "hagn", "Buonanotte") StringReplace(GUICtrlGetData($Label1), "tvtb", "Ti voglio tanto bene") StringReplace(GUICtrlGetData($Label1), "tat", "Ti amo tanto") StringReplace(GUICtrlGetData($Label1), "lafs", "Amore a prima vista") StringReplace(GUICtrlGetData($Label1), "fli?", "Flirtiamo?") StringReplace(GUICtrlGetData($Label1), "msidt", "Mi sono innamorato di te") StringReplace(GUICtrlGetData($Label1), "ba", "Bacio") StringReplace(GUICtrlGetData($Label1), "midi", "Mi dispiace.") StringReplace(GUICtrlGetData($Label1), "ntm", "Non ti merito") StringReplace(GUICtrlGetData($Label1), "tdp", "Togliti dai piedi.") StringReplace(GUICtrlGetData($Label1), "amò", "Amore") StringReplace(GUICtrlGetData($Label1), "ap", "A presto!") StringReplace(GUICtrlGetData($Label1), "cmq", "comunque") StringReplace(GUICtrlGetData($Label1), "cvd", "Ci vediamo dopo") StringReplace(GUICtrlGetData($Label1), "Tvb", "Ti voglio bene") StringReplace(GUICtrlGetData($Label1), "nn", "non") StringReplace(GUICtrlGetData($Label1), "risp", "rispondimi") StringReplace(GUICtrlGetData($Label1), "cel", "cellulare") StringReplace(GUICtrlGetData($Label1), "dom", "qualcosa") StringReplace(GUICtrlGetData($Label1), "nm", "numero") StringReplace(GUICtrlGetData($Label1), "fv", "favore") StringReplace(GUICtrlGetData($Label1), "-male", "meno male") StringReplace(GUICtrlGetData($Label1), "disc", "discoteca") StringReplace(GUICtrlGetData($Label1), "se#", "settimana") StringReplace(GUICtrlGetData($Label1), "+ o -", "più o meno") StringReplace(GUICtrlGetData($Label1), "ts", "torno subito") StringReplace(GUICtrlGetData($Label1), "tvtbcoa", "Ti voglio tanto bene come amica") EndSwitch WEnd  
    • Karnalsyn
      By Karnalsyn
      As with a lot of programming, the less manual repetition done to achieve the same outcome...the better.
      I package programs for network deployment at the organization I work for. Sometimes these applications require verbose messaging to the user, and sometimes by special request we have to turn that off and deploy silently.
      The way I currently handle these 2 scenarios is this.
      I have a function that builds the splashwin display screen to variable size depending on message length, and displays the desired message to the end user.
      Then at each point throughout my script as I need to make the user aware of what is currently happening, I inject a splashwin function call with the unique message pertaining to that specific event. ie. "Installing Microsoft Office, please wait..."
      In effort to build a more universal script to handle any type of request submitted. I've incorporated a switch command of '/silent'
      If cmdlineraw detects the usage of that switch when the script is triggered it sets a variable flag, ie. $silent = "on"
      Then at every splashwin call I make, I'm prefixing it with an IF statement that checks for the flag, and then does NOT display the message if that flag is "on". Or does display it if its not. Has worked for me just fine. But while I grow my programming skills and look for more streamlined ways of handling areas I find myself creating repetition. I'm curious if I can relocate that flag check. Taking it out of every single splashwin call, and injecting it into the function itself.
      Example of how I currently display or hide the splashwin based on command line...
      If StringInStr($cmdlineraw, "/silent", 0) Then
          $SilentSwitch = "ON"
      EndIf
      If $SilentSwitch = "OFF" Then SplashWin($Uninstalling & $ProductInfo[1][0])
      Some scripts have dozens of those splashwin calls littered throughout, so Is this the best approach I can take already? Or as stated earlier, can I pull the IF statement away from the splashwin call. And left the function as a whole either activate or deactivate as a result of the command line check.
    • wakillon
      By wakillon
      SciTE Hopper : Jump to Any line by one click and many other helpfull functions !


      As Ashalshaikh suggested me after leaving me the task to continue >SciTE Hopper, i open a new Topic about it.
      It will be more easy for futures updates.

      Many helpfull functions in contextual menu.
      SciTE Hopper is now multipurpose.
      • Color Catcher added
      • BinaryToAu3Kompressor added
      • TinyAu3Search replaced by StringFinder
      • RegJumper added
      • Edit With SciTE added (available in Options)
      • SpecialCharactersViewer added (available in Tray menu)
      New Contextual Menu :

      For a right Click on a function :

      • Copy function name
      • Insert a function header
      • Cut function
      • Copy function
      • Delete function
      • Create a variables List
      • Remove usseless Blank lines
      • Remove Debug lines ( all lines starting with ConsoleWrite or _ArrayDisplay )
      • Set AutoIt Code Layout
      • Remove Comments

      For entire script :

      • Create a functions List
      • Create a variables List
      • Remove usseless Blank lines
      • Remove Debug lines ( all lines starting with ConsoleWrite or _ArrayDisplay )
      • Set AutoIt Code Layout
      • Remove Comments
      • ( Open in SciTE a ) Duplicate of current Script in Temp Dir
      • ( Open in SciTE a ) Duplicate of current Script in Same Dir
      • Explore Parent Script Folder
      • Copy Script name
      • Copy Script path
      • Find Unused Functions
      • Find Unused Variables
      • Set all functions in alphabetic order.( func headers and regions ( in fact, all lines between functions ) are not supported.)

      SciTE Editor New Contextual Menu if SciTE Hopper is added ( in Options ) to SciTE Editor :
      when you made a selection in SciTE Editor you can :

      • Open a Reg Key in Regedit using RegJumper
      • Open a Url in your default Browser
      • Search on google in your default Browser
      • Search on AutoIt Website in your default Browser
      Now Can be added to windows start (minimized)
      Options are available by Tray Menu.
      A double click on tray icon will open clipboard content to SciTE Editor ( Handy when you have copied some code from your browser )

      How to proceed for add SciTE Hopper to SciTE Editor :
      Run Scite Editor, run Scite Hopper ( compiled! ) go to Options and select Add/Remove to SciTE Tab. then click on Add button and it's done !
      Right click on SciTE Editor and choose SciTE Hopper in Contextual Menu for run it when you need it !
      Update of 07 Dec 2017
      TinyAu3Search is replaced by StringFinder

      Previous downloads : 1287
      Script and compiled version are available in the download section
       
      Thanks to Ashalshaikh, Melba23, Th3 MMA, Alzri2, taitel, Manadar, taz742, Yashield, Authenticity, Xenobiologist for their help
      and asdf8 for his >Includes Helper and azjio for his >FileSearch.

      Hope it help you and happy Scripting !

       
×