111 votes

Demander l'élévation de l'UAC à partir d'un script Python ?

Je veux que mon script Python copie des fichiers sous Vista. Lorsque je l'exécute à partir d'un programme normal cmd.exe aucune erreur n'est générée, mais les fichiers ne sont PAS copiés. Si j'exécute cmd.exe "en tant qu'administrateur" et ensuite exécuter mon script, cela fonctionne bien.

Cela est logique puisque le contrôle des comptes d'utilisateurs (UAC) empêche normalement de nombreuses actions sur le système de fichiers.

Existe-t-il un moyen d'invoquer, à partir d'un script Python, une demande d'élévation de l'UAC (ces dialogues qui disent quelque chose comme "telle ou telle application a besoin d'un accès administrateur, est-ce que c'est OK ?").

Si ce n'est pas possible, y a-t-il un moyen pour que mon script puisse au moins détecter qu'il n'est pas élevé afin qu'il puisse échouer gracieusement ?

3 votes

stackoverflow.com/a/1445547/1628132 en suivant cette réponse, vous créez un .exe à partir du .py script en utilisant py2exe et en utilisant un drapeau appelé 'uac_info', c'est une solution assez soignée.

72voto

Jorenko Points 1174

Il m'a fallu un peu de temps pour faire fonctionner la réponse de dguaraglia, alors pour faire gagner du temps aux autres, voici ce que j'ai fait pour mettre en œuvre cette idée :

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)

1 votes

Il semble juste s'élever puis sortir ... si je mets des instructions d'impression, elles ne sont pas exécutées une deuxième fois.

6 votes

@JoranBeasley, vous ne verrez aucune sortie. ShellExecuteEx ne renvoie pas son STDOUT au shell d'origine. À cet égard, le débogage sera... difficile. Mais l'astuce du hissage de privilège fonctionne définitivement.

1 votes

@TimKeating, ActiveState a une recette qui devrait rendre le débogage un peu plus facile : Utiliser l'utilitaire DebugView avec la journalisation standard de python

29voto

dguaraglia Points 3113

Il semble qu'il n'y ait aucun moyen d'élever les privilèges de l'application pendant un certain temps pour vous permettre d'effectuer une tâche particulière. Windows doit savoir au début du programme si l'application nécessite certains privilèges, et demandera à l'utilisateur de confirmer lorsque l'application effectue des tâches qui besoin de ces privilèges. Il y a deux façons de procéder :

  1. Rédiger un fichier manifeste qui indique à Windows que l'application peut nécessiter certains privilèges.
  2. Exécuter l'application avec des privilèges élevés à partir d'un autre programme.

Ce site deux articles explique de manière beaucoup plus détaillée comment cela fonctionne.

Ce que je ferais, si vous ne voulez pas écrire un wrapper ctypes pour l'API CreateElevatedProcess, c'est utiliser l'astuce ShellExecuteEx expliquée dans l'article de Code Project (Pywin32 est livré avec un wrapper pour ShellExecute). Comment ? Quelque chose comme ceci :

Lorsque votre programme démarre, il vérifie s'il a les privilèges d'un administrateur, s'il ne les a pas, il s'exécute en utilisant l'astuce ShellExecute et sort immédiatement, s'il les a, il exécute la tâche en question.

Comme vous décrivez votre programme comme un "script", je suppose que c'est suffisant pour vos besoins.

A la vôtre.

0 votes

Merci pour ces liens, ils m'ont été très utiles pour découvrir beaucoup de choses sur l'UAC.

4 votes

Une chose à noter à ce sujet est que vous pouvez faire ShellExecute sans PyWin32 (j'ai eu des problèmes pour l'installer) en utilisant os.startfile($EXECUTABLE, "runas").

0 votes

@Mike - mais runas fait apparaître une nouvelle invite. Et startfile n'accepte pas d'arguments en ligne de commande pour $EXECUTABLE.

2voto

TinyGrasshopper Points 155

Cela ne répond peut-être pas complètement à votre question, mais vous pouvez également essayer d'utiliser le Elevate Command Powertoy afin d'exécuter le script avec des privilèges UAC élevés.

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

Je pense que si vous l'utilisez, cela ressemblera à 'elevate python yourscript.py'.

2voto

user2088050 Points 19

Vous pouvez créer un raccourci quelque part et l'utiliser comme cible : python yourscript.py puis, sous Propriétés et Avancées, sélectionnez Exécuter en tant qu'administrateur.

Lorsque l'utilisateur exécute le raccourci, il lui est demandé d'élever l'application.

0voto

J.F. Sebastian Points 102961

Si votre script nécessite toujours les privilèges d'un Administrateur alors :

runas /user:Administrator "python your_script.py"

16 votes

Attention, élévation != exécution en tant qu'administrateur

0 votes

Je suis novice en python... pouvez-vous me dire où je dois mettre ce code ?

0 votes

@RahatIslamKhan : Ouvrez une fenêtre d'invite de commande et mettez-la où : la commande s'exécute. your_script.py en tant qu'utilisateur Administrateur. Assurez-vous de bien comprendre Commentaire de @Kugel .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X