Quiero que mi secuencia de comandos de Python copie archivos en Vista. Cuando lo ejecuto desde una cmd.exe
ventana normal , no se generan errores, pero los archivos NO se copian. Si ejecuto cmd.exe
"como administrador" y luego ejecuto mi script, funciona bien.
Esto tiene sentido ya que el Control de cuentas de usuario (UAC) normalmente evita muchas acciones del sistema de archivos.
¿Hay alguna manera de que pueda, desde un script de Python, invocar una solicitud de elevación de UAC (esos cuadros de diálogo que dicen algo como "tal y tal aplicación necesita acceso de administrador, está bien?")
Si eso no es posible, ¿hay alguna forma en que mi script pueda al menos detectar que no está elevado para que pueda fallar correctamente?
python
windows
windows-vista
uac
jwfearn
fuente
fuente
Respuestas:
A partir de 2017, un método sencillo para lograrlo es el siguiente:
Si está utilizando Python 2.x, debe reemplazar la última línea por:
También nota que si usted convirtió script en Python en un archivo ejecutable (usando herramientas como
py2exe
,cx_freeze
,pyinstaller
), entonces usted debe utilizarsys.argv[1:]
en lugar desys.argv
en el cuarto parámetro.Algunas de las ventajas aquí son:
ctypes
ysys
de la biblioteca estándar.La documentación de la llamada ShellExecute subyacente está aquí .
fuente
ctypes.windll.shell32.ShellExecuteW(None, "runas", sys.executable, "", None, 1)
sys.executable
resuelve solo el intérprete de Python (pC:\Python27\Python.exe
. Ej. ) La solución es agregar el script en ejecución como argumento (reemplazar""
).ctypes.windll.shell32.ShellExecuteW(None, "runas", sys.executable, __file__, None, 1)
También tenga en cuenta que para que esto funcione en python 2.x, todos los argumentos de cadena deben ser unicode (es deciru"runas"
,unicode(sys.executable)
yunicode(__file__)
)ShellExecuteW
yShellExecuteA
son llamadas a laShellExecute
función en la API de Windows. El primero obliga a que las cadenas estén en formato unicode y el segundo se usa con formato ANSIMe tomó un poco de tiempo hacer que la respuesta de dguaraglia funcionara, así que en el interés de ahorrar tiempo a otros, esto es lo que hice para implementar esta idea:
fuente
subprocess.list2cmdline
para hacerlo correctamente.Parece que no hay forma de elevar los privilegios de la aplicación durante un tiempo para que pueda realizar una tarea en particular. Windows necesita saber al inicio del programa si la aplicación requiere ciertos privilegios, y le pedirá al usuario que confirme cuándo la aplicación realiza alguna tarea que necesita esos privilegios. Hay dos maneras de hacer esto:
Estos dos artículos explican con mucho más detalle cómo funciona.
Lo que haría, si no desea escribir un contenedor ctypes desagradable para la API CreateElevatedProcess, es usar el truco ShellExecuteEx explicado en el artículo del Proyecto de código (Pywin32 viene con un contenedor para ShellExecute). ¿Cómo? Algo como esto:
Cuando su programa se inicia, comprueba si tiene privilegios de administrador, si no los tiene, se ejecuta a sí mismo usando el truco ShellExecute y sale inmediatamente, si los tiene, realiza la tarea en cuestión.
Como describe su programa como un "script", supongo que es suficiente para sus necesidades.
Salud.
fuente
runas
muestra un nuevo mensaje. Y startfile no acepta argumentos de línea de comando para$EXECUTABLE.
.chm
archivo.Solo agrego esta respuesta en caso de que la Búsqueda de Google dirija a otros aquí como yo. Usé el
elevate
módulo en mi secuencia de comandos de Python y la secuencia de comandos ejecutada con privilegios de administrador en Windows 10.https://pypi.org/project/elevate/
fuente
elevate
módulo y aparece el error "El sistema no puede acceder al archivo", ¿alguna idea de por qué sucedería eso?El siguiente ejemplo se basa en el excelente trabajo y la respuesta aceptada de MARTIN DE LA FUENTE SAAVEDRA . En particular, se introducen dos enumeraciones. El primero permite especificar fácilmente cómo se abrirá un programa elevado y el segundo ayuda cuando los errores deben identificarse fácilmente. Tenga en cuenta que si desea que todos los argumentos de línea de comandos pasados al nuevo proceso,
sys.argv[0]
probablemente debería ser reemplazada con una llamada a la función:subprocess.list2cmdline(sys.argv)
.fuente
Reconociendo que esta pregunta se hizo hace años, creo que frmdstryr ofrece una solución más elegante en github usando su módulo pywinutils:
Extracto:
Esto utiliza la interfaz COM e indica automáticamente que se necesitan privilegios de administrador con el cuadro de diálogo familiar que vería si estuviera copiando en un directorio donde se requieren privilegios de administrador y también proporciona el cuadro de diálogo de progreso de archivo típico durante la operación de copia.
fuente
Es posible que esto no responda completamente a su pregunta, pero también puede intentar usar Elevate Command Powertoy para ejecutar el script con privilegios elevados de UAC.
http://technet.microsoft.com/en-us/magazine/2008.06.elevation.aspx
Creo que si lo usa, se vería como 'elevar python yourscript.py'
fuente
Puede hacer un acceso directo en algún lugar y como destino usar: python yourscript.py luego en propiedades y selección avanzada ejecutar como administrador.
Cuando el usuario ejecuta el acceso directo, le pedirá que eleve la aplicación.
fuente
Si su secuencia de comandos siempre requiere privilegios de administrador, entonces:
fuente
your_script.py
como un usuario administrador. Asegúrese de entender el comentario de @ Kugel .Una variación del trabajo de Jorenko anterior permite que el proceso elevado use la misma consola (pero vea mi comentario a continuación):
fuente
Esta es principalmente una actualización de la respuesta de Jorenko, que permite usar parámetros con espacios en Windows, pero también debería funcionar bastante bien en Linux :) Además, funcionará con cx_freeze o py2exe ya que no usamos
__file__
perosys.argv[0]
como ejecutablefuente