Updater System
A simple and customizable update system for Windows applications.
Supports update checking via a remote manifest.json
hosted on an HTTP or HTTPS server.
Features
- Automatic checking and downloading of updated files
- GUI built with wxPython
- File integrity verification using SHA-1
- Easy integration into any existing application
Requirements
- Python 3.8 or higher
wxPython
library (pip install wxPython
)- Server access to host
manifest.json
and application files over HTTP or HTTPS
How It Works
- The application provides the updater with the base server URL.
- The updater Reads
manifest.json
and checks which files need updating. - If updates are available, users can choose which files to update.
- Updated files are downloaded and the main application is relaunched.
Setup
1. Set MAIN_APP
At the top of your updater.py
, configure:
MAIN_APP = "YourApp.exe"
MAIN_APP
defines the executable file that will be relaunched after a successful update.
2. Prepare Your Server
Host the following:
manifest.json
(contains file listings and their SHA-1 hashes)- All application files that may require updating
Ensure files are accessible via URLs, e.g., https://yourdomain.com/yourapp/manifest.json
.
3. Generate manifest.json
Use the provided generator.py
tool.
Usage:
python3 generator.py <folder_name>
Example:
python3 generator.py my_app_folder
This command scans all files inside the specified folder and generates a manifest.json
.
Important Notes:
- Some files are automatically excluded, such as:
manifest.json
Updater.exe
- You can modify the
excluded_paths
list ingenerator.py
to customize exclusions.
4. Compile the Updater
It is strongly recommended to compile updater.py
into an executable (.exe) for better usability and portability.
You can use any Python-to-EXE compiler, such as:
Example compilation using PyInstaller:
pyinstaller --onefile updater.py
Integrating the Updater into Your Application
You can easily trigger the updater using the following pattern:
import wx
import os
import threading
import subprocess
class MainFrame(wx.Frame):
def __init__(self, parent, title):
super().__init__(parent, title=title, size=(300, 200))
panel = wx.Panel(self)
menubar = wx.MenuBar()
file_menu = wx.Menu()
run_updater_item = file_menu.Append(wx.ID_ANY, "Run Updater\tCtrl+U")
exit_item = file_menu.Append(wx.ID_EXIT, "Exit\tCtrl+Q")
menubar.Append(file_menu, "File")
self.SetMenuBar(menubar)
# Event bindings
self.Bind(wx.EVT_MENU, self.onRunUpdater, run_updater_item)
self.Bind(wx.EVT_MENU, self.onExit, exit_item)
def run_updater_thread(self, updater_path, updater_key):
"""Launch the updater in a separate thread."""
if os.path.exists(updater_path):
try:
subprocess.Popen([updater_path, updater_key], shell=False)
except Exception as e:
print(f"Error running updater: {e}")
else:
print("Updater executable not found.")
def onRunUpdater(self, event):
"""Handler for running the updater."""
updater_path = os.path.join(os.getcwd(), "Updater.exe")
updater_key = "https://yourdomain.com/yourapp/"
threading.Thread(target=self.run_updater_thread, args=(updater_path, updater_key)).start()
def onExit(self, event):
"""Exit the application."""
self.Close()
if __name__ == "__main__":
app = wx.App(False)
frame = MainFrame(None, "My App")
frame.Show()
app.MainLoop()
Example Directory Structure on your server-site
/your-app/
Updater.exe
YourApp.exe
manifest.json
(other file/folderss...)
Best Practices
- Always compile the updater script to
.exe
format to ensure a smooth user experience. - Sign your executables if possible to avoid Windows SmartScreen warnings.
- Regularly update your
manifest.json
whenever files are changed.
License
This project is licensed under the MIT License.
You are free to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the software.
See the MIT-LICENSE.txt file for more details.