# ExeBundle - Command-Line Reference **Version**: See `ExeBundle.exe license` for current version **License**: Free for non-commercial use. See LICENSE.txt for details. ## Quick Reference ```bash # Build with auto-discovery (recommended for most cases) ExeBundle.exe --exe MyApp.exe --out MyApp-Bundled.exe --auto # Build from file list ExeBundle.exe --exe MyApp.exe --filelist filelist.txt --out MyApp-Bundled.exe # Build with manual file selection ExeBundle.exe --exe MyApp.exe --out MyApp-Bundled.exe --files lib1.dll lib2.dll # Build with 32-bit loader for smaller bundle size ExeBundle.exe --exe MyApp.exe --out MyApp-Bundled.exe --auto --loader x86 # Build with custom command line and working directory ExeBundle.exe --exe MyApp.exe --out MyApp-Bundled.exe --auto \ --cmdline "{exe} --config {bundledir}\app.cfg" \ --workdir "{bundledir}" # Show license information ExeBundle.exe license ``` _Note: The `build` command is optional and can be omitted (it's the default). All examples work with or without `build` keyword._ ## Commands ### `build` (optional, default) Create a bundled executable from an application and its dependencies. **Syntax**: ```bash ExeBundle.exe [build] [options] ``` _Note: The `build` command keyword is optional. If omitted, build mode is assumed by default._ ### `license` Display ExeBundle license terms and third-party library licenses (LZ4, Zstandard). **Syntax**: ```bash ExeBundle.exe license ``` ## Build Options ### Required Options #### `-o, --out ` **Output bundled executable path** (required) Specifies the path where the bundled executable will be created. **Example**: ```bash --out MyApp-Portable.exe ``` ### Input Selection You must choose **exactly one** of these three file selection modes: #### `-a, --auto` **Auto-discover files recursively from exe directory** Automatically discovers and bundles all files in the same directory as the main executable, including subdirectories. This is the recommended mode for most applications. **How it works**: 1. Starts from the directory containing the specified `--exe` file 2. Recursively scans all subdirectories 3. Includes all regular files found 4. Excludes the main executable itself (added separately) 5. Maintains directory structure in the bundle 6. Creates a `.log` file listing all bundled files **Default Limits** (can be overridden with `--limits`): - Maximum 500 files (safe preset) - Maximum 500 MB total size (safe preset) **Example**: ```bash ExeBundle.exe --exe MyApp.exe --out Bundled.exe --auto ``` **When to use**: - Bundling complete applications with DLLs and assets - When you want everything in the app directory included - For portable application distribution **Output**: Creates a `.log` file named after the output file (e.g., `Bundled.exe.log` for `--out Bundled.exe`) containing the list of all bundled files. #### `--filelist ` **Read file list from text file** Reads the list of files to bundle from a text file. Each line specifies a file to include, as a path relative to the main executable directory. **File format**: ```text lib1.dll lib2.dll assets\icon.png config\settings.ini ``` **Example**: ```bash ExeBundle.exe --exe MyApp.exe --filelist filelist.txt --out Bundled.exe ``` **Note**: The `--exe` option is required when using `--filelist`. The file list contains only additional files to bundle (not the exe itself). **When to use**: - Selective bundling (only specific files) - Repeated builds with consistent file sets - When you need precise control over included files #### `--files ` **Manual file list (positional arguments after --)** Manually specify files to bundle as command-line arguments after the `--` separator. **Path resolution**: Paths are resolved **relative to the directory containing `--exe`**, not the current working directory. **Example**: ```bash ExeBundle.exe --exe MyApp.exe --out Bundled.exe --files lib1.dll lib2.dll config.json ``` If `MyApp.exe` is located at `C:\MyApp\bin\MyApp.exe`, then `lib1.dll` must be at `C:\MyApp\bin\lib1.dll`. **When to use**: - Quick ad-hoc bundling - Scripting scenarios where file list is dynamically generated ### Main Executable #### `-e, --exe ` **Main executable to bundle** (required) Specifies the primary executable that will be launched when the bundled executable runs. This executable must be a valid Windows PE file (.exe). This option is **always required** for all file selection modes (`--auto`, `--filelist`, or manual `--`). **Example**: ```bash --exe MyApp.exe ``` ### Compression Options #### `-c, --compression ` **Compression strategy** Controls the compression strategy applied to bundled files. Each mode uses a different algorithm optimized for the specified goal. Affects bundle size, creation time, and extraction speed. **Values**: | Mode | Algorithm | Best For | Compression | Speed | |------|-----------|----------|-------------|-------| | `none` | No compression | Already compressed files (images, videos) | None | Instant | | `fast` | Zstandard (level 1) | Quick builds, faster extraction | Good | Fast | | `balanced` | Zstandard (level 4) | General use (default) | Better | Medium | | `ultra` | Zstandard (level 12) | Smallest bundles, network distribution | Best | Slowest | **Default**: `balanced` **Examples**: ```bash # Fast build, good compression ExeBundle.exe --exe App.exe --out Bundle.exe --auto --compression fast # Smallest bundle size ExeBundle.exe --exe App.exe --out Bundle.exe --auto --compression ultra # No compression ExeBundle.exe --exe App.exe --out Bundle.exe --auto --compression none ``` **Recommendations**: - Use `balanced` for most cases (good size reduction, reasonable speed) - Use `ultra` for network distribution (minimize download size) - Use `fast` for frequent testing/iteration cycles - Use `none` if files are already compressed (images, videos, archives) **Benchmark** (FirefoxPortable 146.0.1, 146 files, 323.2 MB): | Mode | Build Time | Compression | Bundle Size | Extraction | |------|------------|-------------|-------------|------------| | `none` | 1.2 s | 0% | 323.4 MB | 473 ms | | `fast` | 1.6 s | 58.2% | 135.1 MB | 998 ms | | `balanced` | 2.4 s | 63.6% | 117.6 MB | 1050 ms | | `ultra` | 13.5 s | 66.8% | 107.3 MB | 998 ms | ### Auto-Discovery Limits #### `--limits ` **Safety limits for auto-discovery mode** Prevents accidental bundling of excessively large directory trees when using `--auto`. **Values**: | Preset | Max Files | Max Size | Use Case | |--------|-----------|----------|----------| | `safe` (default) | 500 | 500 MB | Normal applications | | `relaxed` | 2,000 | 2 GB | Large applications, game assets | | `off` | Unlimited | Unlimited | CI/controlled environments only | **Default**: `safe` **Example**: ```bash # Allow larger bundles ExeBundle.exe --exe App.exe --out Bundle.exe --auto --limits relaxed # No limits (controlled environments only) ExeBundle.exe --exe App.exe --out Bundle.exe --auto --limits off ``` **⚠ Warning about `--limits off`**: - Disables all safeguards against accidental bundling of large directory trees - **Intended for CI/CD pipelines or controlled build environments only** - In interactive use, prefer `--limits relaxed` for large applications - Risk: May bundle unexpected files (node_modules, .git, build artifacts, etc.) **Notes**: - Only applies to `--auto` mode - Limits are checked before bundling begins - Error message shows actual count/size if limits exceeded ### Loader Platform Selection #### `--loader ` **Loader platform selection** Controls which loader stub (32-bit or 64-bit) is embedded in the bundled executable. The loader is responsible for extracting and launching your application at runtime. **Values**: | Platform | Description | Use Case | |----------|-------------|----------| | `auto` (default) | Match payload bitness | Recommended for most cases | | `x86` or `32` | Force 32-bit loader | Smaller bundles (~40KB savings per bundle) | | `x64` or `64` | Force 64-bit loader | Better ARM64 performance, native appearance | **Default**: `auto` (matches the bitness of the `--exe` file) **Examples**: ```bash # Smaller bundle with 32-bit loader (works perfectly on 64-bit Windows via WoW64) ExeBundle.exe --exe MyApp64.exe --out Bundle.exe --auto --loader x86 # Force 64-bit loader for ARM64 optimization ExeBundle.exe --exe MyApp32.exe --out Bundle.exe --auto --loader x64 # Use alias format ExeBundle.exe --exe MyApp.exe --out Bundle.exe --auto --loader 32 ``` **Technical Details**: - **32-bit loaders run perfectly on 64-bit Windows** via WoW64 (Windows-on-Windows-64) emulation - **32-bit loaders can launch 64-bit applications** without any limitations - **64-bit loaders can launch 32-bit applications** without any limitations - Performance difference is negligible (loader is I/O-bound, not CPU-bound) - Size difference: ~40KB per bundle (32-bit loaders are smaller) **When to Use Each**: | Scenario | Recommended Loader | Reason | |----------|-------------------|---------| | **Default/Most cases** | `auto` | Smart default, matches expectations | | **Distribution/Download** | `x86` | Smaller bundle size for faster downloads | | **ARM64 Windows devices** | `x64` | Better performance (avoids double emulation) | | **Corporate environments** | `auto` or `x64` | Some IT policies flag 32-bit executables | **Notes**: - WoW64 overhead is ~1-2% and only affects syscalls, not I/O operations - The loader's main work is reading files and decompressing data (unaffected by bitness) - Task Manager shows the loader's bitness, not the payload's bitness - ARM64 Windows: x64 loaders run via emulation, x86 via double emulation (slower) ## Runtime Behavior (Embedded into Bundle) These **build-time options** control the runtime behavior of the bundled executable. They are **permanently embedded into the bundle** at build time and affect how it behaves when users run it. ### `--extract ` **File extraction strategy** Controls where and how files are extracted at runtime. **Values**: | Mode | Behavior | Use Case | |------|----------|----------| | `auto` (default) | Smart selection based on bundle characteristics | Recommended for most cases | | `cache` | Extract to user's temp directory with caching (survives runs) | Faster repeated launches | | `subdir` | Extract to subdirectory next to executable | Debugging, inspection | | `temp` | Extract to unique per-process temp directory (cleaned after run) | Maximum isolation, single-run | **Default**: `auto` **Examples**: ```bash # Enable persistent caching for faster repeated runs ExeBundle.exe --exe App.exe --out Bundle.exe --auto --extract cache # Extract to local subdirectory (useful for debugging) ExeBundle.exe --exe App.exe --out Bundle.exe --auto --extract subdir ``` **Cache behavior**: - Cache directory: `%ProgramData%\ExeBundle\` (admin) or `%LOCALAPPDATA%\ExeBundle\` (user) - BundleId derived from bundle content (different versions get separate cache) - Survives across runs - Files verified for integrity on each run - Can be cleared manually by user or with `/exebundle:cleanup` switch ### `--cleanup ` **Temporary file cleanup policy** Controls when extracted files are deleted. **Values**: | Policy | Behavior | Use Case | |--------|----------|----------| | `auto` (default) | Smart cleanup based on extraction mode | Recommended | | `always` | Always delete files after app exits | Maximum disk cleanliness | | `never` | Never delete extracted files | Debugging, persistence | **Default**: `auto` **Examples**: ```bash # Force cleanup even in cache mode ExeBundle.exe --exe App.exe --out Bundle.exe --auto --cleanup always # Leave files for inspection ExeBundle.exe --exe App.exe --out Bundle.exe --auto --cleanup never ``` ### `--protect ` **Extracted directory protection** Controls write-protection of the extraction directory to prevent tampering. **Values**: | Policy | Behavior | Use Case | |--------|----------|----------| | `auto` (default) | Enable protection where appropriate | Recommended | | `on` | Always protect extraction directory | Enhanced security | | `off` | Never protect (files remain writable) | Apps that modify their own files | **Default**: `auto` **Examples**: ```bash # Disable protection for apps that modify their files ExeBundle.exe --exe App.exe --out Bundle.exe --auto --protect off ``` ### `--cmdline