Comment exécuter un script python avec des privilèges élevés sur windows

j'écris une application pyqt qui nécessite d'exécuter une tâche d'administration. Je préférerais commencer mon script avec le privilège elevate. Je sais que cette question est posée à plusieurs reprises dans tel ou tel forum. Mais la solution que les gens proposent est de jeter un coup D'oeil à cette question. demande élévation UAC depuis un script Python?

cependant, je ne suis pas en mesure d'exécuter le code d'exemple donné dans le lien. J'ai mis ce code en haut de le fichier principal et a essayé de l'exécuter.

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)
print "I am root now."

il demande en fait la permission d'élever mais la ligne d'impression ne sont jamais exécutés. Quelqu'un peut m'aider à exécuter le code ci-dessus avec succès. Merci à l'avance.

39
demandé sur Community 2013-10-30 05:41:19

7 réponses

merci à tous pour votre réponse. J'ai fait travailler mon script avec le module / script écrit par Preston Landers en 2010. Après deux jours de navigation sur internet, j'ai pu trouver le script car il était profondément caché dans la liste de diffusion pywin32. Avec ce script, il est plus facile de vérifier si l'utilisateur est administrateur et, si ce n'est pas le cas, de demander UAC/ admin à droite. Il fournit une sortie dans des fenêtres séparées pour savoir ce que fait le code. Exemple sur la façon d'utiliser le code, également inclus dans le script. Pour le bénéfice de tous ceux qui sont tous à la recherche de UAC sur windows ont un coup d'oeil à ce code. J'espère que ça aidera quelqu'un qui cherche la même solution. Il peut être utilisé quelque chose comme ceci à partir de votre script principal: -

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

le code réel est: -

#!/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())
61
répondu sundar_ima 2013-11-01 01:06:42

dans les commentaires à la réponse vous avez pris le code de quelqu'un dit ShellExecuteEx ne Poste pas son STDOUT retour à l'shell d'origine . donc vous ne verrez pas" je suis root maintenant", même si le code fonctionne probablement bien.

au lieu d'imprimer quelque chose, essayez d'écrire dans un fichier:

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"

et regardez dans le dossier.

8
répondu andrew cooke 2017-05-23 12:10:29

Voici une solution avec une redirection stdout:

def elevate():
    import ctypes, win32com.shell.shell, win32event, win32process
    outpath = r'%s\%s.out' % (os.environ["TEMP"], os.path.basename(__file__))
    if ctypes.windll.shell32.IsUserAnAdmin():
        if os.path.isfile(outpath):
            sys.stderr = sys.stdout = open(outpath, 'w', 0)
        return
    with open(outpath, 'w+', 0) as outfile:
        hProc = win32com.shell.shell.ShellExecuteEx(lpFile=sys.executable, \
            lpVerb='runas', lpParameters=' '.join(sys.argv), fMask=64, nShow=0)['hProcess']
        while True:
            hr = win32event.WaitForSingleObject(hProc, 40)
            while True:
                line = outfile.readline()
                if not line: break
                sys.stdout.write(line)
            if hr != 0x102: break
    os.remove(outpath)
    sys.stderr = ''
    sys.exit(win32process.GetExitCodeProcess(hProc))

if __name__ == '__main__':
    elevate()
    main()
6
répondu Florent B. 2015-07-20 06:11:37

Voici une solution qui ne nécessitait qu'un module ctypes. Soutenez le programme enveloppé de pyinstaller.

#!python
# coding: utf-8
import sys
import ctypes

def run_as_admin(argv=None, debug=False):
    shell32 = ctypes.windll.shell32
    if argv is None and shell32.IsUserAnAdmin():
        return True

    if argv is None:
        argv = sys.argv
    if hasattr(sys, '_MEIPASS'):
        # Support pyinstaller wrapped program.
        arguments = map(unicode, argv[1:])
    else:
        arguments = map(unicode, argv)
    argument_line = u' '.join(arguments)
    executable = unicode(sys.executable)
    if debug:
        print 'Command line: ', executable, argument_line
    ret = shell32.ShellExecuteW(None, u"runas", executable, argument_line, None, 1)
    if int(ret) <= 32:
        return False
    return None


if __name__ == '__main__':
    ret = run_as_admin()
    if ret is True:
        print 'I have admin privilege.'
        raw_input('Press ENTER to exit.')
    elif ret is None:
        print 'I am elevating to admin privilege.'
        raw_input('Press ENTER to exit.')
    else:
        print 'Error(ret=%d): cannot elevate privilege.' % (ret, )
4
répondu Gary Lee 2015-11-22 14:58:34

j'ai trouvé une solution très facile à ce problème.

  1. créer un raccourci pour python.exe
  2. changez la cible de raccourci en quelque chose comme C:\xxx\...\python.exe your_script.py
  3. , Cliquez sur "avance..."dans le panneau de propriétés du raccourci, puis cliquez sur l'option "exécuter en tant qu'administrateur"

Je ne sais pas si les sorts de ces options sont corrects, puisque j'utilise la version chinoise de Windows.

0
répondu delphifirst 2015-09-21 15:49:49

je peux confirmer que la solution de delphifirst fonctionne et est la solution la plus simple et la plus simple au problème d'exécuter un script python avec des privilèges élevés.

j'ai créé un raccourci vers l'exécutable python (python.exe) et ensuite modifié le raccourci en ajoutant mon nom du script après l'appel à python.EXE. J'ai ensuite coché "exécuter en tant qu'administrateur" dans l'onglet "compatibilité" du raccourci. Lorsque le raccourci est exécuté, vous obtenez un message demandant la permission de exécuter le script en tant qu'administrateur.

mon application python particulière était un programme d'installation. Le programme permet d'installer et de désinstaller une autre application python. Dans mon cas, j'ai créé deux raccourcis, l'un nommé "appname installer" et l'autre nommé "appname désinstaller". La seule différence entre les deux raccourcis est l'argument qui suit le nom du script python. Dans la version d'installation, l'argument est "install". Dans la version uninstall, l'argument est "uninstall". Code dans le script d'installation évalue l'argument fourni et appelle la fonction appropriée (installation ou désinstallation).

j'espère que mon explication aidera les autres à trouver plus rapidement comment exécuter un script python avec des privilèges élevés.

0
répondu John Moore 2016-12-06 17:32:33

aussi si votre répertoire de travail est différent de celui que vous pouvez utiliser lpDirectory

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

sera utile si changer le chemin n'est pas une option souhaitable supprimer unicode pour python 3.X

0
répondu Pranav 2017-02-28 06:13:36