Request UAC elevation from within a Python script?

前端 未结 11 642

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

相关标签:
11条回答
  • 2020-11-22 05:28

    A variation on Jorenko's work above allows the elevated process to use the same console (but see my comment below):

    def spawn_as_administrator():
        """ Spawn ourself with administrator rights and wait for new process to exit
            Make the new process use the same console as the old one.
              Raise Exception() if we could not get a handle for the new re-run the process
              Raise pywintypes.error() if we could not re-spawn
            Return the exit code of the new process,
              or return None if already running the second admin process. """
        #pylint: disable=no-name-in-module,import-error
        import win32event, win32api, win32process
        import win32com.shell.shell as shell
        if '--admin' in sys.argv:
            return None
        script = os.path.abspath(sys.argv[0])
        params = ' '.join([script] + sys.argv[1:] + ['--admin'])
        SEE_MASK_NO_CONSOLE = 0x00008000
        SEE_MASK_NOCLOSE_PROCESS = 0x00000040
        process = shell.ShellExecuteEx(lpVerb='runas', lpFile=sys.executable, lpParameters=params, fMask=SEE_MASK_NO_CONSOLE|SEE_MASK_NOCLOSE_PROCESS)
        hProcess = process['hProcess']
        if not hProcess:
            raise Exception("Could not identify administrator process to install drivers")
        # It is necessary to wait for the elevated process or else
        #  stdin lines are shared between 2 processes: they get one line each
        INFINITE = -1
        win32event.WaitForSingleObject(hProcess, INFINITE)
        exitcode = win32process.GetExitCodeProcess(hProcess)
        win32api.CloseHandle(hProcess)
        return exitcode
    
    0 讨论(0)
  • 2020-11-22 05:32

    Recognizing this question was asked years ago, I think a more elegant solution is offered on github by frmdstryr using his module pywinutils:

    Excerpt:

    import pythoncom
    from win32com.shell import shell,shellcon
    
    def copy(src,dst,flags=shellcon.FOF_NOCONFIRMATION):
        """ Copy files using the built in Windows File copy dialog
    
        Requires absolute paths. Does NOT create root destination folder if it doesn't exist.
        Overwrites and is recursive by default 
        @see http://msdn.microsoft.com/en-us/library/bb775799(v=vs.85).aspx for flags available
        """
        # @see IFileOperation
        pfo = pythoncom.CoCreateInstance(shell.CLSID_FileOperation,None,pythoncom.CLSCTX_ALL,shell.IID_IFileOperation)
    
        # Respond with Yes to All for any dialog
        # @see http://msdn.microsoft.com/en-us/library/bb775799(v=vs.85).aspx
        pfo.SetOperationFlags(flags)
    
        # Set the destionation folder
        dst = shell.SHCreateItemFromParsingName(dst,None,shell.IID_IShellItem)
    
        if type(src) not in (tuple,list):
            src = (src,)
    
        for f in src:
            item = shell.SHCreateItemFromParsingName(f,None,shell.IID_IShellItem)
            pfo.CopyItem(item,dst) # Schedule an operation to be performed
    
        # @see http://msdn.microsoft.com/en-us/library/bb775780(v=vs.85).aspx
        success = pfo.PerformOperations()
    
        # @see sdn.microsoft.com/en-us/library/bb775769(v=vs.85).aspx
        aborted = pfo.GetAnyOperationsAborted()
        return success is None and not aborted    
    

    This utilizes the COM interface and automatically indicates that admin privileges are needed with the familiar dialog prompt that you would see if you were copying into a directory where admin privileges are required and also provides the typical file progress dialog during the copy operation.

    0 讨论(0)
  • 2020-11-22 05:33

    It took me a little while to get dguaraglia's answer working, so in the interest of saving others time, here's what I did to implement this idea:

    import os
    import sys
    import win32com.shell.shell as shell
    ASADMIN = 'asadmin'
    
    if sys.argv[-1] != ASADMIN:
        script = os.path.abspath(sys.argv[0])
        params = ' '.join([script] + sys.argv[1:] + [ASADMIN])
        shell.ShellExecuteEx(lpVerb='runas', lpFile=sys.executable, lpParameters=params)
        sys.exit(0)
    
    0 讨论(0)
  • 2020-11-22 05:33

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

    runas /user:Administrator "python your_script.py"
    
    0 讨论(0)
  • 2020-11-22 05:35

    This may not completely answer your question but you could also try using the Elevate Command Powertoy in order to run the script with elevated UAC privileges.

    http://technet.microsoft.com/en-us/magazine/2008.06.elevation.aspx

    I think if you use it it would look like 'elevate python yourscript.py'

    0 讨论(0)
  • 2020-11-22 05:37

    You can make a shortcut somewhere and as the target use: python yourscript.py then under properties and advanced select run as administrator.

    When the user executes the shortcut it will ask them to elevate the application.

    0 讨论(0)
提交回复
热议问题