python windows admin elevated-privileges

Cómo ejecutar un script de python con privilegios elevados en Windows



admin elevated-privileges (7)

Estoy escribiendo una aplicación pyqt que requieren para ejecutar la tarea de administración. Preferiría comenzar mi script con elevar el privilegio. Soy consciente de que esta pregunta se hace muchas veces en SO o en otro foro. Pero la solución que la gente está sugiriendo es echar un vistazo a esta pregunta de SO. Solicitar elevación de UAC desde dentro de un script de Python.

Sin embargo, no puedo ejecutar el código de muestra que figura en el enlace. Puse este código en la parte superior del archivo principal y traté de ejecutarlo.

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."

De hecho, pide permiso para elevar, pero la línea de impresión nunca se ejecuta. Alguien puede ayudarme a ejecutar el código anterior con éxito. Gracias por adelantado.


Además, si su directorio de trabajo es diferente de lo que puede usar lpDirectory

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

Será útil si cambiar la ruta no es una opción deseable eliminar unicode para python 3.X


Aquí hay una solución con una redirección estándar:

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()


Aquí hay una solución que solo necesita el módulo ctypes. Admite el programa envuelto 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, )


Encontré una solución muy fácil a este problema.

  1. Crear un acceso directo para python.exe
  2. Cambie el destino del acceso directo a algo como C:/xxx/.../python.exe your_script.py
  3. Haga clic en "avanzar ..." en el panel de propiedades del acceso directo, y haga clic en la opción "ejecutar como administrador"

No estoy seguro de si los hechizos de estas opciones son correctos, ya que estoy usando la versión china de Windows.


Gracias a todos por su respuesta. Tengo mi guión trabajando con el módulo / guión escrito por Preston Landers en el año 2010. Después de dos días de navegar por Internet pude encontrar el guión tal como estaba, que estaba profundamente escondido en la lista de correo de pywin32. Con esta secuencia de comandos, es más fácil verificar si el usuario es administrador y, en caso negativo, solicitar el derecho de administrador / UAC. Proporciona salida en ventanas separadas para descubrir qué está haciendo el código. Ejemplo sobre cómo usar el código también incluido en el script. Para el beneficio de todos los que buscan el UAC en Windows, echen un vistazo a este código. Espero que ayude a alguien que busca la misma solución. Se puede usar algo como esto desde tu script principal:

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

El código real es: -

#!/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())


Puedo confirmar que la solución de delphifirst funciona y es la solución más simple y sencilla al problema de ejecutar un script de Python con privilegios elevados.

Creé un acceso directo al ejecutable de python (python.exe) y luego modifiqué el acceso directo agregando el nombre de mi script después de la llamada a python.exe. Luego marqué "ejecutar como administrador" en la "pestaña de compatibilidad" del acceso directo. Cuando se ejecuta el acceso directo, se le solicita que solicite permiso para ejecutar el script como administrador.

Mi aplicación Python particular fue un programa instalador. El programa permite instalar y desinstalar otra aplicación de Python. En mi caso, creé dos accesos directos, uno llamado "appname install" y el otro llamado "appname uninstall". La única diferencia entre los dos atajos es el argumento que sigue al nombre del script de python. En la versión del instalador, el argumento es "instalar". En la versión de desinstalación, el argumento es "desinstalar". El código en el script del instalador evalúa el argumento proporcionado y llama a la función apropiada (instalar o desinstalar) según sea necesario.

Espero que mi explicación ayude a otros a descubrir más rápidamente cómo ejecutar un script de Python con privilegios elevados.


en los comentarios a la respuesta que tomó el código de alguien dice que ShellExecuteEx no publica su STDOUT de vuelta al shell de origen . por lo que no verá "Ahora soy root", aunque el código probablemente funcione bien.

en lugar de imprimir algo, intente escribir en un archivo:

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"

y luego mira en el archivo.