I've created a solution that bundles the runtime installer with your app and auto-installs it on first launch.
Location: FireStickScreenSaverEnforcer.App\Services\RuntimeBootstrapper.cs
This service:
- ? Checks if Windows App SDK Runtime is installed
- ? Prompts user to install if missing
- ? Auto-runs the bundled installer with admin elevation
- ? Restarts the app after installation
Now checks for the runtime on startup and prompts for installation if needed.
# Download the installer
$url = "https://aka.ms/windowsappsdk/1.8/latest/windowsappruntimeinstall-x64.exe"
$output = "windowsappruntimeinstall-x64.exe"
Invoke-WebRequest -Uri $url -OutFile $outputCopy windowsappruntimeinstall-x64.exe to:
FireStickScreenSaverEnforcer.App\bin\Release\net10.0-windows10.0.19041.0\win-x64\publish\
Add this to your .csproj:
<!-- Bundle Windows App SDK Runtime Installer -->
<ItemGroup>
<None Include="windowsappruntimeinstall-x64.exe" Condition="Exists('windowsappruntimeinstall-x64.exe')">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>dotnet publish -c Release -r win-x64 --self-contained true- User extracts ZIP and runs
FireStickScreenSaverEnforcer.exe - App detects missing runtime
- Shows dialog: "Windows App SDK Runtime Required"
- User clicks "Install"
- App auto-runs the bundled installer (requests admin permission)
- Installer completes (~1 minute)
- App shows "Installation Complete - Please restart"
- App restarts automatically
- App now works!
- Runtime check passes instantly
- App launches normally
- No prompts or delays
| Approach | User Experience | File Size | Complexity |
|---|---|---|---|
| Without Bundling | ? Must download separately | 99 MB | ? Simple |
| With Bundling | ? One-click install | 108 MB | ?? Medium |
| MSIX Package | ? Fully automatic | 150 MB | ??? Complex |
If you don't want to bundle the 9MB installer, you can download it on first launch:
public static async Task<bool> DownloadAndInstallRuntimeAsync()
{
const string runtimeUrl = "https://aka.ms/windowsappsdk/1.8/latest/windowsappruntimeinstall-x64.exe";
var tempPath = Path.Combine(Path.GetTempPath(), "windowsappruntimeinstall-x64.exe");
// Download
using var client = new HttpClient();
var bytes = await client.GetByteArrayAsync(runtimeUrl);
await File.WriteAllBytesAsync(tempPath, bytes);
// Install
var process = Process.Start(new ProcessStartInfo
{
FileName = tempPath,
UseShellExecute = true,
Verb = "runas"
});
await Task.Run(() => process?.WaitForExit());
return process?.ExitCode == 0;
}For v1.0.1: Bundle the installer and use the RuntimeBootstrapper I created.
Pros:
- ? One-click setup for users
- ? No separate downloads needed
- ? Professional user experience
- ? Only adds 9MB to your ZIP
Cons:
- ?? Increases ZIP size to ~108 MB (was 99 MB)
- ?? Requires admin elevation on first launch
-
Test the RuntimeBootstrapper:
# Build with the new code dotnet build # Run from Visual Studio to test the dialog
-
Download the installer:
Invoke-WebRequest -Uri "https://aka.ms/windowsappsdk/1.8/latest/windowsappruntimeinstall-x64.exe" -OutFile "FireStickScreenSaverEnforcer.App\windowsappruntimeinstall-x64.exe"
-
Update .csproj to include it in builds
-
Rebuild release:
dotnet publish -c Release -r win-x64 --self-contained true
-
Test on a clean Windows 11 PC (without runtime)
- Build completes successfully
- Runtime check works (false on clean machine)
- Dialog appears on first launch
- Installer runs with admin elevation
- App restarts after installation
- Runtime check passes after install
- App launches normally
- ZIP includes the installer EXE
Update your README/release notes:
## One-Click Setup
The app will automatically install required dependencies on first launch:
1. Extract the ZIP
2. Run FireStickScreenSaverEnforcer.exe
3. Click "Install" when prompted (requires administrator permission)
4. App will restart and work normally
No manual downloads or configuration needed!Your app will now have a professional, seamless setup experience! ??