How to Reload Script as Administrator Automatically?

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
TheMaxx
Posts: 10
Joined: 28 Mar 2019, 15:14

How to Reload Script as Administrator Automatically?

10 Apr 2019, 03:33

Hello.

I have a AHK script/application that stays running on the taskbar in the notification area. It contains some hotkeys and functions.

It needs to be running as administrator in order to manipulate the Task Manager.

I can use the following common code snippet to automatically run the script.ahk file as administrator:

Code: Select all

;restart script in admin mode
if not A_IsAdmin
{
   Run *RunAs "%A_ScriptFullPath%" 
   ExitApp
}
That brings up the User Account Control window to confirm running as administrator just fine.

I also use the following code to reload the script automatically without showing the reload script confirmation window:

Code: Select all

#SingleInstance Force						; Replaces script if running.
My problem is that when I am working on the script and want to reload the script by running the script.ahk file, it's seems not able to reload the script or run the code snippet to restart in admin mode because the non-elevated script can't do it's thing because the elevated script is already running as administrator...and shows the window:

Could not close the previous instance of this script. Keep waiting? Yes|No

I can omit the code snippet "restart script in admin mode" and either: compile the script and set the properties of the application to run as administrator, or create a shortcut to the script.ahk file and set the properties of the shortcut to run as administrator. Both of those work fine and always run as admin and reload the script or application.

But how to make this work by opening the script.ahk file itself? Is it possible?

I just want to be able to double click the script.ahk file, have it show the User Account Control window, click Yes and have it reload the script.

Thanks a lot.
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: How to Reload Script as Administrator Automatically?

10 Apr 2019, 04:13

- I'd probably use #SingleInstance off, and write code to mimic #SingleInstance force.

- E.g. if script is not admin, reopen as admin.
- E.g. if script is admin, check if script already open, close other instances.

- Here's some code for interacting with other scripts:
list of AutoHotkey WM_COMMAND IDs (e.g. Reload/Edit/Suspend/ListVars on another script) - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=74&t=27824
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
spookynutz
Posts: 12
Joined: 09 Apr 2019, 12:48

Re: How to Reload Script as Administrator Automatically?

10 Apr 2019, 10:02

This should elevate the script, regardless if it's compiled or not, assuming the current user actually is an administrator, and it shouldn't get stuck in an endless loop of restarting if something goes wrong.

Code: Select all

ElevateAdministrator()

if(A_IsAdmin)
	MsgBox Yer a wizard, Harry!
ExitApp


ElevateAdministrator() {
	ret := "", hToken := "", ReturnLength := ""
	DllCall("SetLastError", "UInt", 0)
	ret := DllCall("Advapi32.dll\OpenProcessToken", "UInt", DllCall("GetCurrentProcess"), "UInt", 0x0008, "UIntP", hToken)
	DllCall("SetLastError", "UInt", 0)
	DllCall("Advapi32.dll\GetTokenInformation", "UInt", hToken, "UInt", 18, "Int", 0, "Int", 0, "UIntP", ReturnLength)
	sizeof_elevationType := VarSetCapacity(elevationType, ReturnLength, 0)
	DllCall("SetLastError", "UInt", 0)
	DllCall("Advapi32.dll\GetTokenInformation", "UInt", hToken, "UInt", 18, "UIntP", elevationType, "Int", sizeof_elevationType, "UIntP", ReturnLength)
	if (elevationType == 3) {
		full_command_line := DllCall("GetCommandLine", "str")
		if not (RegExMatch(full_command_line, " /restart(?!\S)")) {
			if(A_IsCompiled) {
				Run *RunAs "%A_ScriptFullPath%" /restart,, UseErrorLevel
			} else {
				Run *RunAs "%A_AhkPath%" /restart "%A_ScriptFullPath%",, UseErrorLevel
			}
			ExitApp
		}
	} 
	if (hToken)
		DllCall("CloseHandle", "UInt", hToken)
	return
}

If you know you have admin privilege and just want to elevate an AHK file, below is all you would need.

Code: Select all

if not (RegExMatch(DllCall("GetCommandLine", "str"), " /restart(?!\S)")) {
	Run *RunAs "%A_AhkPath%" /restart "%A_ScriptFullPath%",, UseErrorLevel
	ExitApp
}

if(A_IsAdmin)
	MsgBox Yer a wizard, Harry!
ExitApp
TheMaxx
Posts: 10
Joined: 28 Mar 2019, 15:14

Re: How to Reload Script as Administrator Automatically?

11 Apr 2019, 14:06

jeeswg: I want to reload the script with admin rights, so using #SingleInstance off is not an option, since I don't want a second instance of the program open. If the script is ran not as admin, it reopens as admin just fine, but if the script is already running as admin, then running the script again not as admin can't replace the script already running as admin.

spookynutz: I tried both your code snippets. I commented out the ExitApp line after the MsgBox line because I want to keep the program open. They both end up with the same result of seeing the window: Could not close the previous instance of this script. Keep waiting? Yes|No

Isn't there a simpler way? Maybe it's just not possible? Thanks for the help.
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: How to Reload Script as Administrator Automatically?

11 Apr 2019, 14:48

- When you have 2 admin scripts running at the same time, the newer one can close the older one.
- The principle of '#SingleInstance force' can be recreated in a custom way: based on certain criteria, you tell another script to close.
- If you want to reload an admin script, as a non-admin script, you could check this:
Reloading: Admin to Non-Admin - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=5&t=7752
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
User avatar
DavidP
Posts: 220
Joined: 10 Aug 2014, 07:31

Re: How to Reload Script as Administrator Automatically?

12 Jun 2021, 14:01

spookynutz wrote:
10 Apr 2019, 10:02
This should elevate the script, regardless if it's compiled or not, assuming the current user actually is an administrator, and it shouldn't get stuck in an endless loop of restarting if something goes wrong.

Code: Select all

ElevateAdministrator()

if(A_IsAdmin)
	MsgBox Yer a wizard, Harry!
ExitApp


ElevateAdministrator() {
	ret := "", hToken := "", ReturnLength := ""
	DllCall("SetLastError", "UInt", 0)
	ret := DllCall("Advapi32.dll\OpenProcessToken", "UInt", DllCall("GetCurrentProcess"), "UInt", 0x0008, "UIntP", hToken)
	DllCall("SetLastError", "UInt", 0)
	DllCall("Advapi32.dll\GetTokenInformation", "UInt", hToken, "UInt", 18, "Int", 0, "Int", 0, "UIntP", ReturnLength)
	sizeof_elevationType := VarSetCapacity(elevationType, ReturnLength, 0)
	DllCall("SetLastError", "UInt", 0)
	DllCall("Advapi32.dll\GetTokenInformation", "UInt", hToken, "UInt", 18, "UIntP", elevationType, "Int", sizeof_elevationType, "UIntP", ReturnLength)
	if (elevationType == 3) {
		full_command_line := DllCall("GetCommandLine", "str")
		if not (RegExMatch(full_command_line, " /restart(?!\S)")) {
			if(A_IsCompiled) {
				Run *RunAs "%A_ScriptFullPath%" /restart,, UseErrorLevel
			} else {
				Run *RunAs "%A_AhkPath%" /restart "%A_ScriptFullPath%",, UseErrorLevel
			}
			ExitApp
		}
	} 
	if (hToken)
		DllCall("CloseHandle", "UInt", hToken)
	return
}

If you know you have admin privilege and just want to elevate an AHK file, below is all you would need.

Code: Select all

if not (RegExMatch(DllCall("GetCommandLine", "str"), " /restart(?!\S)")) {
	Run *RunAs "%A_AhkPath%" /restart "%A_ScriptFullPath%",, UseErrorLevel
	ExitApp
}

if(A_IsAdmin)
	MsgBox Yer a wizard, Harry!
ExitApp
Sorry I don't fully understand yet what effectively is the difference between these two 'Reload as Admin" scripts?

I will be admin when running my (compiled) script, and just want to make sure it runs as admin. Which of the two above variants do I use in this case?

(If it should not be possible for some reason for the script to run as Admin, then it should still run and not quit)
User avatar
DavidP
Posts: 220
Joined: 10 Aug 2014, 07:31

Re: How to Reload Script as Administrator Automatically?

14 Jun 2021, 12:41

a friendly *bump*...
DavidP wrote:
12 Jun 2021, 14:01
Sorry I don't fully understand yet what effectively is the difference between these two 'Reload as Admin" scripts?

I will be admin when running my (compiled) script, and just want to make sure it runs as admin. Which of the two above variants do I use in this case?

(If it should not be possible for some reason for the script to run as Admin, then it should still run and not quit)
Also, to me it seems that these two scripts do an ExitApp in all cases -- but that can't be correct?
Eureka
Posts: 65
Joined: 03 Apr 2018, 13:31

Re: How to Reload Script as Administrator Automatically?

14 Jun 2021, 18:56

Does this work for you?
( I had to add the A_AhkPath as there is no .ahk file association on my system, but you can do probably without)

Code: Select all

#SingleInstance Off

;	Restart script in admin mode if needed.

	if not A_IsAdmin
	{
		Run *RunAs "%A_AhkPath%" /restart "%A_ScriptFullPath%"
		ExitApp
	}


; Admin code

	MsgBox We are admin!


EDIT: That is basically what DavidP suggested too :o (didn't read all that ...)
User avatar
DavidP
Posts: 220
Joined: 10 Aug 2014, 07:31

Re: How to Reload Script as Administrator Automatically?

12 May 2022, 08:02

Sorry for the late reply, didn't get a mail notification for some reason.

Just was going to report that the following works for me, even without #SingleInstance Off, and even when having #SingleInstance Force in the header of the script (added header for completeness)

Code: Select all

#MenuMaskKey vkE8
#MaxHotkeysPerInterval, 800
#WinActivateForce
#InstallKeybdHook
#UseHook
SetTitleMatchMode, 2  
CoordMode, Mouse, Window
DetectHiddenText, Off
DetectHiddenWindows, On 
SetBatchLines -1 

#SingleInstance Force
; #SingleInstance Off

if not A_IsAdmin ; check if script runs as Administrator and if not restart script with Administrator privileges
	{
		Run *RunAs "%A_AhkPath%" /restart "%A_ScriptFullPath%"
		ExitApp
	}
	
; [...]
User avatar
DavidP
Posts: 220
Joined: 10 Aug 2014, 07:31

Re: How to Reload Script as Administrator Automatically?

14 May 2022, 17:54

Strangely, this script does not run:

Code: Select all

if not A_IsAdmin ; check if script runs as Administrator and if not restart script with Administrator privileges
	{
		Run *RunAs "%A_AhkPath%" /restart "%A_ScriptFullPath%"
		ExitApp
	}
...when it is compiled to an EXE with the default option (Base File "U64")

The compiled script then throws the following error message at startup:
Image

It works however when it is compiled with the base file option AutoHotkeyU64.exe instead:
Image

Can anyone explain this?
Last edited by DavidP on 15 May 2022, 04:03, edited 1 time in total.
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: How to Reload Script as Administrator Automatically?

14 May 2022, 18:28

There is an example in the documentation, :arrow: Run as Administrator.

Cheers.
TAC109
Posts: 1098
Joined: 02 Oct 2013, 19:41
Location: New Zealand

Re: How to Reload Script as Administrator Automatically?

14 May 2022, 18:43

@DavidP

You should also update your AutoHotkey to version 1.1.34.02, as this fixes some Ahk2Exe problems (as well as other bugs).

Cheers
My scripts:-
XRef - Produces Cross Reference lists for scripts
ReClip - A Text Reformatting and Clip Management utility
ScriptGuard - Protects Compiled Scripts from Decompilation
I also maintain Ahk2Exe

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: Google [Bot] and 132 guests