NoelG Posted June 1, 2010 Share Posted June 1, 2010 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? Link to comment Share on other sites More sharing options...
Juvigy Posted June 1, 2010 Share Posted June 1, 2010 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) Link to comment Share on other sites More sharing options...
NoelG Posted June 1, 2010 Author Share Posted June 1, 2010 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. Link to comment Share on other sites More sharing options...
Juvigy Posted June 1, 2010 Share Posted June 1, 2010 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 Link to comment Share on other sites More sharing options...
Tvern Posted June 1, 2010 Share Posted June 1, 2010 (edited) 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 June 1, 2010 by Tvern Link to comment Share on other sites More sharing options...
NoelG Posted June 1, 2010 Author Share Posted June 1, 2010 (edited) 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 June 1, 2010 by NoelG Link to comment Share on other sites More sharing options...
Tvern Posted June 1, 2010 Share Posted June 1, 2010 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 Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now