Skip to content

Instantly share code, notes, and snippets.

@pa-0
Forked from anonymous1184/Elevate.ahk
Last active May 14, 2025 05:22
Show Gist options
  • Select an option

  • Save pa-0/b249cc9626d95c41f99fe4a1cc30a4b9 to your computer and use it in GitHub Desktop.

Select an option

Save pa-0/b249cc9626d95c41f99fe4a1cc30a4b9 to your computer and use it in GitHub Desktop.
Elevate() / ElevateWait()

Elevate()/ElevateWait()1

The function are the counterparts of Run/RunWait commands(v1.1)/functions(v2.0).

Show / Hide

Elevate without UAC prompt

From time to time one needs to run applications, scripts and even shell commands with administrative privileges, but since Vista the pesky (but necessary) UAC prompt is shown, breaking the automation process or at least making you pay attention to what you are doing.

Elevate() and ElevateWait() functions found on this gist keep things as easy as possible by removing the UAC prompt

How Does It Work?

It is pretty simple: a single scheduled task is automatically created and that is used to run whatever is thrown in the functions. The functions accept the same arguments as the Run / RunWait commands (v1.1) / functions (v2.0). Here's the signature:

Built-in Run/RunWait functions:

Run(Target [, WorkingDir, Options, &OutputVarPID])
ExitCode := RunWait(Target [, WorkingDir, Options, &OutputVarPID])

Elevate/ElevateWait functions:

Elevate(Target [, WorkingDir, Options, &OutputVarPID])
ExitCode := ElevateWait(Target [, WorkingDir, Options, &OutputVarPID])

The same caveat of the PID in RunWait applies to ElevateWait, you need to check it in a new thread.

Task creation

It is handled automatically, and only a single task is ever created (user needs to accept the UAC prompt just this time).

What that means? Users doesn't need to keep creating tasks each time the functions are used in a script or for every set of arguments when the functions are called.

That's right, dynamic arguments can be used (unlike regular scheduled tasks).

Examples:

There's not much to showcase as examples, as they are straight-forward:

#Requires AutoHotkey v2.0

Run(A_ComSpec)           ; Runs a terminal
Run("*RunAs " A_ComSpec) ; Runs a terminal as admin, shows the UAC prompt
Elevate(A_ComSpec)       ; Runs a terminal as admin, no UAC prompt

cmd := "whoami /groups | findstr 12288"

result := RunWait(A_ComSpec ' /C "' cmd '"', , "Hide")
result := result ? "Error, not elevated" : "OK, elevated"
MsgBox("Result was: " result)

result := ElevateWait(A_ComSpec ' /C "' cmd '"', , "Hide")
result := result ? "Error, not elevated" : "OK, elevated"
MsgBox("Result was: " result)

Extra

v2 gives so much freedom and allows you to do so many things... one of them is to extend the built-ins, so... why don't we?

I always follow the namespace detailed in the official docs, so:

  • Download Elevate.ahk.
  • Download Run.ahk.
  • Add them to a library.

The is just a matter of include/run the patch:

#Requires AutoHotkey v2.0
#Include <Run>
Run_Patch()
Run("*RunAs " A_ComSpec)

That's it, an elevated terminal will be opened without showing a UAC dialog.

If you are used to adding all of your includes after the auto-execute, just remember that the patch call needs to be before the first call:

#Requires AutoHotkey v2.0
Run_Patch()
Run("*RunAs " A_ComSpec)
return ; End of auto-execute
#Include <Run>

Hopefully you find this useful.

Footnotes

  1. Original Post and Discussion at http://redd.it/1450upb

#Requires AutoHotkey v2.0
; Version: 2023.06.09.2
; https://gist.github.com/d92498381a74a4535662306152b34ab
; Usage and examples: https://redd.it/1450upb
Elevate(Target, WorkingDir := "", Options := "", &OutputVarPID := 0) {
return Elevate_(false, Target, WorkingDir, Options, &OutputVarPID)
}
ElevateWait(Target, WorkingDir := "", Options := "", &OutputVarPID := 0) {
return Elevate_(true, Target, WorkingDir, Options, &OutputVarPID)
}
/**
* @private
*/
Elevate_(bWait, Target, WorkingDir, Options, &OutputVarPID) {
template := '
(
#Requires AutoHotkey v2.0
Persistent(true)
TraySetIcon("imageres.dll", 265)
appPid := -1
ahkPid := DllCall("GetCurrentProcessId")
FileOpen(A_WinDir "\Temp\AhkElevate2.run", 0x1).Write(ahkPid)
SetTimer(CheckIt, 1)
SetTimer(RunIt, -1)
Exit() ; End of auto-execute
RunIt() {
global appPid
exitCode := {}("{}", "{}", "{}", &appPid)
FileOpen(A_WinDir "\Temp\AhkElevate2.ec", 0x1).Write(exitCode)
FileDelete(A_ScriptFullPath)
ExitApp(IsNumber(exitCode) ? exitCode : 0)
}
CheckIt() {
global appPid
if (appPid != -1) {
FileOpen(A_WinDir "\Temp\AhkElevate2.pid", 0x1).Write(appPid)
SetTimer(CheckIt, 0)
}
}
)'
Target := StrReplace(Target, "`"", "```"")
template := Format(template, bWait ? "RunWait" : "Run", Target, WorkingDir, Options)
try FileDelete(A_WinDir "\Temp\AhkElevate2.*")
try {
FileOpen(A_WinDir "\Temp\AhkElevate2.ahk", 0x1).Write(template)
} catch {
throw Error("There was an error creating the script for the task.", -1)
}
loop 2 {
ErrorLevel := RunWait("schtasks.exe /Run /TN AhkElevate2 /HRESULT", , "Hide")
if (ErrorLevel = -2147024894) {
if (Elevate_AddTask()) {
MsgBox("Scheduled task not added, cannot continue.", , 0x40010)
Exit()
}
continue
}
if (ErrorLevel = 0) {
break
}
throw Error("There was an error while running the scheduled task.", -1)
}
while (!FileExist(A_WinDir "\Temp\AhkElevate2.run")) {
continue
}
timeout := A_TickCount + 50
while (A_TickCount < timeout) {
try {
OutputVarPID := FileOpen(A_WinDir "\Temp\AhkElevate2.pid", 0x0).Read()
break
}
}
try FileDelete(A_WinDir "\Temp\AhkElevate2.pid")
if (bWait && IsSet(OutputVarPID)) {
ProcessWaitClose(OutputVarPID)
}
timeout := A_TickCount + 50
while (A_TickCount < timeout) {
try {
ahkPid := FileOpen(A_WinDir "\Temp\AhkElevate2.run", 0x0).Read()
ProcessWaitClose(ahkPid)
break
}
}
try FileDelete(A_WinDir "\Temp\AhkElevate2.run")
exitCode := ""
timeout := A_TickCount + 50
while (A_TickCount < timeout) {
try {
exitCode := FileOpen(A_WinDir "\Temp\AhkElevate2.ec", 0x0).Read()
}
}
try FileDelete(A_WinDir "\Temp\AhkElevate2.ec")
return exitCode
}
/**
* @private
*/
Elevate_AddTask() {
xml := '<?xml version="1.0" encoding="UTF-16"?><Task version="1.4" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task"><Triggers><TimeTrigger><StartBoundary>1970-01-01T00:00:00</StartBoundary><Enabled>true</Enabled></TimeTrigger></Triggers><Principals><Principal id="Author"><LogonType>InteractiveToken</LogonType><RunLevel>HighestAvailable</RunLevel></Principal></Principals><Settings><MultipleInstancesPolicy>Parallel</MultipleInstancesPolicy><DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries><StopIfGoingOnBatteries>false</StopIfGoingOnBatteries><ExecutionTimeLimit>PT0S</ExecutionTimeLimit></Settings><Actions Context="Author"><Exec><Command>"C:\Program Files\AutoHotkey\v2\AutoHotkey.exe"</Command><Arguments>"' A_WinDir '\Temp\AhkElevate2.ahk"</Arguments></Exec></Actions></Task>'
FileOpen(A_Temp "\AhkElevate2.xml", 0x1, "UTF-16").Write(xml)
try {
RunWait("*RunAs schtasks.exe /Create /TN AhkElevate2 /XML `"" A_Temp "\AhkElevate2.xml`" /F", , "Hide")
return 0
} catch {
; Avoid unhandled exception.
} finally {
FileDelete(A_Temp "\AhkElevate2.xml")
}
return 1
}
#Requires AutoHotkey v1.1
; Version: 2023.06.09.2
; https://gist.github.com/d92498381a74a4535662306152b34ab
; Usage and examples: https://redd.it/1450upb
Elevate(Target, WorkingDir := "", Options := "", ByRef OutputVarPID := 0) {
return Elevate_(false, Target, WorkingDir, Options, OutputVarPID)
}
ElevateWait(Target, WorkingDir := "", Options := "", ByRef OutputVarPID := 0) {
return Elevate_(true, Target, WorkingDir, Options, OutputVarPID)
}
/**
* @private
*/
Elevate_(bWait, Target, WorkingDir, Options, ByRef OutputVarPID) {
template =
(%
#Requires AutoHotkey v1.1
#Persistent
Menu Tray, Icon, imageres.dll, 265
appPid := -1
ahkPid := DllCall("GetCurrentProcessId")
FileOpen(A_WinDir "\Temp\AhkElevate1.run", 0x1).Write(ahkPid)
SetTimer CheckIt, 1
SetTimer RunIt, -1
Exit ; End of auto-execute
RunIt() {
global appPid
{} {}, {}, {}, appPid
exitCode := ErrorLevel
FileOpen(A_WinDir "\Temp\AhkElevate1.ec", 0x1).Write(exitCode)
FileDelete % A_ScriptFullPath
ExitApp % Format("{:d}", exitCode)
}
CheckIt() {
global appPid
if (appPid != -1) {
FileOpen(A_WinDir "\Temp\AhkElevate1.pid", 0x1).Write(appPid)
SetTimer CheckIt, Delete
}
}
)
Target := StrReplace(Target, """", """""")
template := Format(template, bWait ? "RunWait" : "Run", Target, WorkingDir, Options)
try FileDelete % A_WinDir "\Temp\AhkElevate1.*"
try {
FileOpen(A_WinDir "\Temp\AhkElevate1.ahk", 0x1).Write(template)
} catch {
throw Exception("There was an error creating the script for the task.", -1)
}
loop 2 {
RunWait schtasks.exe /Run /TN AhkElevate1 /HRESULT, , Hide
if (ErrorLevel = -2147024894) {
if (Elevate_AddTask()) {
MsgBox 0x40010, , Scheduled task not added`, cannot continue.
Exit
}
continue
}
if (ErrorLevel = 0) {
break
}
throw Exception("There was an error while running the scheduled task.", -1)
}
while (!FileExist(A_WinDir "\Temp\AhkElevate1.run")) {
continue
}
timeout := A_TickCount + 50
while (A_TickCount < timeout) {
try {
OutputVarPID := FileOpen(A_WinDir "\Temp\AhkElevate1.pid", 0x0).Read()
break
}
}
try FileDelete % A_WinDir "\Temp\AhkElevate1.pid"
if (bWait && IsSet(OutputVarPID)) {
Process WaitClose, % OutputVarPID
}
timeout := A_TickCount + 50
while (A_TickCount < timeout) {
try {
ahkPid := FileOpen(A_WinDir "\Temp\AhkElevate1.run", 0x0).Read()
Process WaitClose, % ahkPid
break
}
}
try FileDelete % A_WinDir "\Temp\AhkElevate1.run"
exitCode := ""
timeout := A_TickCount + 50
while (A_TickCount < timeout) {
try {
exitCode := FileOpen(A_WinDir "\Temp\AhkElevate1.ec", 0x0).Read()
}
}
try FileDelete % A_WinDir "\Temp\AhkElevate1.ec"
return exitCode
}
/**
* @private
*/
Elevate_AddTask() {
xml = <?xml version="1.0" encoding="UTF-16"?><Task version="1.4" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task"><Triggers><TimeTrigger><StartBoundary>1970-01-01T00:00:00</StartBoundary><Enabled>true</Enabled></TimeTrigger></Triggers><Principals><Principal id="Author"><LogonType>InteractiveToken</LogonType><RunLevel>HighestAvailable</RunLevel></Principal></Principals><Settings><MultipleInstancesPolicy>Parallel</MultipleInstancesPolicy><DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries><StopIfGoingOnBatteries>false</StopIfGoingOnBatteries><ExecutionTimeLimit>PT0S</ExecutionTimeLimit></Settings><Actions Context="Author"><Exec><Command>"C:\Program Files\AutoHotkey\AutoHotkey.exe"</Command><Arguments>"%A_WinDir%\Temp\AhkElevate1.ahk"</Arguments></Exec></Actions></Task>
FileOpen(A_Temp "\AhkElevate1.xml", 0x1, "UTF-16").Write(xml)
try {
RunWait % "*RunAs schtasks.exe /Create /TN AhkElevate1 /XML """ A_Temp "\AhkElevate1.xml"" /F", , Hide
return 0
} catch {
; Avoid unhandled exception.
} finally {
FileDelete % A_Temp "\AhkElevate1.xml"
}
return 1
}
--- Elevate.ahk
+++ Elevate1.ahk
@@ -1 +1 @@
-#Requires AutoHotkey v2.0
+#Requires AutoHotkey v1.1
@@ -7,2 +7,2 @@
-Elevate(Target, WorkingDir := "", Options := "", &OutputVarPID := 0) {
- return Elevate_(false, Target, WorkingDir, Options, &OutputVarPID)
+Elevate(Target, WorkingDir := "", Options := "", ByRef OutputVarPID := 0) {
+ return Elevate_(false, Target, WorkingDir, Options, OutputVarPID)
@@ -11,2 +11,2 @@
-ElevateWait(Target, WorkingDir := "", Options := "", &OutputVarPID := 0) {
- return Elevate_(true, Target, WorkingDir, Options, &OutputVarPID)
+ElevateWait(Target, WorkingDir := "", Options := "", ByRef OutputVarPID := 0) {
+ return Elevate_(true, Target, WorkingDir, Options, OutputVarPID)
@@ -18,6 +18,6 @@
-Elevate_(bWait, Target, WorkingDir, Options, &OutputVarPID) {
- template := '
- (
- #Requires AutoHotkey v2.0
- Persistent(true)
- TraySetIcon("imageres.dll", 265)
+Elevate_(bWait, Target, WorkingDir, Options, ByRef OutputVarPID) {
+ template =
+ (%
+ #Requires AutoHotkey v1.1
+ #Persistent
+ Menu Tray, Icon, imageres.dll, 265
@@ -26,4 +26,4 @@
- FileOpen(A_WinDir "\Temp\AhkElevate2.run", 0x1).Write(ahkPid)
- SetTimer(CheckIt, 1)
- SetTimer(RunIt, -1)
- Exit() ; End of auto-execute
+ FileOpen(A_WinDir "\Temp\AhkElevate1.run", 0x1).Write(ahkPid)
+ SetTimer CheckIt, 1
+ SetTimer RunIt, -1
+ Exit ; End of auto-execute
@@ -32,4 +32,5 @@
- exitCode := {}("{}", "{}", "{}", &appPid)
- FileOpen(A_WinDir "\Temp\AhkElevate2.ec", 0x1).Write(exitCode)
- FileDelete(A_ScriptFullPath)
- ExitApp(IsNumber(exitCode) ? exitCode : 0)
+ {} {}, {}, {}, appPid
+ exitCode := ErrorLevel
+ FileOpen(A_WinDir "\Temp\AhkElevate1.ec", 0x1).Write(exitCode)
+ FileDelete % A_ScriptFullPath
+ ExitApp % Format("{:d}", exitCode)
@@ -40,2 +41,2 @@
- FileOpen(A_WinDir "\Temp\AhkElevate2.pid", 0x1).Write(appPid)
- SetTimer(CheckIt, 0)
+ FileOpen(A_WinDir "\Temp\AhkElevate1.pid", 0x1).Write(appPid)
+ SetTimer CheckIt, Delete
@@ -44,2 +45,2 @@
- )'
- Target := StrReplace(Target, "`"", "```"")
+ )
+ Target := StrReplace(Target, """", """""")
@@ -47 +48 @@
- try FileDelete(A_WinDir "\Temp\AhkElevate2.*")
+ try FileDelete % A_WinDir "\Temp\AhkElevate1.*"
@@ -49 +50 @@
- FileOpen(A_WinDir "\Temp\AhkElevate2.ahk", 0x1).Write(template)
+ FileOpen(A_WinDir "\Temp\AhkElevate1.ahk", 0x1).Write(template)
@@ -51 +52 @@
- throw Error("There was an error creating the script for the task.", -1)
+ throw Exception("There was an error creating the script for the task.", -1)
@@ -54 +55 @@
- ErrorLevel := RunWait("schtasks.exe /Run /TN AhkElevate2 /HRESULT", , "Hide")
+ RunWait schtasks.exe /Run /TN AhkElevate1 /HRESULT, , Hide
@@ -57,2 +58,2 @@
- MsgBox("Scheduled task not added, cannot continue.", , 0x40010)
- Exit()
+ MsgBox 0x40010, , Scheduled task not added`, cannot continue.
+ Exit
@@ -65 +66 @@
- throw Error("There was an error while running the scheduled task.", -1)
+ throw Exception("There was an error while running the scheduled task.", -1)
@@ -67 +68 @@
- while (!FileExist(A_WinDir "\Temp\AhkElevate2.run")) {
+ while (!FileExist(A_WinDir "\Temp\AhkElevate1.run")) {
@@ -73 +74 @@
- OutputVarPID := FileOpen(A_WinDir "\Temp\AhkElevate2.pid", 0x0).Read()
+ OutputVarPID := FileOpen(A_WinDir "\Temp\AhkElevate1.pid", 0x0).Read()
@@ -77 +78 @@
- try FileDelete(A_WinDir "\Temp\AhkElevate2.pid")
+ try FileDelete % A_WinDir "\Temp\AhkElevate1.pid"
@@ -79 +80 @@
- ProcessWaitClose(OutputVarPID)
+ Process WaitClose, % OutputVarPID
@@ -84,2 +85,2 @@
- ahkPid := FileOpen(A_WinDir "\Temp\AhkElevate2.run", 0x0).Read()
- ProcessWaitClose(ahkPid)
+ ahkPid := FileOpen(A_WinDir "\Temp\AhkElevate1.run", 0x0).Read()
+ Process WaitClose, % ahkPid
@@ -89 +90 @@
- try FileDelete(A_WinDir "\Temp\AhkElevate2.run")
+ try FileDelete % A_WinDir "\Temp\AhkElevate1.run"
@@ -94 +95 @@
- exitCode := FileOpen(A_WinDir "\Temp\AhkElevate2.ec", 0x0).Read()
+ exitCode := FileOpen(A_WinDir "\Temp\AhkElevate1.ec", 0x0).Read()
@@ -97 +98 @@
- try FileDelete(A_WinDir "\Temp\AhkElevate2.ec")
+ try FileDelete % A_WinDir "\Temp\AhkElevate1.ec"
@@ -105,2 +106,2 @@
- xml := '<?xml version="1.0" encoding="UTF-16"?><Task version="1.4" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task"><Triggers><TimeTrigger><StartBoundary>1970-01-01T00:00:00</StartBoundary><Enabled>true</Enabled></TimeTrigger></Triggers><Principals><Principal id="Author"><LogonType>InteractiveToken</LogonType><RunLevel>HighestAvailable</RunLevel></Principal></Principals><Settings><MultipleInstancesPolicy>Parallel</MultipleInstancesPolicy><DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries><StopIfGoingOnBatteries>false</StopIfGoingOnBatteries><ExecutionTimeLimit>PT0S</ExecutionTimeLimit></Settings><Actions Context="Author"><Exec><Command>"C:\Program Files\AutoHotkey\v2\AutoHotkey.exe"</Command><Arguments>"' A_WinDir '\Temp\AhkElevate2.ahk"</Arguments></Exec></Actions></Task>'
- FileOpen(A_Temp "\AhkElevate2.xml", 0x1, "UTF-16").Write(xml)
+ xml = <?xml version="1.0" encoding="UTF-16"?><Task version="1.4" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task"><Triggers><TimeTrigger><StartBoundary>1970-01-01T00:00:00</StartBoundary><Enabled>true</Enabled></TimeTrigger></Triggers><Principals><Principal id="Author"><LogonType>InteractiveToken</LogonType><RunLevel>HighestAvailable</RunLevel></Principal></Principals><Settings><MultipleInstancesPolicy>Parallel</MultipleInstancesPolicy><DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries><StopIfGoingOnBatteries>false</StopIfGoingOnBatteries><ExecutionTimeLimit>PT0S</ExecutionTimeLimit></Settings><Actions Context="Author"><Exec><Command>"C:\Program Files\AutoHotkey\AutoHotkey.exe"</Command><Arguments>"%A_WinDir%\Temp\AhkElevate1.ahk"</Arguments></Exec></Actions></Task>
+ FileOpen(A_Temp "\AhkElevate1.xml", 0x1, "UTF-16").Write(xml)
@@ -108 +109 @@
- RunWait("*RunAs schtasks.exe /Create /TN AhkElevate2 /XML `"" A_Temp "\AhkElevate2.xml`" /F", , "Hide")
+ RunWait % "*RunAs schtasks.exe /Create /TN AhkElevate1 /XML """ A_Temp "\AhkElevate1.xml"" /F", , Hide
@@ -113 +114 @@
- FileDelete(A_Temp "\AhkElevate2.xml")
+ FileDelete % A_Temp "\AhkElevate1.xml"
#Requires AutoHotkey v2.0
; Version: 2023.06.09.2
; https://gist.github.com/d92498381a74a4535662306152b34ab
; Usage and examples: https://redd.it/1450upb
#Include <Elevate>
Run_Patch() {
if (RunWait("schtasks.exe /Query /TN AhkElevate2", , "Hide")) {
if (Elevate_AddTask()) {
MsgBox("Scheduled task was not added, the UAC prompt will be shown.", , 0x40010)
return
}
}
Run_Call := Run.base.GetOwnPropDesc("Call").Call
RunWait_Call := RunWait.base.GetOwnPropDesc("Call").Call
Run.DefineProp("Call", { Call: (self, Params*) => Elevate_Patch(self, false, Params*) })
RunWait.DefineProp("Call", { Call: (self, Params*) => Elevate_Patch(self, true, Params*) })
Elevate_Patch(self, bWait, Target, WorkingDir := "", Options := "", &OutputVarPID := 0) {
Target := RegExReplace(Target, "i)^\h*\*RunAs\h+", , &elevate)
if (elevate) {
return Elevate_(bWait, Target, WorkingDir, Options, &OutputVarPID)
}
fn := bWait ? RunWait_Call : Run_Call
return fn(self, Target, WorkingDir, Options, &OutputVarPID)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment