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.
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())
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.
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()
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, )
j'ai trouvé une solution très facile à ce problème.
- créer un raccourci pour
python.exe
- changez la cible de raccourci en quelque chose comme
C:\xxx\...\python.exe your_script.py
- , 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.
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.
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