Run Python Application at Startup on Windows
On Windows, it is something common for a program to run when the system starts. If we have an application written in Python (either as .py
source code or packed as an executable .exe
file) and we want it to be executed when Windows starts, we can include in it a code to let the operating system know that it must be invoked whenever the computer is turned on. The procedure is simple. We create a new entry inside the registry, in a specific location where Microsoft's system will be able to read our program's path and run it on startup.
The Windows Registry is a key-value database (like a big Python dictionary) where the operating system and many programs store configuration data. Developers are able to interact with the registry using functions from the Windows API. In Python there are some alternatives for accessing the API, mainly the ctypes
standard module and the pywin32
package. In this post we'll use pywin32, so let's install it via pip:
py -m pip install pywin32
And make sure that the package was installed successfully by checking there is no exception when running the following in the Python interactive shell:
Once installed, we'll create three functions to achieve our goal. The run_at_startup_set()
and run_script_at_startup_set()
functions will be responsible for creating a new entry in the registry to let the system know our Python script or application must start when the operating system does. (The former should be used when delivering our application as an executable file, the later when delivering as source code.) Inversely, the run_at_startup_remove()
function will let us remove the entry from the registry.
Each function includes a user
argument that is False
by default. When user=True
, these functions write in a registry key that is common to all users, in which case the code requires admin rights. If we just want to configure our application or script to run at startup for the current user (the one that executes the code), then we use user=True
and thus the functions do not require elevation.
If our application is released as an executable file (e. g. myapp.exe
), let's call the first function at the beginning of our code like this:
|
# For the current user only (no elevation required.)
|
|
run_at_startup_set("My Application", user=True)
|
The first argument will be the name of the key in the registry, so make sure it is a unique name. There is no risk in executing the code every time our program is started since the function will check that the key is not already there before writing anything. If the key already exists, nothing happens.
We can check whether the operation succeeded by looking up the path (stored in STARTUP_KEY_PATH
) using the Windows Registry editor (regedit.exe
):
If we want to use the function to set up the startup of another application, its path can be specified as the second argument:
|
# For all users (requires elevation).
|
|
run_at_startup_set("Other Application", r"C:\path\to\other\application.exe")
|
|
# For the current user only (no elevation required.)
|
|
run_at_startup_set(
|
|
"Other Application",
|
|
r"C:\path\to\other\application.exe",
|
|
user=True
|
|
)
|
If our application is delivered as a source code file (such as myapp.py
), then we must make a call like the following:
|
# For the current user only (no elevation required.)
|
|
run_script_at_startup_set("My Application", user=True)
|
Note how in this case the value in the registry includes the path of the interpreter which called the code above:
Finally, if we want to clear the registry programmatically, so our application or script no longer starts with the system, we do: