simple-updater/README.md
2025-05-02 07:05:17 +07:00

166 lines
4.5 KiB
Markdown

# 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
1. The application provides the updater with the base server URL.
2. The updater Reads `manifest.json` and checks which files need updating.
3. If updates are available, users can choose which files to update.
4. Updated files are downloaded and the main application is relaunched.
---
## Setup
### 1. Set `MAIN_APP`
At the top of your `updater.py`, configure:
```python
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:
```bash
python3 generator.py <folder_name>
```
Example:
```bash
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 in `generator.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:
- [Nuitka](https://nuitka.net/)
- [PyInstaller](https://pyinstaller.org/)
- [cx_Freeze](https://anthony-tuininga.github.io/cx_Freeze/)
Example compilation using PyInstaller:
```bash
pyinstaller --onefile updater.py
```
---
## Integrating the Updater into Your Application
You can easily trigger the updater using the following pattern:
```python
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.