Skip to content

self contained executables

Cyber Official edited this page May 31, 2026 · 1 revision

Self-Contained Patch Executables

NEW FEATURE

Create standalone .exe files that embed patch data, making distribution simpler for end users.

Overview

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.

How It Works

Traditional Workflow

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

Self-Contained Workflow

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!)

Creating Self-Contained Executables

Using the CLI Generator

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-exe

Executable 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

Batch Mode

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

Technical Details

File Structure

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
└─────────────────────────────┘

Header Format (128 bytes)

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

Detection Process

When patch-apply.exe starts:

  1. Reads last 128 bytes of itself
  2. Parses header structure
  3. 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)
  4. 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
  5. If any validation fails:
    • Runs in normal mode (browse for .patch file)

File Sizes

Size Breakdown

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)

Size Optimization Tips

  1. Use compression: Always enable zstd compression

    Without compression: 50 MB + 10 MB = 60 MB
    With zstd: 50 MB + 2 MB = 52 MB
    
  2. Skip identical files: Enable "Skip identical files" option

    • Reduces patch data size
    • Only includes actual changes
  3. Higher compression level: Use level 3 or 4 for production

    • Level 3 (default): Good balance
    • Level 4: Smallest size, slower generation

Distribution

Recommended Distribution Structure

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

README.txt Example

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

User Experience

What End Users See

CLI Self-Contained Executable (Created by CLI)

  1. Download: One .exe file matching their version
  2. Run: Double-click the executable
  3. 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]:
    
  4. Choose Option: Select 1 for dry run or 2 to apply
  5. Apply: Confirm with "yes" when prompted
  6. Done: Patch applied successfully

User Benefits

  • 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

Automation Mode (Silent Flag)

Self-contained executables support silent mode for fully automated patching without user interaction. There are two ways to enable silent mode:

Method 1: Embed Silent Mode (Generator --silent Flag)

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.exe

How it works:

  • Generator's --silent flag 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

Method 2: Command-Line Silent Flag (Applier --silent)

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:\MyApp

How it works:

  • Works with any self-contained executable (doesn't need to be created with --silent)
  • User provides --silent flag 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

Comparison: Embedded vs Command-Line Silent Mode

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.

Advantages vs Traditional Patches

For End Users

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

For Developers

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

When to Use

Use Self-Contained Executables When:

  • 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

Use Traditional Patches When:

  • 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

Troubleshooting

"Failed to create executable: failed to read applier executable"

Problem: Generator can't find patch-apply.exe

Solution:

  • Ensure patch-apply.exe is in the same directory as patch-gen.exe
  • Check file hasn't been renamed or deleted
  • Verify read permissions on applier file

"Executable created but won't run"

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

"Patch size exceeds 1GB limit"

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

"Checksum mismatch (data corrupted)"

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

"No patches generated in batch mode"

Problem: Self-contained executables not created in batch mode

Solution:

  • Check patch-apply.exe exists in generator directory
  • Look for errors in log output
  • Ensure sufficient disk space (50 MB × number of patches)

Best Practices

Generation

  1. Always test: Create and test self-contained exe before distribution
  2. Both formats: Generate both traditional and self-contained versions
    • Offer self-contained as "Easy Install"
    • Provide traditional as "Advanced"
  3. Compression: Always use zstd compression to minimize final size
  4. Batch mode: Use batch mode to create all version paths at once

Distribution

  1. 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
    
  2. User instructions: Provide clear README explaining:

    • Which version user needs
    • Where to place the file
    • How to run it
    • What to expect
  3. Mirror files: Host on multiple locations

    • Primary download (fast)
    • Mirror/backup (reliability)
  4. Checksums: Provide SHA-256 checksums

    MyGame_Update_v1.0.3_from_v1.0.0.exe
    SHA256: a3d5f6b8c2e1...
    

Support

  1. Version check: Remind users to verify their current version first
  2. Close app: Instruct users to close application before patching
  3. Backup note: Remind that automatic backups are created
  4. Rollback: Explain how to restore from backup if needed

Technical Limitations

Current Limitations

  1. Windows Only: Currently only generates .exe files for Windows
  2. Fixed Base Size: Base applier is ~50 MB regardless of patch size
  3. No Streaming: Entire file must be downloaded before use
  4. Single Compression: Can't mix compression methods in one exe

Future Enhancements

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

Related Documentation

Clone this wiki locally