Single-File Executable Packaging Guide
InfiniLore.InfiniFrame.SingleFile packages an InfiniFrame application into a single-file executable while embedding:
wwwrootcontent- Native InfiniFrame runtime binaries for the selected runtime identifier (RID)
This guide covers how to use the MSBuild target, configure options, and avoid common packaging issues.
Contents
- Overview
- How It Works
- Install
- Command Syntax
- Usage Examples
- Common Patterns
- App Bootstrap Requirement
- MSBuild Target Reference
- Edge Cases and Pitfalls
Overview
Use InfiniLore.InfiniFrame.SingleFile when you want a single distributable output for an InfiniFrame app.
Compared to a regular dotnet publish, the target additionally:
- Embeds
wwwrootcontent as managed resources - Embeds native InfiniFrame runtime files (
InfiniFrame.Native.dll,WebView2Loader.dll, etc.) as managed resources - Removes unpacked sidecar files from the final publish directory
- Performs a two-pass publish to ensure all content is available before embedding
Because native files are embedded as resources, your app must initialize the runtime resolver at startup with InfiniFrameSingleFileBootstrap.Initialize().
How It Works
The InfiniFrameSingleFile MSBuild target runs a two-pass publish pipeline:
- Pass 1: Publish without single-file to generate all
wwwrootcontent, static web assets, and framework files. - Pass 2: Publish with
PublishSingleFile=true, embedding all generated content and native runtime files as embedded resources. - Cleanup: Remove unpacked
wwwroot, sidecar files (*.staticwebassets.endpoints.json,web.config), and native runtime files from the publish directory.
Install
NuGet package
dotnet add package InfiniLore.InfiniFrame.SingleFile
The package ships MSBuild .targets that are automatically imported when the package is referenced.
Build from source (for repo development)
From the repository root:
dotnet build src/InfiniFrame.SingleFile/InfiniFrame.SingleFile.csproj -c Release
No separate tool installation is required -- the targets are consumed directly via MSBuild.
Command Syntax
dotnet publish <project.csproj> -t:InfiniFrameSingleFile -r <RID> -c <Configuration>
Or set the target to auto-run after a standard publish:
dotnet publish <project.csproj> -r <RID> -c Release -p:InfiniFrameSingleFileAuto=true
Target properties
| Property | Default | Description |
|---|---|---|
-r <RID> | (required) | Target runtime identifier (e.g. win-x64, linux-arm64, osx-x64) |
-c <Configuration> | Release | Build configuration |
InfiniFrameSingleFileSelfContained | true | Self-contained publish mode |
InfiniFrameSingleFileAuto | false | Auto-run after dotnet publish |
Usage Examples
Basic publish
dotnet publish src/MyApp/MyApp.csproj -t:InfiniFrameSingleFile -r win-x64 -c Release
Publish for Linux
dotnet publish src/MyApp/MyApp.csproj -t:InfiniFrameSingleFile -r linux-x64 -c Release
Auto-run after publish
dotnet publish src/MyApp/MyApp.csproj -r win-x64 -c Release -p:InfiniFrameSingleFileAuto=true
Non-self-contained publish
dotnet publish src/MyApp/MyApp.csproj -t:InfiniFrameSingleFile -r win-x64 -c Release -p:InfiniFrameSingleFileSelfContained=false
Common Patterns
Packaging multiple RIDs
Run the publish command once per RID:
dotnet publish src/MyApp/MyApp.csproj -t:InfiniFrameSingleFile -r win-x64 -c Release
dotnet publish src/MyApp/MyApp.csproj -t:InfiniFrameSingleFile -r linux-x64 -c Release
dotnet publish src/MyApp/MyApp.csproj -t:InfiniFrameSingleFile -r osx-arm64 -c Release
CI-friendly deterministic output paths
Pass an explicit -o directory so build artifacts land in a stable path:
dotnet publish src/MyApp/MyApp.csproj -t:InfiniFrameSingleFile -r win-x64 -c Release -o artifacts/publish/MyApp
MSBuild auto-run integration
To automatically run single-file packaging as part of your build, add to your .csproj:
<PropertyGroup>
<InfiniFrameSingleFileAuto>true</InfiniFrameSingleFileAuto>
</PropertyGroup>
App Bootstrap Requirement
After publishing with InfiniLore.InfiniFrame.SingleFile, initialize the single-file bootstrap before creating a window:
using InfiniFrame;
public static class Program {
[STAThread]
public static void Main(string[] args) {
InfiniFrameSingleFileBootstrap.Initialize();
var window = InfiniFrameWindowBuilder.Create()
.SetTitle("My App")
.SetSize(1280, 720)
.Center()
.Build();
window.WaitForClose();
}
}
Why this is required:
- The publish target embeds
InfiniFrame.Nativeand platform loader files (WebView2Loader.dllon Windows) as resources. InfiniFrameSingleFileBootstrap.Initialize()extracts them to a temporary RID-specific folder and registers a native resolver so P/Invoke can load them.
Alternatively, use the higher-level InfiniFrameSingleFile.Initialize() helper which also configures embedded static web assets for Blazor apps:
using InfiniFrame.SingleFile;
public static class Program {
[STAThread]
public static void Main(string[] args) {
InfiniFrameSingleFile.Initialize();
var window = InfiniFrameWindowBuilder.Create()
.SetTitle("My App")
.SetSize(1280, 720)
.Center()
.Build();
window.WaitForClose();
}
}
MSBuild Target Reference
The InfiniFrame.SingleFile.targets file defines the following MSBuild targets:
| Target | Description |
|---|---|
InfiniFrameSingleFile | Two-pass publish for truly single-file output |
InfiniFramePackEmbedStaticWebAssets | Embeds static web assets and wwwroot content as resources |
InfiniFramePackEmbedNativeArtifacts | Embeds native runtime files (InfiniFrame.Native.dll, WebView2Loader.dll, etc.) |
InfiniFramePackCleanupPublishArtifacts | Removes sidecar files and native files from the publish directory |
InfiniFramePackGenerateConfig | Generates a module initializer to set InfiniFramePackMode.IsActive at compile time |
InfiniFrameSingleFileAuto | Auto-runs InfiniFrameSingleFile after Publish when enabled |
Pack mode detection
The targets set InfiniFramePackMode.IsActive = true via a generated module initializer when packaging is active. The InfiniFrameSingleFile library checks this flag at runtime to skip bootstrap when not in pack mode.
Edge Cases and Pitfalls
-r <RID>is required. The target fails with an error if noRuntimeIdentifieris specified.--rid autois not supported. You must specify an explicit RID (win-x64,linux-arm64,osx-x64, etc.).- The two-pass publish performs a full non-single-file publish first. Ensure your project builds successfully in non-single-file mode.
- If your project defines
TargetFrameworks(plural), the target uses the first framework entry. Pass-f <TFM>to select a specific framework. - The target requires
pwsh(PowerShell Core) to be available on the system PATH for generating the pack mode initializer. - If final output does not contain the expected single-file executable, the build may succeed but the app may fail at runtime. Verify the publish output contains the expected executable.