Starpacks: Why and how to copy your own executable and launching the copied instance instead
Here's the latest standardized version of the above snipped:
################################################################################ # # Modul : autoclone.tcl # Stand : 27.06.2007 # Zweck : Kopieren des eigenen Programmes an eine temporäre Position und # starte neu von dort # Autor : M.Hoffmann # Hinweise : # # `Autoclone`-Verfahren zur Vermeidung blockierter .EXEs (Updates!): Das # Programm kopiert sich selbst in Temp-Position und lädt von dort. ACHTUNG: # Ein Starkit kann sich mittels 'file copy' oder 'open/fcopy/get/put' nur dann # selbst kopieren, wenn das VFS vorübergehend abgehängt, oder ein externes Tool # (z.B. XCOPY) verwendet wird (Warum XCOPY? Leider geht die Methode, cmd.exe # im Hintergrund zu starten und einen copy-befehl dorthin zu pipen, nicht, da # Benutzer teilweise kein Recht haben, cmd.exe zu starten). # # ACHTUNG: Ist dieses Paket eingebunden, wird das Verfahren automatisch über # das Paket initscript verwendet, es sei denn, der LETZTE Kommandozeilen- # Parameter lautet: --noautoclone. MOMENTAN NUR FÜR STARPACKS VERWENDBAR! # # Historie : # 13.11.05 v1.0: als Paket aus RECEIVE übernommen (Schalter inkompatibel!) # 11.05.07 v1.0: nur kosmetische Änderungen und Wiki-Update # 27.06.07 v2.0: Nutze suspendVFS statt XCOPY; Starpacks abfangen # ################################################################################ package provide autoclone 2.0 ################################################################################ # Siehe http://permalink.gmane.org/gmane.comp.lang.tcl.starkit/2537 # proc suspendVFS {code} { set me [info nameofexe] lassign [vfs::filesystem info $me] drv dbh vfs::filesystem unmount $me # unmounted, now run the code uplevel $code # Remount vfs::filesystem mount $me [list vfs::mk4::handler $dbh] } ################################################################################ # Prozedur zur Vermeidung globaler Variablen! # proc autoClone {} { if {[string equal -nocase [lindex $::argv end] "--noautoclone"]} { # Paket ist zwar eingebunden, aber wegen --noautoclone das # Verfahren nicht verwenden; also Schalter entfernen, um das # spätere Kommandozeilenparsing nicht zu stören. set ::argv [lreplace $::argv end end] set ::argc [llength $::argv] } else { set myself [file normalize [info nameofexecutable]] set mytempP $::env(temp); # Schwachpunkt: Umgebungsvar TEMP muss existieren! set mytemp [file normalize [file join $mytempP [file tail $myself]]] # v2.0: Nur Starpacks berücksichtigen if {[string first $myself [file normalize [info script]]] != 0} { return } # Abfangen: Aufruf bereits aus TempVerzeichnis if {[string compare $myself $mytemp]} { # Voraussetzung: Aufruf von XCOPY muss möglich sein! # catch {exec -- [auto_execok xcopy] [file nativename $myself] [file nativename $mytempP] /Y} # v2.0: internes Kopieren! catch {suspendVFS [list file copy -force -- $myself $mytempP]} # Falls Kopieren scheiterte, aber Ziel schon da war, ebenfalls fortfahren if {[file exists $mytemp]} { set ::argv [linsert $::argv 0 $mytemp] # Versuch mit START, bislang erfolglos (EXEC ist eigenwillig!): # set ::argv [linsert $::argv 0 [auto_execok cmd] /c start \"[file nativename $mytemp]\"] lappend ::argv --noautoclone # durch Angabe von --noautoclone hier Rekursion verhindern! if {[catch {eval exec -- $::argv &} rc]} { # Kopie ist aus irgendwelchen Gründen nicht aufrufbar; # Fehler ignorieren und aktuelle Instanz weiter verwenden! } else { exit 0; # sofort BEENDEN, da mit Kopie weitergearbeitet wird! } } } } } # ACHTUNG: Sofortige Ausführung durch PACKAGE REQUIRE! autoClone;
It should be mentioned that the code is intended for use by starpacks only, especially for GUI-Starpacks (problems with tclkitSH-version are likely, since the EXECd process eventually inherits some resources belonging to the console, so the EXECing process doesn't end...).
EF I was trying to point out that the locking mechanism that you describe here is the reason why my updater library [L1 ] does not work on Windows. However, the techniques that you are describing could be combined to the library in order to provide for binaries that update themselves when a new version appears at a known Internet location.