How to run python script with elevated privilege on windows

前端 未结 11 1387
臣服心动
臣服心动 2020-11-22 07:34

I am writing a pyqt application which require to execute admin task. I would prefer to start my script with elevate privilege. I am aware that this question is asked many ti

相关标签:
11条回答
  • 2020-11-22 08:10

    in comments to the answer you took the code from someone says ShellExecuteEx doesn't post its STDOUT back to the originating shell. so you will not see "I am root now", even though the code is probably working fine.

    instead of printing something, try writing to a file:

    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)
    with open("somefilename.txt", "w") as out:
        print >> out, "i am root"
    

    and then look in the file.

    0 讨论(0)
  • 2020-11-22 08:12

    This worked for me:


    import win32com.client as client
    
    required_command = "cmd" # Enter your command here
    
    required_password = "Simple1" # Enter your password here
    
    def run_as(required_command, required_password):
        shell = client.Dispatch("WScript.shell")
        shell.Run(f"runas /user:administrator {required_command}")
        time.sleep(1)
        shell.SendKeys(f"{required_password}\r\n", 0)
    
    
    if __name__ = '__main__':
        run_as(required_command, required_password)
    

    Below are the references I used for above code: https://win32com.goermezer.de/microsoft/windows/controlling-applications-via-sendkeys.html https://www.oreilly.com/library/view/python-cookbook/0596001673/ch07s16.html

    0 讨论(0)
  • 2020-11-22 08:15

    Thank you all for your reply. I have got my script working with the module/ script written by Preston Landers way back in 2010. After two days of browsing the internet I could find the script as it was was deeply hidden in pywin32 mailing list. With this script it is easier to check if the user is admin and if not then ask for UAC/ admin right. It does provide output in separate windows to find out what the code is doing. Example on how to use the code also included in the script. For the benefit of all who all are looking for UAC on windows have a look at this code. I hope it helps someone looking for same solution. It can be used something like this from your main script:-

    import admin
    if not admin.isUserAdmin():
            admin.runAsAdmin()
    

    The actual code is:-

    #!/usr/bin/env python
    # -*- coding: utf-8; mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*-
    # vim: fileencoding=utf-8 tabstop=4 expandtab shiftwidth=4
    
    # (C) COPYRIGHT © Preston Landers 2010
    # Released under the same license as Python 2.6.5
    
    
    import sys, os, traceback, types
    
    def isUserAdmin():
    
        if os.name == 'nt':
            import ctypes
            # WARNING: requires Windows XP SP2 or higher!
            try:
                return ctypes.windll.shell32.IsUserAnAdmin()
            except:
                traceback.print_exc()
                print "Admin check failed, assuming not an admin."
                return False
        elif os.name == 'posix':
            # Check for root on Posix
            return os.getuid() == 0
        else:
            raise RuntimeError, "Unsupported operating system for this module: %s" % (os.name,)
    
    def runAsAdmin(cmdLine=None, wait=True):
    
        if os.name != 'nt':
            raise RuntimeError, "This function is only implemented on Windows."
    
        import win32api, win32con, win32event, win32process
        from win32com.shell.shell import ShellExecuteEx
        from win32com.shell import shellcon
    
        python_exe = sys.executable
    
        if cmdLine is None:
            cmdLine = [python_exe] + sys.argv
        elif type(cmdLine) not in (types.TupleType,types.ListType):
            raise ValueError, "cmdLine is not a sequence."
        cmd = '"%s"' % (cmdLine[0],)
        # XXX TODO: isn't there a function or something we can call to massage command line params?
        params = " ".join(['"%s"' % (x,) for x in cmdLine[1:]])
        cmdDir = ''
        showCmd = win32con.SW_SHOWNORMAL
        #showCmd = win32con.SW_HIDE
        lpVerb = 'runas'  # causes UAC elevation prompt.
    
        # print "Running", cmd, params
    
        # ShellExecute() doesn't seem to allow us to fetch the PID or handle
        # of the process, so we can't get anything useful from it. Therefore
        # the more complex ShellExecuteEx() must be used.
    
        # procHandle = win32api.ShellExecute(0, lpVerb, cmd, params, cmdDir, showCmd)
    
        procInfo = ShellExecuteEx(nShow=showCmd,
                                  fMask=shellcon.SEE_MASK_NOCLOSEPROCESS,
                                  lpVerb=lpVerb,
                                  lpFile=cmd,
                                  lpParameters=params)
    
        if wait:
            procHandle = procInfo['hProcess']    
            obj = win32event.WaitForSingleObject(procHandle, win32event.INFINITE)
            rc = win32process.GetExitCodeProcess(procHandle)
            #print "Process handle %s returned code %s" % (procHandle, rc)
        else:
            rc = None
    
        return rc
    
    def test():
        rc = 0
        if not isUserAdmin():
            print "You're not an admin.", os.getpid(), "params: ", sys.argv
            #rc = runAsAdmin(["c:\\Windows\\notepad.exe"])
            rc = runAsAdmin()
        else:
            print "You are an admin!", os.getpid(), "params: ", sys.argv
            rc = 0
        x = raw_input('Press Enter to exit.')
        return rc
    
    
    if __name__ == "__main__":
        sys.exit(test())
    
    0 讨论(0)
  • 2020-11-22 08:21

    Also if your working directory is different than you can use lpDirectory

        procInfo = ShellExecuteEx(nShow=showCmd,
                              lpVerb=lpVerb,
                              lpFile=cmd,
                              lpDirectory= unicode(direc),
                              lpParameters=params)
    

    Will come handy if changing the path is not a desirable option remove unicode for python 3.X

    0 讨论(0)
  • 2020-11-22 08:22

    It worth mentioning that if you intend to package your application with PyInstaller and wise to avoid supporting that feature by yourself, you can pass the --uac-admin or --uac-uiaccess argument in order to request UAC elevation on start.

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