home *** CD-ROM | disk | FTP | other *** search
- /*
- [AutoHotkey Updater]
- version = 0.001
- */
-
- KeepBackup = 0 ; Set to 1 to keep old EXE as <filename>.<version>.bak.
- SelfUpdate = 1 ; Set to 0 to prevent the script from checking for updates to itself.
-
- ; Alternate update sources should use the following structure:
- ; %UpdateURL%/Update.ahk -- [optional] newer version of this script
- ; %UpdateURL%/version.txt -- text file: ONLY a version number
- ; %UpdateURL_bin% -- zip file: AutoHotkey.exe and AutoHotkeySC.bin;
- ; {suffix} is replaced with "w", "a" or "w64" as appropriate.
- ; %UpdateURL_chm% -- zip file: AutoHotkey.chm
- ; %UpdateURL_a2e% -- zip file: Ahk2Exe.exe
- UpdateURL = http://www.autohotkey.net/~Lexikos/AutoHotkey_L
- UpdateURL_bin = %UpdateURL%/AutoHotkey_L{suffix}.zip
- UpdateURL_chm = %UpdateURL%/AutoHotkey_L_Help.zip
- UpdateURL_a2e = %UpdateURL%/Ahk2Exe_L.zip
-
- TempDir = %A_Temp%\AhkUpdate%A_Now%
-
-
- #NoEnv
- #Include *i %A_ScriptDir%\UpdateDebug.ahk
-
- if 0 > 0
- {
- if IsFunc("_" %True%) ; Recursive call, used to swap exes or elevate the process.
- {
- prms := Object()
- Loop %0%
- prms.Insert(%A_Index%)
- func := prms.Remove(1), _%func%(prms*)
- ExitApp
- }
- else if 1 = SuppressUpToDate ; Suppress "AutoHotkey is up to date" message.
- SuppressUpToDate := true
- }
-
- if !A_IsCompiled && SelfUpdate
- {
- ; First, check for a newer version of this script.
- URLDownloadToFile %UpdateURL%/Update.ahk, %A_Temp%\Update.ahk
- IniRead rver, %A_Temp%\Update.ahk, AutoHotkey Updater, version, %A_Space%
- IniRead lver, %A_ScriptFullPath%, AutoHotkey Updater, version, %A_Space%
- if (lver < rver)
- {
- MsgBox 3, AutoHotkey Updater,
- (LTrim Join`s
- A newer version of this script is available. It is recommended
- that you use the updated version of the script to install further
- updates. *** WARNING: If you click yes, any modifications you
- have made to this script will be lost. ***
- `n`nUse the updated script?
- )
- ifMsgBox Yes
- {
- _SelfUpdate(A_Temp "\Update.ahk")
- ExitApp
- }
- ifMsgBox Cancel
- {
- FileDelete %A_Temp%\Update.ahk
- ExitApp
- }
- }
- FileDelete %A_Temp%\Update.ahk
- }
-
- if A_OSVersion in WIN_2000,WIN_NT4,WIN_95,WIN_98,WIN_ME ; Only WIN_2000 should actually be possible.
- {
- MsgBox 16, AutoHotkey Updater, Windows XP or later is required.
- ExitApp
- }
-
- FileCreateDir %TempDir%
-
- ; Retrieve latest version number.
- URLDownloadToFile %UpdateURL%/version.txt, %TempDir%\version.txt
- FileRead version, %TempDir%\version.txt
-
- if (version <= A_AhkVersion)
- {
- if !SuppressUpToDate
- MsgBox 64, AutoHotkey Updater, AutoHotkey is up to date.
- FileRemoveDir %TempDir%
- ExitApp
- }
-
- MsgBox 68, AutoHotkey Update Available,
- (
- An update for AutoHotkey is available.
-
- Installed version:`t%A_AhkVersion%
- Latest version:`t%version%
-
- Would you like to install it now?
- )
- ifMsgBox No
- {
- FileRemoveDir %TempDir%
- ExitApp
- }
-
- ; Determine the appropriate package.
- if A_PtrSize = 8
- suffix = w64 ; Above already verified A_IsUnicode is true in this case.
- else if A_IsUnicode
- suffix = w
- else
- suffix = a
- StringReplace UpdateURL_bin, UpdateURL_bin, {suffix}, %suffix%
-
- ; Download binaries.
- errors := !Download(UpdateURL_bin, TempDir "\bin.zip")
- ; Download help file.
- ifExist %A_AhkPath%\..\AutoHotkey.chm
- errors += !Download(UpdateURL_chm, TempDir "\help.zip")
- ; Download compiler.
- ifExist %A_AhkPath%\..\Compiler\Ahk2Exe.exe
- errors += !Download(UpdateURL_a2e, TempDir "\compiler.zip")
-
- if errors
- {
- MsgBox 16, AutoHotkey Updater, Update failed: download error.
- ifExist %TempDir%\*.zip
- Run %TempDir% ; Allow user to extract files manually.
- else
- FileRemoveDir %TempDir%, 1
- ExitApp
- }
-
- ; Extract binaries, help file and compiler into temp dir.
- oShell := ComObjCreate("Shell.Application")
- oDir := oShell.NameSpace(TempDir)
- Loop %TempDir%\*.zip
- {
- oZip := oShell.NameSpace(A_LoopFileFullPath)
- if !(oZip && oDir)
- {
- MsgBox 16, AutoHotkey Updater, Update failed: unzip error.
- Run %TempDir%
- ExitApp
- }
- oDir.CopyHere(oZip.Items, 4)
- }
- oShell := oDir := oZip := ""
-
- _Install(TempDir)
-
- ExitApp
-
-
- _Install(source_dir)
- {
- ; Get list of scripts running on the old executable. This will apparently
- ; work even after the file itself is renamed, but better be on the safe side.
- Process Exist
- my_pid := ErrorLevel
- ComObjError(0) ; ComObjGet("winmgmts:") fails on Guest account.
- for proc in ComObjGet("winmgmts:").InstancesOf("Win32_Process")
- if (proc.ExecutablePath = A_AhkPath && proc.ProcessId != my_pid)
- pids .= proc.ProcessId ","
- pids := SubStr(pids,1,-1)
-
- ; Rename current executable to allow another to take its place.
- backup_path = %A_AhkPath%.%A_AhkVersion%.bak
- FileMove %A_AhkPath%, %backup_path%, 1
- if ErrorLevel
- {
- if !A_IsAdmin
- { ; Try again as admin.
- if Elevate("Install", source_dir)
- ExitApp
- }
- MsgBox 16, AutoHotkey Updater, Update failed: unable to rename old file. Error %err%.`n`nSource: %A_AhkPath%`nDestination: %backup_path%
- Run %source_dir%
- ExitApp
- }
-
- ; Move new files into place -- FileCopy is used because otherwise the files would still have permissions inherited from %A_Temp%.
- FileCopy %source_dir%\AutoHotkey.exe, %A_AhkPath%
- if ErrorLevel
- {
- MsgBox 16, AutoHotkey Updater, Update failed: unable to move AutoHotkey.exe to "%A_AhkPath%".
- Run %source_dir%
- ExitApp
- }
- FileCopy %source_dir%\AutoHotkeySC.bin, %A_AhkPath%\..\Compiler\AutoHotkeySC.bin, 1 ; Should simply fail if no Compiler dir.
- FileCopy %source_dir%\Ahk2Exe.exe, %A_AhkPath%\..\Compiler\Ahk2Exe.exe, 1 ; If it exists.
- FileCopy %source_dir%\AutoHotkey.chm, %A_AhkPath%\..\AutoHotkey.chm, 1 ; If it exists.
-
- ; Clean up. :)
- FileRemoveDir %source_dir%, 1
-
- ; Relaunch using new executable -- see _TidyUp() below.
- Run "%A_AhkPath%" "%A_ScriptFullPath%" TidyUp "%my_pid%" "%backup_path%" "%pids%"
- }
-
-
- _TidyUp(parent_pid, delete_me, other_pids="")
- {
- ; Update registry -- this is done here so can be positive the version number is accurate.
- RegRead InstallDir, HKLM, SOFTWARE\AutoHotkey, InstallDir
- if (A_AhkPath = InstallDir "\AutoHotkey.exe")
- {
- RegWrite REG_SZ, HKLM, SOFTWARE\AutoHotkey, Version, %A_AhkVersion%
- RegWrite REG_SZ, HKLM, SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\AutoHotkey, DisplayName, AutoHotkey %A_AhkVersion%
- RegWrite REG_SZ, HKLM, SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\AutoHotkey, DisplayVersion, %A_AhkVersion%
- }
-
- Process WaitClose, %parent_pid% ; Wait for previous instance of this script to close.
- DetectHiddenWindows On
- scripts := Object()
- Loop Parse, other_pids, `,
- {
- ifWinExist ahk_pid %A_LoopField% ahk_class AutoHotkey
- {
- WinGetTitle script
- script := RegExReplace(script, " - [^-]*$")
- scripts[WinExist()] := script
- script_filenames .= script "`n"
- }
- }
- SplitPath A_AhkPath, exe
- SplitPath delete_me, bak
- if scripts.MaxIndex() != ""
- {
- MsgBox 4, AutoHotkey Updater, The following scripts are still running:`n`n%script_filenames%`nWould you like to automatically reload them?
- ifMsgBox Yes
- {
- failed := ""
- while (id := scripts.MaxIndex()) ; Must be MAX rather than MIN, otherwise existing IDs will be invalidated by Remove().
- {
- script := scripts.Remove(id)
- ifExist %script%
- {
- ; Triggering reload won't work in most cases since the version number
- ; in the window title has changed. Instead, forcibly start the script
- ; and automatically close the old one if the new one loaded okay.
- Run "%A_AhkPath%" /force "%script%",,, pid
- WinWait ahk_pid %pid%,, 1
- ; Above may have timed out or found a load-time error dialog.
- ; Check for the "ahk_class AutoHotkey" window specifically,
- ; since its presence indicates the script loaded okay.
- ifWinExist ahk_pid %pid% ahk_class AutoHotkey
- WinClose ahk_id %id%,, 0
- }
- ifWinExist ahk_id %id%
- failed .= script "`n"
- }
- if failed !=
- MsgBox 16, AutoHotkey Updater, One or more scripts were not successfully reloaded:`n`n%failed%
- }
- }
-
- global KeepBackup
- if KeepBackup ; This is set at the top of the script, for configuration by a user.
- ExitApp
- ; Attempt to delete file. This will fail if any old scripts are still running.
- FileDelete %delete_me%
- ; If unsuccessful, attempt to schedule it for deletion. This will only work
- ; for administrators. If a limiter user got this far in the installation,
- ; they're probably working with a portable installation and won't want to
- ; provide admin credentials just to schedule a file for deletion.
- if ErrorLevel && !DllCall("MoveFileEx", "str", delete_me, "ptr", 0, "uint", 4) ; MOVEFILE_DELAY_UNTIL_REBOOT:=4
- MsgBox 16, AutoHotkey Updater, Failed to delete old file "%bak%".
- ExitApp
- }
-
-
- _SelfUpdate(source_path)
- {
- ; Copy and Delete instead of Move so that file permissions are inherited correctly.
- FileCopy %source_path%, %A_ScriptFullPath%, 1
- if ErrorLevel
- {
- if !A_IsAdmin
- { ; Try again as admin.
- if Elevate("SelfUpdate", source_path)
- ExitApp
- }
- MsgBox 16, AutoHotkey Updater, Script update failed. Error %err%.
- ExitApp
- }
- FileDelete %source_path%
- Reload
- }
-
-
- Elevate(func, prms*)
- {
- cmd := func
- for i,prm in prms
- {
- StringReplace prm, prm, `", "", All
- cmd .= " """ prm """"
- }
- if A_IsCompiled
- exe := A_ScriptFullPath
- else
- exe := A_AhkPath, cmd := """" A_ScriptFullPath """ " cmd
- return DllCall("shell32\ShellExecute", "ptr", 0, "str", "RunAs"
- , "str", exe, "str", cmd, "ptr", 0, "int", 1) > 32
- }
-
-
- D(debug_string)
- {
- OutputDebug AhkUpdate: %debug_string%`n
- FileAppend %debug_string%`n, *, CP0
- }
-
-
- ; Based on code by Sean and SKAN @ http://www.autohotkey.com/forum/viewtopic.php?p=184468#184468
- Download(url, file)
- {
- static vt
- if !VarSetCapacity(vt)
- {
- VarSetCapacity(vt, A_PtrSize*11), nPar := "31132253353"
- Loop Parse, nPar
- NumPut(RegisterCallback("DL_Progress", "F", A_LoopField, A_Index-1), vt, A_PtrSize*(A_Index-1))
- }
- global _cu
- SplitPath file, dFile
- SysGet m, MonitorWorkArea, 1
- y := mBottom-52-2, x := mRight-330-2, VarSetCapacity(_cu, 100)
- , DllCall("shlwapi\PathCompactPathEx", "str", _cu, "str", url, "uint", 50, "uint", 0)
- Progress Hide CWFAFAF7 CT000020 CB445566 x%x% y%y% w330 h52 B1 FS8 WM700 WS700 FM8 ZH12 ZY3 C11,, %_cu%, AutoHotkeyProgress, Tahoma
- WinSet Transparent, 192, AutoHotkeyProgress
- re := DllCall("urlmon\URLDownloadToFile", "ptr", 0, "str", url, "str", file, "uint", 0, "ptr*", &vt)
- Progress Off
- return re=0 ? 1 : 0
- }
- DL_Progress( pthis, nP=0, nPMax=0, nSC=0, pST=0 )
- {
- global _cu
- if A_EventInfo = 6
- {
- Progress Show
- Progress % P := 100*nP//nPMax, % "Downloading: " Round(np/1024,1) " KB / " Round(npmax/1024) " KB [ " P "`% ]", %_cu%
- }
- return 0
- }