Jump to content
Sign in to follow this  
NoelG

Self updating Executable

Recommended Posts

NoelG

Hello all,

I have a script that gets used by 30+ systems and is hosted locally on each. I'm looking for a way to have it self update when I place an updated version in a specific folder on the network. I have the file version check all worked out. My issue lies in the over-writing of an open file. Is there a way to release the lock on the file so it can be overwritten.

<about 20 minutes>

I think I can create a separate update script, then call it from the main script (if an update is found) with a RUN then Exit. This way the file is closed, then the update script runs, with a 1-2 second sleep at the beginning, allowing for the main program to close. Once the update is complete, relaunch the main script with the new version. This shouldn't cause a loop as long as the version checking works correct from the main script before the update function.

Anyone doing something similar or achieving the same results using a better method?

Share this post


Link to post
Share on other sites
Juvigy

I would suggest :

1.FileCopy the new version in the script dir (testv2.exe for example)

2.Selfdelete the running exe (selfdelete testv.exe which is the old script)

Share this post


Link to post
Share on other sites
NoelG

I would suggest :

1.FileCopy the new version in the script dir (testv2.exe for example)

2.Selfdelete the running exe (selfdelete testv.exe which is the old script)

How would I then rename testv2.exe to test.exe at that point.

Share this post


Link to post
Share on other sites
Juvigy

Why would you need that ?

You can put in the update func something like:

1. FileMove test1.exe to test2.exe in same folder

2. Start test2.exe

3. Selfdelere test1.exe

4. The test2.exe should wait for the selfdelete of test1 to finish

5. test2 downloads the new version and then selfdeletes itself

OR

You can create a new Update.exe on the server which does:

1. Test1.exe starts update.exe and closes

2. update.exe deletes/overwrites it to the new version

Share this post


Link to post
Share on other sites
Tvern

I would do it like this:

*Make the old script download the new script to @scriptdir with a fixed name.

*Make the old script write a batch file.

*Make the old script run the batch file.

*Make the old script exit.

*Make the batch file delete the old script.

*Make the batch file rename the new script to the old scripts name.

*Make the batch file run the new script.

*Make the batch file delete itsself (batch files can do this as they are not stand alone executables)

Edited by Tvern

Share this post


Link to post
Share on other sites
NoelG

I ended up liking the batch Idea the best. Not sure if I did it right and my code isn't exactly pristine, or professional but here you have a working copy of it:

Func self_update()
    SplashTextOn("HLC: Checking for HLC Update", "Please wait... This may take a few moments.", "400", "100", "-1", "-1", 50, "", "", "")
    If Not IsDeclared("$complete_hlcfile_master_data_path") Then Global $complete_hlcfile_master_data_path
    $complete_hlcfile_master_data_path = $site_master_data_path & "_HLC"
    IF FileGetVersion($complete_hlcfile_master_data_path & "\hlc.exe") <> FileGetVersion("C:\hes\locationchange\hlc.exe") Then
        FileCopy($complete_hlcfile_master_data_path & "\hlc.exe", "C:\hes\locationchange\hlc_new.exe")
        $hlc_update_bat = fileopen("C:\hes\locationchange\hlc_update.bat", 2)
        FileWriteLine($hlc_update_bat, "@echo off")
        FileWriteLine($hlc_update_bat, "ping localhost -n 2 > nul")
        FileWriteLine($hlc_update_bat, "del /Q C:\hes\locationchange\hlc.exe")
        FileWriteLine($hlc_update_bat, "move C:\hes\locationchange\hlc_new.exe C:\hes\locationchange\hlc.exe")
        FileWriteLine($hlc_update_bat, "start C:\hes\locationchange\hlc.exe")
        FileWriteLine($hlc_update_bat, "del /Q C:\hes\locationchange\hlc_update.bat")
        FileWriteLine($hlc_update_bat, "exit")
        FileClose($hlc_update_bat)
        Run("C:\hes\locationchange\hlc_update.bat", "", @SW_HIDE)
        SplashOff()
        Exit
    Else
        SplashOff()
    EndIf
EndFunc ;==>self_update
Edited by NoelG

Share this post


Link to post
Share on other sites
Tvern

I expect your batch file to run into some problems:

*It won't be able to delete the main executable untill it properly exits, so I made it loop the delete. You could also build in a timeout and make it as complicated as you like.

*If you want to use the script from different locations you can use @ScriptFullPath and alike, but you'd need to put the path in double quotes in case it is too long, or has spaces in it.

I personally like the single filewrite approach, but it has no real advantages that I know off.

I made an example, but didn't test it.

Func self_update()
    SplashTextOn("HLC: Checking for HLC Update", "Please wait... This may take a few moments.", "400", "100", "-1", "-1", 50, "", "", "")
    If Not IsDeclared("$complete_hlcfile_master_data_path") Then
        Global $complete_hlcfile_master_data_path = $site_master_data_path & "_HLC"
        If FileGetVersion($complete_hlcfile_master_data_path & "\hlc.exe") <> FileGetVersion("C:\hes\locationchange\hlc.exe") Then FileCopy($complete_hlcfile_master_data_path & "\hlc.exe", @ScriptFullPath & ".new") ;changed the name of the new file.
        Local $batchPath = @ScriptDir & '\hlc_update.bat'
        Local $batchFile =  "@echo off"& @CRLF _
                            "ping localhost -n 2 > nul" & @CRLF _ ;not sure what you're doing here. Giving the script time to exit?
                            ":loop" & @CRLF _ ;specify the start of a zone
                            'del /Q "' & @ScriptFullPath & '"' & @CRLF _ ;the quotes are needed for long filepaths, and filepaths with spaces. The @SciptfullPath is for flexibility
                            'if exist "' & @ScriptFullPath & '" goto loop' & @CRLF _ ;if the delete failed, try again
                            'move "' & @ScriptFullPath & '.new" "' & @ScriptFullPath & '"' & @CRLF _ ;this is why I changed the new file's name.
                            'start "' & @ScriptFullPath & '"' & @CRLF _
                            'del /Q "' & $batchPath & '"' & @CRLF _
                            "exit"      
        FileWrite($batchPath,$batchFile)
        Run($batchPath, "", @SW_HIDE)
        SplashOff()
        Exit
    Else
        SplashOff()
    EndIf
EndFunc

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
Sign in to follow this  

×

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.