Request UAC elevation from within a Python script?

Viewed 131218

I want my Python script to copy files on Vista. When I run it from a normal cmd.exe window, no errors are generated, yet the files are NOT copied. If I run cmd.exe "as administator" and then run my script, it works fine.

This makes sense since User Account Control (UAC) normally prevents many file system actions.

Is there a way I can, from within a Python script, invoke a UAC elevation request (those dialogs that say something like "such and such app needs admin access, is this OK?")

If that's not possible, is there a way my script can at least detect that it is not elevated so it can fail gracefully?

12 Answers

It seems there's no way to elevate the application privileges for a while for you to perform a particular task. Windows needs to know at the start of the program whether the application requires certain privileges, and will ask the user to confirm when the application performs any tasks that need those privileges. There are two ways to do this:

  1. Write a manifest file that tells Windows the application might require some privileges
  2. Run the application with elevated privileges from inside another program

This two articles explain in much more detail how this works.

What I'd do, if you don't want to write a nasty ctypes wrapper for the CreateElevatedProcess API, is use the ShellExecuteEx trick explained in the Code Project article (Pywin32 comes with a wrapper for ShellExecute). How? Something like this:

When your program starts, it checks if it has Administrator privileges, if it doesn't it runs itself using the ShellExecute trick and exits immediately, if it does, it performs the task at hand.

As you describe your program as a "script", I suppose that's enough for your needs.

Cheers.

Just adding this answer in case others are directed here by Google Search as I was. I used the elevate module in my Python script and the script executed with Administrator Privileges in Windows 10.

https://pypi.org/project/elevate/

For one-liners, put the code to where you need UAC.

Request UAC, if failed, keep running:

import ctypes, sys

ctypes.windll.shell32.IsUserAnAdmin() or ctypes.windll.shell32.ShellExecuteW(
    None, "runas", sys.executable, " ".join(sys.argv), None, 1) > 32 and exit()


Request UAC, if failed, exit:

import ctypes, sys

ctypes.windll.shell32.IsUserAnAdmin() or (ctypes.windll.shell32.ShellExecuteW(
    None, "runas", sys.executable, " ".join(sys.argv), None, 1) > 32, exit())

Function style:

# Created by BaiJiFeiLong@gmail.com at 2022/6/24
import ctypes
import sys


def request_uac_or_skip():
    ctypes.windll.shell32.IsUserAnAdmin() or ctypes.windll.shell32.ShellExecuteW(
        None, "runas", sys.executable, " ".join(sys.argv), None, 1) > 32 and sys.exit()


def request_uac_or_exit():
    ctypes.windll.shell32.IsUserAnAdmin() or (ctypes.windll.shell32.ShellExecuteW(
        None, "runas", sys.executable, " ".join(sys.argv), None, 1) > 32, sys.exit())

If your script always requires an Administrator's privileges then:

runas /user:Administrator "python your_script.py"
Related