Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ask for admin access for a Python function in Windows

I want to copy a list of files to the Windows system directory (C:\Windows) using a Python function.

I have a function:

import shutil

def copy_list(src_list, dst):
    for file in src_list:
        shutil.copy(file, dst)

And I want to call it like this:

def copy_as_admin():
    #... some code to obtain user elevation ...

    copy_list(files_list, "C:\\Windows\")

How can I achieve this? PS: I'm using Python3, I tried solutions in this thread, How to run python script with elevated privilege on windows but those solutions are for Python version 2.

like image 624
lpsandaruwan Avatar asked Sep 08 '25 16:09

lpsandaruwan


2 Answers

The following example builds on Cyrbil's excellent work. In particular, two enumerations are introduced. The first allows for easy specification of how an elevated program is to be opened, and the second helps when errors need to be easily identified. Please note that if you want all command line arguments passed to the new process, sys.argv[0] should probably be replaced with a function call: subprocess.list2cmdline(sys.argv).

#! /usr/bin/env python3
import ctypes
import enum
import sys


# Reference:
# msdn.microsoft.com/en-us/library/windows/desktop/bb762153(v=vs.85).aspx


class SW(enum.IntEnum):

    HIDE = 0
    MAXIMIZE = 3
    MINIMIZE = 6
    RESTORE = 9
    SHOW = 5
    SHOWDEFAULT = 10
    SHOWMAXIMIZED = 3
    SHOWMINIMIZED = 2
    SHOWMINNOACTIVE = 7
    SHOWNA = 8
    SHOWNOACTIVATE = 4
    SHOWNORMAL = 1


class ERROR(enum.IntEnum):

    ZERO = 0
    FILE_NOT_FOUND = 2
    PATH_NOT_FOUND = 3
    BAD_FORMAT = 11
    ACCESS_DENIED = 5
    ASSOC_INCOMPLETE = 27
    DDE_BUSY = 30
    DDE_FAIL = 29
    DDE_TIMEOUT = 28
    DLL_NOT_FOUND = 32
    NO_ASSOC = 31
    OOM = 8
    SHARE = 26


def bootstrap():
    if ctypes.windll.shell32.IsUserAnAdmin():
        main()
    else:
        hinstance = ctypes.windll.shell32.ShellExecuteW(
            None, 'runas', sys.executable, sys.argv[0], None, SW.SHOWNORMAL
        )
        if hinstance <= 32:
            raise RuntimeError(ERROR(hinstance))


def main():
    # Your Code Here
    print(input('Echo: '))


if __name__ == '__main__':
    bootstrap()
like image 183
Noctis Skytower Avatar answered Sep 10 '25 08:09

Noctis Skytower


You cannot change privilege at runtime on windows.

An app needs to have a manifest (not suitable for python) or be ran as a privileged user.

When the app starts and privileges are too low, you can ask the user to run as administrator, or let the app relaunch itself with elevated privileges by calling runas.

import ctypes

if not ctypes.windll.shell32.IsUserAnAdmin():
    print('Not enough priviledge, restarting...')
    import sys
    ctypes.windll.shell32.ShellExecuteW(
        None, 'runas', sys.executable, ' '.join(sys.argv), None, None)
else:
    print('Elevated privilege acquired')
like image 37
Cyrbil Avatar answered Sep 10 '25 06:09

Cyrbil