Skip to content

Instantly share code, notes, and snippets.

@anonymous1184
Last active August 8, 2023 00:35
Show Gist options
  • Save anonymous1184/2bac256e32247ca9f5ed1c108d3c0b1f to your computer and use it in GitHub Desktop.
Save anonymous1184/2bac256e32247ca9f5ed1c108d3c0b1f to your computer and use it in GitHub Desktop.
AutoHotkey v1.1.x / v2.0.x (un)installer.

AutoHotkey v1.1.x / v2.0.x (un)installer

Usage and information: https://redd.it/15l2b6l

The source code is for informative purposes, the file needed is the executable.

  • Download (1.83 MB).
    • SHA256: e30f09fe36238b1a8fbed3250c637888811a10443029ccc20da20a5830a318a7
    • Alternatively: zip file (890 KB).
  • VirusTotal (no detections, 71 engines).
#Requires AutoHotkey_H =v2.0.4.0 64-bit
main()
Exit() ; End of auto-execute
main() {
if (!A_IsAdmin) {
try Run("*RunAs " A_ScriptFullPath)
ExitApp(0)
}
; Ask before continue
answer := MsgBox("You are about to uninstall AutoHotkey (all versions), continue?", "Continue?", 0x40024)
if (answer = "No") {
ExitApp(0)
}
; Releases info
whr := ComObject("WinHttp.WinHttpRequest.5.1")
try {
whr.Open("GET", "https://api.github.com/repos/AutoHotkey/AutoHotkey/releases", true)
whr.Send()
whr.WaitForResponse()
responseJson := JSON.parse(whr.ResponseText, false, false)
} catch {
ExitApp(1) ; Initial connection or data parsing went wrong
}
; Assets info
assets := [1, 2] ; v1.1.x && v2.0.x
loop 2 {
majorVersion := A_Index
for (release in responseJson) {
if (release.assets.Length = 0) {
continue
}
RegExMatch(release.name, "^v(" majorVersion "[\d\.]+)$", &match)
if (!IsObject(match)) {
continue
}
fullVersion := match[1]
name := release.assets[1].name
downloadUrl := release.assets[1].browser_download_url
RegExMatch(release.body, "i)[0-9A-F]{64}", &match)
hash := IsObject(match) ? match[0] : ""
assets[majorVersion] := { filename: name, sha256: hash, url: downloadUrl, version: fullVersion }
break
}
if (!IsObject(assets[majorVersion])) {
MsgBox("Couldn't find an asset for the v" majorVersion " major version.", "Error", 0x40010)
ExitApp(0)
}
}
; Download dir
dir := A_Temp
for (CLSID in ["088e3905-0323-4b02-9826-5d99428e115f", "374DE290-123F-4565-9164-39C4925E467B"]) {
try {
dir := RegRead("HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders", "{" CLSID "}")
break
}
}
; Download & verify
for (asset in assets) {
path := dir "\" asset.filename
cmd := 'CertUtil -HashFile "' path '" sha256 | FindStr /I ' asset.sha256
; Already downloaded
if (FileExist(path)) {
if (RunWait(A_ComSpec ' /C "' cmd '"', , "Hide")) {
try FileDelete(path)
} else {
continue
}
}
; Download
try {
Download(asset.url, path)
try FileDelete(path ":Zone.Identifier")
} catch {
MsgBox("Couldn't download AutoHotkey v" asset.version " installer.", "Error", 0x40010)
ExitApp(1)
}
if (asset.sha256 = "") {
continue
}
; Verify
if (RunWait(A_ComSpec ' /C "' cmd '"', , "Hide")) {
try FileDelete(path)
MsgBox("Invalid hash for AutoHotkey v" asset.version " installer.", "Error", 0x40010)
ExitApp(1)
}
}
; Kill processes
cmd := "taskkill.exe /F"
for item in ComObjGet("winmgmts:").ExecQuery("SELECT * FROM Win32_Process WHERE ExecutablePath LIKE '%AutoHotkey%'") {
cmd .= " /PID " item.ParentProcessId
}
RunWait(cmd, , "Hide")
; Uninstall
errors := 0
for (asset in assets) {
try {
; v1 ignores `/silent`, but `/uninstall` is always silent
errors += !!RunWait(asset.filename " /silent /uninstall", dir)
} catch {
errors++
}
}
if (errors != 0) {
answer := MsgBox("AutoHotkey couldn't uninstall old versions, would you like to continue installing over them?", "Attention!", 0x40034)
if (answer = "No") {
ExitApp(1)
}
}
; Delete install folder(s)
LocalAppData := EnvGet("LocalAppData")
programFilesWoW := EnvGet("ProgramFiles(x86)")
for (root in [A_ProgramFiles, programFilesWoW, LocalAppData "\Programs"]) {
try {
FileRecycle(root "\AutoHotkey")
} catch {
loop files root "\AutoHotkey\*", "DR" {
try FileRecycle(A_LoopFileFullPath)
}
loop files root "\AutoHotkey\*", "FR" {
try FileRecycle(A_LoopFileFullPath)
}
RunWait(A_ComSpec ' /C rd /s /q "' root '\AutoHotkey"')
}
}
; Self-signed certificate
RunWait('CertUtil -DelStore Root "AutoHotkey"', , "Hide")
; Registry remnants
keys := [
"HKCR\.ahk",
"HKCR\AutoHotkeyScript",
"HKCU\SOFTWARE\AutoHotkey",
"HKCU\SOFTWARE\Classes\.ahk",
"HKCU\SOFTWARE\Classes\AutoHotkeyScript",
"HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\AutoHotkey"
"HKLM\SOFTWARE\AutoHotkey",
"HKLM\SOFTWARE\Classes\.ahk",
"HKLM\SOFTWARE\Classes\AutoHotkeyScript",
"HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\AutoHotkey"
]
for (key in keys) {
try RegDelete(key)
}
; Install
answer := MsgBox("Uninstall is completed. Do you want to continue installing versions " assets[1].version " and " assets[2].version, "Continue?", 0x40024)
if (answer = "No") {
ExitApp(0)
}
target := A_ProgramFiles "\AutoHotkey"
if (RunWait(assets[1].filename ' /S /U64 /D="' target '" /uiAccess=1', dir)) {
MsgBox(assets[1].filename " couldn't be installed.", "Error", 0x40010)
ExitApp(1)
}
if (RunWait(assets[2].filename ' /silent /to "' target '"', dir)) {
MsgBox(assets[2].filename " couldn't be installed.", "Error", 0x40010)
ExitApp(1)
}
; FInished
MsgBox("Install of versions " assets[1].version " and " assets[2].version " is complete.", "Finalized", 0x40040)
}
#NoTrayIcon
This file has been truncated, but you can view the full file.
View raw

(Sorry about that, but we can’t show files that are this big right now.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment