Jump to content

Automatically Update Program/Software


brutal
 Share

Recommended Posts

*Note: I am putting this here because I couldn't find any recent walk-through posts on the topic and didn't want to revive an old thread.

#cs

Notice: This script is coded in a way that most enperienced coders will scoff at... But it is a valid starting point for anyone to get an idea of how to achieve the end result.

This is a walk-though on creating a simple and effective invisible update process for your software.

There are many ways to do this. This is as simplified as it comes to achieve the desired end result.

----
Your srcipt will check the version number of your local target exe file and it will check version.txt on your server.
[if] version.txt is higher than your local exe version [then] the update file is downloaded, the original file is deleted, and the update file is renamed to the original exe file name.
----

*Note- In my own software builds I tend to run 2 exe's... One is my gui (that contains my update script) and the other is the actual exe that does the real work. This allows me to
update my underlying program code without the user needing to do anything on his side.

*You can run 2 copies of this script (names/vars changed) so that you can also version check/update your main gui exe as well. (This will require a little different approach and will not be covered here.)

I included message boxes along the way to help you visualize the process - You will want to remove those for a production environment.

#ce


#include <MsgBoxConstants.au3>
#include <IE.au3>
#include <INet.au3>
#include <WinAPIFiles.au3>




;global vars have to be above all code - Global vars are frowned upon in general, but for this example they do what is needed
Global $serverVersionFile = "https://yourdomain.com/version.txt";create a txt file in your webhosting account and only include your software version in it, for example: 2.0.0.0
Global $UpdatePathIs = @ScriptDir & "\update.exe"; This is the local path where you want your update to be downloaded into.
Global $serverUpdateExe = "http://yourdomain.com/update.exe"; This is the path to the update.exe file on your server.
Global $ToBeReplacedPathIs = @ScriptDir & "\original.exe"; This is the path to your original program that you want to update.
Global $doDownload
Global $updateFailed
Global $retryornot

; ---- These are the two main functions to run
GetCurrentSoftwareVersion()
doVersionCheck()
;----


Func GetCurrentSoftwareVersion()
    ; Retrieve the file version of the target/original executable. | Retrieve the version number contained in your version.txt file.
    Global $localEXEversion = FileGetVersion($ToBeReplacedPathIs)
    Global $remoteEXEversion = _INetGetSource($serverVersionFile)

EndFunc   ;==>GetCurrentSoftwareVersion

Func doVersionCheck()
;check if local version is lower than server version - if server version higher than local version then push update
If $localEXEversion < $remoteEXEversion Then
    MsgBox(0,"","server version higher - lets update it")

    Global $doDownload = InetGet($serverUpdateExe, $UpdatePathIs, $INET_FORCERELOAD, $INET_DOWNLOADBACKGROUND); This goes and downloads our update.exe file (forces a fresh download)
    ;The 'do' statment below forces the script to wait until the download has completed to continue.
    Do
        Sleep(250)
    Until InetGetInfo($doDownload, $INET_DOWNLOADCOMPLETE)
    MsgBox(0,"","download completed")
    DownloadDeleteRename()

Else
    MsgBox(0,"","server version lower than current local verison - no action needed"); we do "lower" so that when you are working on updates locally and testing, your script doesn't force you to update.
EndIf

EndFunc;doVersionCheck

Func DownloadDeleteRename()

    FileDelete($ToBeReplacedPathIs); this will delete the original exe file
    FileMove($UpdatePathIs,$ToBeReplacedPathIs,1); this will rename your update.exe to whatver your original exe file name was so that you have replaced the original exe with the updated exe

    ; lets check to make sure our update was successful - We do this by checking the local and remote file versions again... If the update was successful, then the local exe file and the remote version.txt file will be the same number.

    GetCurrentSoftwareVersion()

    MsgBox(0,"",$localEXEversion & $remoteEXEversion)

    If $localEXEversion = $remoteEXEversion Then
        ;all is good - the update was successful
        Global $updateFailed = false; this means the update did not fail
        ConsoleWrite($updateFailed)
    Else
        $retryornot = MsgBox(16 + 5,"Update error detected","Likely cause: Firewall/Antivirus prevented the download. ")
        ;this tells us what button the user clicked on msgbox... cancel = 2, and retry = 4
        Global $updateFailed = true; this means the update failed
        ConsoleWrite($updateFailed)

        EndIf

        ; with the if statement below we are telling the software to simply close if the user rejected our update instead of retrying.
        If $retryornot = 4 Then
            GetCurrentSoftwareVersion()
            doVersionCheck()
        Else
            ;close application
            ;Exit (remove this text and uncomment 'exit' to make the program actually close)



    EndIf

    EndFunc;DownloadDeleteRename

 

Link to comment
Share on other sites

  • 2 years later...

So... you have a good idea here, and I took it a step further and turned it into a fully automated standalone updater.
Below is a script to create a standalone executable that sits next to the file you want updated.
I did my best to make it obvious what needs to change for people to make this work for themselves.

I don't know where this text is coming from, ://////=__=.= but I cannot remove it.

#RequireAdmin

#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Icon=PathTo\YourIcon.ico
#AutoIt3Wrapper_Outfile_x64=%userprofile%\Desktop\MyProgram\Updater.exe
#AutoIt3Wrapper_UseX64=Y
#AutoIt3Wrapper_Res_Comment=Auto_updater
#AutoIt3Wrapper_Res_Description=Updater
#AutoIt3Wrapper_Res_Fileversion=1.0.0.0
#AutoIt3Wrapper_Res_ProductName=MyProgram
#AutoIt3Wrapper_Res_ProductVersion=1.0.0.0
#AutoIt3Wrapper_Res_LegalCopyright=2021 © Myself
#AutoIt3Wrapper_Res_CompanyName=MySelf
://////=__=.=
#AutoIt3Wrapper_Run_After=del /f /q "%scriptdir%\%scriptfile%_stripped.au3"
#AutoIt3Wrapper_Run_Au3Stripper=y

#include <INet.au3> ;place this Updater.exe file In the same Dir as the file you want To update

_updater()

Func _updater()
    Local $RemoteVer = _INetGetSource("https://yourserver.com/updates/UpdateVersion.txt") ; contains the version number of the update,eg 2.2.3.0
    Local $isfilefullpath = @ScriptDir & "\filename.exe" ; the fullpath\filename that you want to update
    Local $isfilename = 'filname.exe'  ; the filename on its own
    If FileGetVersion($isfilefullpath) >= $RemoteVer Then
        MsgBox(0, '', 'There are no updates available.')
    Else
        If MsgBox(33, 'Update Available', 'A direct download of version ' & $RemoteVer & ' is available.' & @CRLF & _
                'Do you want to install this automated update now?' & @CRLF & @CRLF & _
                'Updating usually takes less than 10 seconds.') = 1 Then
            Local $doDownload = InetGet("https://yourserver.com/updates/UpdateVersion.new", @TempDir & '\UpdateVersion.new', 1, 1)
            ; UpdateVersion.new is just a renamed exe that you want to download
            Do
                Sleep(100)
            Until InetGetInfo($doDownload, 2)
            Sleep(150)
            InetClose($doDownload)
            If FileGetVersion(@TempDir & '\UpdateVersion.new') <> $RemoteVer Then
                FileDelete(@TempDir & '\UpdateVersion.new')
                MsgBox(16, 'DOWNLOAD FAILED', 'Windows Defender and/or your Virus Scanner may have blocked the download.' & _
                        @CRLF & @CRLF & 'You may need to temporarily disable your Virus scanner.')
                Exit
            EndIf
            Local $sData = 'TASKKILL /F /IM "' & $isfilename & '"' & @CRLF & 'TIMEOUT 1' & @CRLF & _   ; create a dos cmd file to handle the update
                    'MOVE /Y ' & '"' & @TempDir & '\UpdateVersion.new' & '"' & ' "' & $isfilefullpath & '"' & @CRLF & 'TIMEOUT 1' & @CRLF & _
                    'START /D "' & @ScriptDir & '"' & ' ' & $isfilename & @CRLF & 'DEL "' & '%~f0' & '"' & ' & exit'
            Local $hFileOpen = FileOpen(@TempDir & '\temp.cmd', 2) ;the move command will rename the downloaded file to the filename you want updated
            FileWrite($hFileOpen, $sData)
            FileClose($hFileOpen)
            Return ShellExecute(@TempDir & '\temp.cmd', '', @TempDir, '', @SW_HIDE) ; execute the cmd file
        Else
            Exit
        EndIf
    EndIf
    Exit
EndFunc   ;==>_updater
Edited by Shark007
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...