Ejecutar aplicación o script al iniciar Windows

Actualización 30/01/2022: Tenemos una versión más nueva de este código en Ejecutar aplicación de Python al iniciar Windows.

Versión: 2.6 – 3.x.

Se trata de una tarea sencilla. El procedimiento es el de crear un nuevo valor en el registro, en una ubicación determinada, en donde el sistema operativo podrá leer la ruta de nuestro script o aplicación y ejecutarla al iniciarse.

Para lograrlo, utilizaremos la API de Windows a través del paquete pywin32. Si aún no lo has instalado, puedes descargar los instaladores en el enlace anterior, según la arquitectura de tu ordenador y versión de Python, o ejecutando en la terminal:

python -m pip install pywin32

Una vez instalado, puedes comprobar ejecutando en la consola interactiva o shell de Python:

import win32api

Las funciones de la API necesarias para llevar a cabo la tarea son:

Por lo tanto, comenzaremos importándolas desde el módulo win32api:

from win32api import (GetModuleFileName, RegCloseKey, RegDeleteValue,
                      RegOpenKeyEx, RegSetValueEx)

Nótese la función GetModuleFileName, que retorna la ruta completa de nuestro archivo y utilizaremos más adelante.

Además, serán necesarias algunas constantes para utilizar en las funciones anteriores.

from win32con import HKEY_LOCAL_MACHINE, KEY_WRITE, REG_SZ

La ruta de la clave en donde se guardan las aplicaciones que se ejecutan al iniciar Windows es HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run. En sistemas de 64 bits, generalmente éste se encargará de convertirla a su correspondiente (por ejemplo, HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Run). Crearemos una constante que almacene dicho valor.

SUBKEY = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run"

Una vez hecho esto, comenzaremos con la primera función, a la que llamaremos run_at_startup_set, y se encargará de crear un valor con la ruta de nuestra aplicación o script en la ubicación que indicamos anteriormente.

def run_at_startup_set(appname, path):
    """
    Set the registry key to run at startup.
    """

appname: nombre de nuestra apliación o script.
path: ruta completa del archivo a ejecutar.

    key = RegOpenKeyEx(HKEY_LOCAL_MACHINE, SUBKEY, 0, KEY_WRITE)

Abrimos la clave en la ruta establecida y con los privilegios necesarios para añadir valores.

    RegSetValueEx(key, appname, 0, REG_SZ, path)

Añadimos un nuevo valor con los datos de nuestra aplicación. REG_SZ indica que path finaliza con un carácter nulo. Recuerda que estas funciones son llamadas desde C/C++, y que pywin32 nos provee un wrapper en Python para las mismas.

    RegCloseKey(key)

Cerramos la clave para guardar los cambios.

La reciente función se utiliza, por ejemplo, de la siguiente manera:

run_at_startup_set("Recursos Python", r"C:\RecursosPython\rp.exe")

De esta manera se establece un valor en la clave el cual indica que C:\RecursosPython\rp.exe debe ejecutarse al iniciar Windows.

Vista previa

Para remover el valor establecido, crearemos la función run_at_startup_remove, que tomará como parámetro el nombre que le hemos dado a nuestra aplicación al llamar a run_at_startup_set.

def run_at_startup_remove(appname):
    """
    Removes the run-at-startup registry key.
    """

appname: nombre de nuestra aplicación o script.

    key = RegOpenKeyEx(HKEY_LOCAL_MACHINE, SUBKEY, 0, KEY_WRITE)

Abrimos nuevamente la clave con los privilegios necesarios para remover un valor.

    RegDeleteValue(key, appname)

Eliminamos el valor establecido anteriormente.

    RegCloseKey(key)

Guardamos los cambios.

Por último queda crear una función que ejecute un script utilizando el intérprete de Python actual.

def run_script_at_startup_set(appname, script):

El parámetro appname mantiene la misma funcionalidad en todas las funciones.
script: nombre o ruta del archivo .py.

    path = "%s %s" % (GetModuleFileName(0), script)

Crea la ruta pasando como argumento el nombre del script al intérprete actual.

    run_at_startup_set(appname, path)

Llama a la función original.

Ejemplo de uso:

run_script_at_startup_set("Reproducir audio", "audio.py")

Si este código se ejecuta en Python 2.7, se establecerá la ruta C:\Python27\python.exe audio.py. En Python 3.4, se establecerá C:\Python34\python.exe audio.py.

Código completo:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from win32api import (GetModuleFileName, RegCloseKey, RegDeleteValue,
                      RegOpenKeyEx, RegSetValueEx)
from win32con import HKEY_LOCAL_MACHINE, KEY_WRITE, REG_SZ


SUBKEY = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run"


def run_at_startup_set(appname, path):
    """
    Sets the registry key to run at startup.
    """
    key = RegOpenKeyEx(HKEY_LOCAL_MACHINE, SUBKEY, 0, KEY_WRITE)
    RegSetValueEx(key, appname, 0, REG_SZ, path)
    RegCloseKey(key)


def run_script_at_startup_set(appname, script):
    path = "%s %s" % (GetModuleFileName(0), script)
    run_at_startup_set(appname, path)


def run_at_startup_remove(appname):
    """
    Removes the run-at-startup registry key.
    """
    key = RegOpenKeyEx(HKEY_LOCAL_MACHINE, SUBKEY, 0, KEY_WRITE)
    RegDeleteValue(key, appname)
    RegCloseKey(key)

Curso online 👨‍💻

¡Ya lanzamos el curso oficial de Recursos Python en Udemy! Un curso moderno para aprender Python desde cero con programación orientada a objetos, SQL y tkinter en 2024.

Consultoría 💡

Ofrecemos servicios profesionales de desarrollo y capacitación en Python a personas y empresas. Consultanos por tu proyecto.

19 comentarios.

  1. genio podrias agregar un ejemplo ya que tengo mi script pyton convertido en exe si es posible el codigo completo para poder compararlo con mi codigo

      • entonces me das a entender que

        def run_script_at_startup_set(appname, script):
        path = «%s %s» % (GetModuleFileName(0), script)
        run_at_startup_set(appname, path) o solu uso
        run_at_startup_set(«Mi aplicación», GetModuleFileName(0)) ???????

        seria para mi ejecutable exe?

        podrias ayudarme? estoy sin poder resolverlo porfavor

        • Recursos Python says:

          Hola. No, ese código final no deberías modificarlo. Simplemente agregá en alguna parte de tu código la función para indicar que tu programa debe iniciarse con Windows, como en el ejemplo: run_at_startup_set("Recursos Python", r"C:\RecursosPython\rp.exe") (reemplazá esos valores por el nombre de tu aplicación y la ruta del ejecutable).

          Saludos

  2. Buenas, este articulo me ha resultado bastante útil en cuanto a información, la cual pretendo poner en practica, pero tengo un problema en cuanto a la importación del win32api. En primer lugar cuando lo busco para instalarlo, no me aparece y tampoco he encontrado una pagina donde conseguirlo, así que trate de instalar pywin32 que según leí es similar, pero este solo se instala, al momento de importarlo me sale el error de «unresolved import» y no he encontrado ninguna manera de solucionarlo. Sería de mucha ayuda si alguien me pudiera decir de que manera puedo ya sea instalar win32api o importar pywin32.

  3. Alberto Romero says:

    Buena tarde, pues yo me quedé con los ojos cuadrados, no sabía que se puede configurar un script de esa forma. Muchas gracias!

    Me surge una duda, un compañero que programa en PHP me preguntó por mi afición de aprender Python si puedo hacerle un script ejecutable( es todo un rollo si tiene que ver con bases de datos, pero creo que puedo hacerlo). La pregunta que me hizo es: puedes lograr que se ejecute la App( ejecutablePython.exe) sin que los usuarios se puedan salir a usar windows u otros programas?

    Yo le dije que supongo que eso ya es de políticas del S.O (de windows) pero, se podrá generar un script en Python que no deje salir del executable?

    Entonces me atrevo a pedir alguna sugerencia?

    • Recursos Python says:

      Hola Alberto. Dudo que eso sea posible (en términos generales, independietemente de Python) sin crear algún driver que haga cosas muy raras con las funciones del sistema operativo. Así que eso requiere conocimiento de C y mucho de la arquitectura de Windows en general. En otros sistemas operativos desconozco, pero lo veo complicado.

      No obstante, podés conseguir algunos resultados parciales usando la API de Windows (como hacemos en este artículo), p. ej. que la ventana de tu aplicación aparezca siempre al frente y otras por el estilo.

      Saludos!

  4. Excelente tutorial muy claro todo, solo me surge una ultima duda en la parte:

    def run_script_at_startup_set(appname, script):
    path = «%s %s» % (GetModuleFileName(0), script)
    run_at_startup_set(appname, path)

    Esta función se requiere porque es un script .py ¿verdad? si mi script python ya lo tengo convertido en ,exe ya no sería necesario usar esta función? o me equivoco.

    Saludos y gracias

    • Recursos Python says:

      Hola Adrián, gracias por el comentario. Si ya lo tienes convertido a un ejecutable, entonces puedes usar la primera función en conjunción con GetModuleFileName() ─que retorna la ruta del programa actual─ así:

      run_at_startup_set("Mi aplicación", GetModuleFileName(0))

      Saludos!

  5. Excelente tutorial te lo agradezco, espero puedas resolver un duda, al instala pywin32 parece que lo hace bien pero al importarla: import win32api me manda el siguiente error como si no la encontrara: ModuleNotFoundError: No module name ´pywin32´

    ¿sabrás la causa? saludos y muchas gracias.

      • Agradezco mucho tu respuesta y tiempo, apenas lo pude retomar, ya me fije lo estaba poniendo como import pywin32, haha ya probé con import win32api y memanda esto: ImportError: DLL load failed: %1 is not a valid Win32 application.

        Apenas lo voy viendo, de seguro debo de mover algo a las carpetas de python ¿verdad?

        • Recursos Python says:

          Ese tipo de errores generalmente ocurren cuando se instala una versión de 32-bit de pywin32 en un intérprete de Python de 64-bit o viceversa. ¿Podrías chequear eso?

          • Tienes toda la razón, estaba instalando la versión pywin32 de 64 , muchísimas gracias por tu ayuda, seguiré con el tutorial y estudiando mas. Te lo agradezco.

Deja una respuesta