-
-
Notifications
You must be signed in to change notification settings - Fork 1
self contained executables
NEW FEATURE
Create standalone
.exefiles that embed patch data, making distribution simpler for end users.
Self-contained patch executables combine the patch applier and patch data into a single .exe file. End users simply download one file, drop it into their application folder, and double-click to apply the patch - no additional tools or setup required.
User downloads:
├── patch-1.0.0-to-1.0.1.patch ← Patch file
└── patch-apply.exe ← Applier tool
User must:
1. Download both files
2. Run patch-apply.exe
3. Browse for .patch file
4. Select target directory
5. Click apply
User downloads:
└── patch-1.0.0-to-1.0.1.exe ← Everything in one file
User must:
1. Download one file
2. Drop into game/app folder
3. Double-click
4. Click apply (patch is already loaded!)
You can create self-contained executables from the command line:
# Generate a single patch with self-contained executable
patch-gen --from-dir "C:\releases\1.0.0" --to-dir "C:\releases\1.0.1" --output patches --create-exe
# Using versions directory
patch-gen --versions-dir "C:\versions" --from "1.0.0" --to "1.0.1" --output patches --create-exe
# Batch mode with executables
patch-gen --versions-dir "C:\versions" --new-version "1.0.3" --output patches --create-exeExecutable Type Options:
-
Console Host Type: Uses
patch-apply.exe(interactive command-line interface)- Best for technical users or automated scenarios
- Interactive menu in terminal/console
- Supports silent mode for automation
- Available from CLI generator
CLI Self-Contained Features:
- Interactive console menu with options
- Dry-run simulation before applying
- 1GB bypass toggle in the console
- Manual target directory selection
- Same patch format and verification as traditional version
When using batch mode with the self-contained option enabled:
Input:
- versions/1.0.0/
- versions/1.0.1/
- versions/1.0.2/
- Target version: 1.0.3
Output:
patches/
├── 1.0.0-to-1.0.3.patch
├── 1.0.0-to-1.0.3.exe ← Self-contained
├── 1.0.1-to-1.0.3.patch
├── 1.0.1-to-1.0.3.exe ← Self-contained
├── 1.0.2-to-1.0.3.patch
└── 1.0.2-to-1.0.3.exe ← Self-contained
A self-contained executable consists of up to four parts:
┌─────────────────────────────┐
│ patch-apply.exe │ ← Base applier (~50 MB)
├─────────────────────────────┤
│ Compressed Patch Data │ ← Your patch (varies)
├─────────────────────────────┤
│ Sidecar Blob (optional) │ ← Chunk metadata for multi-part patches
├─────────────────────────────┤
│ 128-byte Header │ ← Metadata at end
└─────────────────────────────┘
Located at the end of the file:
| Offset | Size | Field | Description |
|---|---|---|---|
| 0-7 | 8 bytes | Magic | "CPMPATCH" identifier |
| 8-11 | 4 bytes | Version | Format version (currently 1) |
| 12-19 | 8 bytes | Stub Size | Size of applier executable |
| 20-27 | 8 bytes | Data Offset | Where patch data starts |
| 28-35 | 8 bytes | Data Size | Size of patch data |
| 36-51 | 16 bytes | Compression | Type: "zstd", "gzip", or "none" |
| 52-83 | 32 bytes | Checksum | SHA-256 of patch data |
| 84 | 1 byte | Flags | Feature flags (bit 0: silent mode) |
| 85-127 | 43 bytes | Reserved | For future use |
When patch-apply.exe starts:
- Reads last 128 bytes of itself
- Parses header structure
-
Security validations (fail-safe design):
- Validates format version (only v1 supported)
- Checks for magic bytes "CPMPATCH"
- Verifies
DataOffset == StubSize(no gaps) - Validates
StubSize + DataSize + HEADER_SIZE <= fileSize(minimum check; extra bytes allowed for sidecar data) - Ensures offsets are within file bounds
- Limits patch size to max 1 GB (prevents memory exhaustion)
- If all validations pass:
- Extracts patch data from validated offset
- Verifies SHA-256 checksum
- Decompresses if needed
- Checks Flags byte (offset 84) for embedded silent mode (bit 0)
- Loads patch into console automatically
- If silent mode embedded: Applies patch immediately without prompts
- If not silent mode: Shows interactive console menu
- If any validation fails:
- Runs in normal mode (browse for .patch file)
Base executable: ~50 MB (includes console interface)
Example patch sizes:
- Small update (10 MB changed): 50.01 MB total
- Medium update (50 MB changed): 55 MB total (with zstd)
- Large update (200 MB changed): 80 MB total (with zstd)
-
Use compression: Always enable zstd compression
Without compression: 50 MB + 10 MB = 60 MB With zstd: 50 MB + 2 MB = 52 MB -
Skip identical files: Enable "Skip identical files" option
- Reduces patch data size
- Only includes actual changes
-
Higher compression level: Use level 3 or 4 for production
- Level 3 (default): Good balance
- Level 4: Smallest size, slower generation
MyGame_Update_v1.0.3/
├── README.txt ← Instructions for users
├── patch-1.0.0-to-1.0.3.exe ← For users on 1.0.0
├── patch-1.0.1-to-1.0.3.exe ← For users on 1.0.1
├── patch-1.0.2-to-1.0.3.exe ← For users on 1.0.2
└── advanced/ ← Optional: for power users
├── patch-apply.exe ← Standalone applier
├── patch-1.0.0-to-1.0.3.patch ← Standard patch files
├── patch-1.0.1-to-1.0.3.patch
└── patch-1.0.2-to-1.0.3.patch
MyGame Update v1.0.3
EASY INSTALL (Recommended):
1. Find which version you currently have installed
2. Download the matching patch file:
- patch-1.0.0-to-1.0.3.exe if you're on v1.0.0
- patch-1.0.1-to-1.0.3.exe if you're on v1.0.1
- patch-1.0.2-to-1.0.3.exe if you're on v1.0.2
3. Place the .exe in your game folder (same location as MyGame.exe)
4. Double-click the patch .exe
5. Click "Apply Patch"
ADVANCED:
See the /advanced folder for manual patching with separate patch files.
Need help? Visit: https://support.mygame.com/updates
-
Download: One
.exefile matching their version - Run: Double-click the executable
-
Console Opens: Shows interactive menu:
============================================== CyberPatchMaker - Self-Contained Patch ============================================== === Patch Information === From Version: 1.0.0 To Version: 1.0.1 Key File: program.exe Required Hash: a3f5b2c1d4e6f8... Files Added: 15 Files Modified: 8 Files Deleted: 2 Target directory [D:\Games\MyGame]: ============================================== Options: 1. Dry Run (simulate without changes) 2. Apply Patch 3. Toggle 1GB Bypass Mode (currently: Disabled) 4. Change Target Directory 5. Specify Custom Key File 6. Exit ============================================== Select option [1-6]: - Choose Option: Select 1 for dry run or 2 to apply
- Apply: Confirm with "yes" when prompted
- Done: Patch applied successfully
- Simple: Only one file to download
- No tools needed: Everything embedded
- No confusion: Can't select wrong patch file
- Portable: Single file can be shared easily
- Safe: Still includes all verification and backup features
Self-contained executables support silent mode for fully automated patching without user interaction. There are two ways to enable silent mode:
Recommended for end-user distribution - Silent mode is built into the executable itself:
# Create executable with embedded silent mode
patch-gen --from-dir "C:\releases\1.0.0" --to-dir "C:\releases\1.0.1" --output ./patches --create-exe --silent
# User simply runs the file (no flags needed)
1.0.0-to-1.0.1.exeHow it works:
- Generator's
--silentflag embeds silent mode flag into the executable header (Flags byte, bit 0) - When the executable runs, it detects the embedded flag automatically
- Applies patch immediately without showing menu or prompts
- No command-line flags needed by end user
Benefits:
- Simplest user experience (just run the file)
- No confusion about flags or options
- Perfect for distributing to non-technical users
- User can't accidentally run in interactive mode
For flexibility - Any self-contained executable can be run in silent mode:
# Run any self-contained executable in silent mode
1.0.0-to-1.0.1.exe --silent
# Silent mode with explicit target directory
1.0.0-to-1.0.1.exe --silent --current-dir C:\MyAppHow it works:
- Works with any self-contained executable (doesn't need to be created with --silent)
- User provides
--silentflag when running the executable - Overrides interactive menu and applies patch automatically
Benefits:
- Works with existing executables
- Flexibility to choose interactive or silent mode
- Useful for scripting with standard executables
| Feature | Embedded (--silent) | Command-Line (--silent) |
|---|---|---|
| Generator Command | patch-gen --create-exe --silent ... |
patch-gen --create-exe ... |
| User Command | 1.0.0-to-1.0.1.exe |
1.0.0-to-1.0.1.exe --silent |
| Behavior | Always silent | Silent when flag provided |
| Best For | End-user distribution | Scripting/automation |
| User Control | No (always silent) | Yes (choose at runtime) |
| Simplicity | Highest (no flags) | Moderate (requires flag) |
Features (Both Methods):
- No prompts: Applies patch automatically without asking
- Default settings: Uses verify=true and backup=true
- Exit codes: Returns 0 on success, 1 on failure
- Minimal output: Only essential status messages
-
Perfect for:
- Automated deployments via scripts
- CI/CD pipelines
- Mass deployments across machines
- Task Scheduler / cron jobs
- Unattended updates
Example: PowerShell deployment script
# Deploy patch to multiple machines
$servers = @("Server1", "Server2", "Server3")
foreach ($server in $servers) {
Write-Host "Updating $server..."
& "\\share\1.2.4-to-1.2.5.exe" --silent --current-dir "\\$server\C$\MyApp"
if ($LASTEXITCODE -eq 0) {
Write-Host "✓ Success" -ForegroundColor Green
} else {
Write-Host "✗ Failed" -ForegroundColor Red
}
}Example: Task Scheduler automation
# Create scheduled task for automated patching at 2 AM
$action = New-ScheduledTaskAction `
-Execute "C:\Patches\1.2.4-to-1.2.5.exe" `
-Argument "--silent --current-dir C:\MyApp"
$trigger = New-ScheduledTaskTrigger -At 2:00AM -Daily
Register-ScheduledTask `
-TaskName "MyApp Auto-Update" `
-Action $action `
-Trigger $trigger `
-User "SYSTEM"See Applier Guide - Automation Mode for more details.
| Feature | Traditional | Self-Contained |
|---|---|---|
| Files to download | 2 (applier + patch) | 1 (exe only) |
| Setup complexity | Medium | None |
| Confusion possible | Yes (wrong patch file) | No (embedded) |
| File management | Must keep organized | Single file |
| Portability | Multi-file | Single file |
| Feature | Traditional | Self-Contained |
|---|---|---|
| Distribution | Multiple files | Clean, single file |
| Support burden | Higher (setup issues) | Lower (simpler) |
| User errors | More common | Rare |
| Bandwidth | Lower (~2-10 MB) | Higher (~50+ MB) |
| Hosting cost | Lower | Higher |
- Target audience is non-technical users
- Simplicity is more important than bandwidth
- You want to minimize support requests
- Distribution platform allows large files
- Users have reasonable internet speeds
- You want one-click update experience
- Bandwidth/hosting costs are a concern
- Target users have slow internet
- Patch files are very small (< 5 MB)
- Users are technical and prefer flexibility
- You need multiple applier versions
- Storage space is limited
Problem: Generator can't find patch-apply.exe
Solution:
- Ensure
patch-apply.exeis in the same directory aspatch-gen.exe - Check file hasn't been renamed or deleted
- Verify read permissions on applier file
Problem: Self-contained exe fails to launch
Solution:
- Check Windows doesn't block downloaded exe (right-click → Properties → Unblock)
- Verify file isn't corrupted (check file size)
- Try running from command line to see error messages
- Ensure user has execution permissions
Problem: Self-contained executable fails to load because patch data is over 1GB
Solution:
- Use CLI flag: Run executable with
patch-1.0.0-to-1.0.1.exe --ignore1gb - Note: Requires sufficient RAM to load large patch into memory
- Consider: If patch is very large, traditional separate .patch file may be better
Problem: Embedded patch data fails validation
Solution:
- Re-download the executable (file may be corrupted)
- Check antivirus didn't quarantine or modify file
- Verify download completed successfully
- Re-generate the self-contained exe
Problem: Self-contained executables not created in batch mode
Solution:
- Check
patch-apply.exeexists in generator directory - Look for errors in log output
- Ensure sufficient disk space (50 MB × number of patches)
- Always test: Create and test self-contained exe before distribution
-
Both formats: Generate both traditional and self-contained versions
- Offer self-contained as "Easy Install"
- Provide traditional as "Advanced"
- Compression: Always use zstd compression to minimize final size
- Batch mode: Use batch mode to create all version paths at once
-
Clear naming: Use descriptive names
Good: patch-1.0.0-to-1.0.3-INSTALLER.exe Better: MyGame_Update_v1.0.3_from_v1.0.0.exe -
User instructions: Provide clear README explaining:
- Which version user needs
- Where to place the file
- How to run it
- What to expect
-
Mirror files: Host on multiple locations
- Primary download (fast)
- Mirror/backup (reliability)
-
Checksums: Provide SHA-256 checksums
MyGame_Update_v1.0.3_from_v1.0.0.exe SHA256: a3d5f6b8c2e1...
- Version check: Remind users to verify their current version first
- Close app: Instruct users to close application before patching
- Backup note: Remind that automatic backups are created
- Rollback: Explain how to restore from backup if needed
-
Windows Only: Currently only generates
.exefiles for Windows - Fixed Base Size: Base applier is ~50 MB regardless of patch size
- No Streaming: Entire file must be downloaded before use
- Single Compression: Can't mix compression methods in one exe
Potential future improvements:
- Linux/Mac support (.AppImage, .app bundles)
- Progress bar during embedded patch extraction
- Custom branding/icons for generated executables
- Compression of the applier executable itself
- Delta updates for self-contained exes
- Generator Guide - Creating patches
- Applier Guide - Applying patches
- How It Works - Understanding the patch system
- Compression Guide - Optimizing patch sizes