Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

Run as Administrator (XP/Vista/7) A_IsAdmin Params [Lib]


  • Please log in to reply
49 replies to this topic
shajul
  • Members
  • 571 posts
  • Last active: Aug 01 2015 03:45 PM
  • Joined: 15 Sep 2006
Lib compliant script to Elevate privileges of compiled/non-compiled scripts with/without parameters.

Just put this script to your Standard Library and put this function at the top of the script, as simple as that.
RunAsAdmin()

Download : RunAsAdmin.ahk


History:
To check if the user has Administrator rights and elevate it if needed by the script, i stumbled upon the help doc, which states that

..this would need to be enhanced to work for compiled scripts and/or to pass parameters..

on page http://www.autohotke...les.htm#BuiltIn..

The code given is..

if not A_IsAdmin
{
   DllCall("shell32\ShellExecuteA", uint, 0, str, "RunAs", str, A_AhkPath
      , str, """" . A_ScriptFullPath . """", str, A_WorkingDir, int, 1)
   ExitApp
}

To run for any scripts, compiled or not, with params use this code instead..

Loop, %0%  ; For each parameter:
  {
    param := %A_Index%  ; Fetch the contents of the variable whose name is contained in A_Index.
    params .= A_Space . param
  }
ShellExecute := A_IsUnicode ? "shell32\ShellExecute":"shell32\ShellExecuteA"
    
if not A_IsAdmin
{
    If A_IsCompiled
       DllCall(ShellExecute, uint, 0, str, "RunAs", str, A_ScriptFullPath, str, params , str, A_WorkingDir, int, 1)
    Else
       DllCall(ShellExecute, uint, 0, str, "RunAs", str, A_AhkPath, str, """" . A_ScriptFullPath . """" . A_Space . params, str, A_WorkingDir, int, 1)
    ExitApp
}

Edit1: Now it should work with both Basic AHK, Ansi and Unicode Autohotkey_L
Edit2: Shorter code, thanks Lexikos.
Edit3: Lib compliant version.


Also, why not use this code in the help file and docs also, so that any noob like me can benefit?
[/url]

  • Guests
  • Last active:
  • Joined: --
So that code will not work for compiled (.exe) scripts? What can I do to make it work on compiled scripts?

Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006
In theory, your script can be simplified as commented below:
SetWorkingDir %A_ScriptDir%
Loop, %0%  ; No need for the intermediary variable 'param':
    params .= A_Space . [color=darkred]"""" .[/color] %A_Index% [color=darkred]. """"[/color]
if not A_IsAdmin  ; Check this first to reduce repetition.
{
    if A_IsCompiled
        DllCall("shell32\ShellExecuteA", uint, 0, str, "RunAs", str, A_ScriptFullPath
            , str, [color=darkred]SubStr([/color]params[color=darkred],2)[/color] , str, A_WorkingDir, int, 1)
    else
        DllCall("shell32\ShellExecuteA", uint, 0, str, "RunAs", str, A_AhkPath
            , str, """" . A_ScriptFullPath . """" [color=darkred].[/color] params, str, A_WorkingDir, int, 1)
    ExitApp
}
...however, I haven't tested it. Note the changes I've made to compensate for the extra space at the beginning of the params, and spaces in parameters (i.e. in case the script was invoked as script.ahk "one param" "two params").

I would vote to update the example to demonstrate the difference between compiled and uncompiled scripts, but leave parameters as an exercise for the readers.

What can I do to make it work on compiled scripts?

I think you missed the point of shajul's post...

aaffe
  • Members
  • 1045 posts
  • Last active: Jan 16 2014 01:32 PM
  • Joined: 17 May 2007
I think the second one must also just Substr:
SetWorkingDir %A_ScriptDir%
Loop, %0%  ; No need for the intermediary variable 'param':
    params .= A_Space . """" . %A_Index% . """"
if not A_IsAdmin  ; Check this first to reduce repetition.
{
    if A_IsCompiled
        DllCall("shell32\ShellExecuteA", uint, 0, str, "RunAs", str, A_ScriptFullPath
            , str, SubStr(params,2) , str, A_WorkingDir, int, 1)
    else
        DllCall("shell32\ShellExecuteA", uint, 0, str, "RunAs", str, A_AhkPath
            , str, """" . A_ScriptFullPath . """" . [color=red]SubStr(params,2), [/color]str, A_WorkingDir, int, 1)
    ExitApp
}

Edit: Sorry, I saw that the leading space MUST be there in the second one. So forget my changing.

shajul
  • Members
  • 571 posts
  • Last active: Aug 01 2015 03:45 PM
  • Joined: 15 Sep 2006
Just updated my code so that it runs on Autohotkey_L also (unicode)

Also, Lexikos version of the same will also just need the modification of

DllCall("shell32\ShellExecuteA"

to be changed to

DllCall("shell32\ShellExecute"

as ShellExecuteA expects an Ansi string..

The documentation supplied with Autohotkey_L be changed so that all ansi functions are replaced. I can help in whatever way possible by me.

Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006
I'll update the documentation. However, in AutoHotkey_L this is possible:
if not A_IsAdmin
{
    Run *RunAs "%A_ScriptFullPath%"
    ExitApp
}
This will work with compiled or uncompiled scripts (though the latter only works if AutoHotkey is installed). Unfortunately Run *verb "file" parameters isn't supported... yet.

Edit 2011-01-17: Hmm, apparently doesn't work with uncompiled scripts?? Wonder what I was thinking.

shajul
  • Members
  • 571 posts
  • Last active: Aug 01 2015 03:45 PM
  • Joined: 15 Sep 2006
I just moved over to AutoHotkey_L, and was updating my scripts to run with it.. The extra features are cool.. Thanks.

I'll update the documentation. However, in AutoHotkey_L this is possible:

if not A_IsAdmin
{
    Run *RunAs "%A_ScriptFullPath%"
    ExitApp
}
This will work with compiled or uncompiled scripts (though the latter only works if AutoHotkey is installed). Unfortunately Run *verb "file" parameters isn't supported... yet.



hotkeyd
  • Guests
  • Last active:
  • Joined: --
Using standard AHK, which version of the above scripts is correct for compiled and un-compiled scripts ?

shajul
  • Members
  • 571 posts
  • Last active: Aug 01 2015 03:45 PM
  • Joined: 15 Sep 2006

Using standard AHK, which version of the above scripts is correct for compiled and un-compiled scripts ?


Use this..
RunAsAdmin:
params := ""
if 0>0
{
    Loop, %0%  ; For each parameter:
    {
        param := %A_Index%  ; Fetch the contents of the variable whose name is contained in A_Index.
        params .= A_Space . param
    }
}
ShellExecute := A_IsUnicode ? "shell32\ShellExecute":"shell32\ShellExecuteA"
    
If A_IsCompiled
{
    if not A_IsAdmin
    {
       DllCall(ShellExecute, uint, 0, str, "RunAs", str, A_ScriptFullPath, str, params , str, A_WorkingDir, int, 1)
       ExitApp
    }
}
Else
{
    if not A_IsAdmin
    {
       DllCall(ShellExecute, uint, 0, str, "RunAs", str, A_AhkPath, str, """" . A_ScriptFullPath . """" . A_Space . params, str, A_WorkingDir, int, 1)
       ExitApp
    }
}


hotkeyd
  • Guests
  • Last active:
  • Joined: --
cheers I'll try this later.

Should this allow my script to write ini files and machines where they don't have admin access ?

aaffe
  • Members
  • 1045 posts
  • Last active: Jan 16 2014 01:32 PM
  • Joined: 17 May 2007
*Deleted* Sorry, didnt read that you cant overgive parameters via *Runas...

shajul
  • Members
  • 571 posts
  • Last active: Aug 01 2015 03:45 PM
  • Joined: 15 Sep 2006
I have created a scheduled task to run a small script that runs as administrator at logon..
That script spawns all my other scripts, so that they all run with administrator privileges! :)

aaffe
  • Members
  • 1045 posts
  • Last active: Jan 16 2014 01:32 PM
  • Joined: 17 May 2007
Sorry, but this doesnt run for me:
if not A_IsAdmin
{
    Run *RunAs "%A_ScriptFullPath%"
    ExitApp
}
It says:
Action: RunAs
Verb: RunAs
There is no program bound to this file.

The ahk-file isnt compiled.....does it have to be compiled?

hotkeyd
  • Guests
  • Last active:
  • Joined: --
RunAsAdmin:
params := ""
if 0>0
{
    Loop, %0%  ; For each parameter:
    {
        param := %A_Index%  ; Fetch the contents of the variable whose name is contained in A_Index.
        params .= A_Space . param
    }
}
If A_IsCompiled
{
    if not A_IsAdmin
    {
       DllCall("shell32\ShellExecute", uint, 0, str, "RunAs", str, A_ScriptFullPath, str, params , str, A_WorkingDir, int, 1)
       ExitApp
    }
}
Else
{
    if not A_IsAdmin
    {
       DllCall("shell32\ShellExecute", uint, 0, str, "RunAs", str, A_AhkPath, str, """" . A_ScriptFullPath . """" . A_Space . params, str, A_WorkingDir, int, 1)
       ExitApp
    }
}

return

msgbox %A_IsAdmin%
Running the above on XP logged in with admin rights returns a msgbox with 1

Running as a compiled exe on XP with admin rights returns a msgbox with 1

Running on Win 7 as a compiled exe returns nothing.

Win 7 Right click run as administrator, return msgbox with 1.

I thought this would elevate the script/exe to have admin rights ?
Is that wrong ? or have I missed something ?

hotkeyd
  • Guests
  • Last active:
  • Joined: --
Loop, %0%  ; For each parameter:
  {
    param := %A_Index%  ; Fetch the contents of the variable whose name is contained in A_Index.
    params .= A_Space . param
  }
ShellExecute := A_IsUnicode ? "shell32\ShellExecute":"shell32\ShellExecuteA"
   
if not A_IsAdmin
{
    If A_IsCompiled
       DllCall(ShellExecute, uint, 0, str, "RunAs", str, A_ScriptFullPath, str, params , str, A_WorkingDir, int, 1)
    Else
       DllCall(ShellExecute, uint, 0, str, "RunAs", str, A_AhkPath, str, """" . A_ScriptFullPath . """" . A_Space . params, str, A_WorkingDir, int, 1)
    ExitApp
}

this seems to work :)