Skip to content

Commit e3fd7d9

Browse files
authored
added windows app sdk fetching and bundling into the installer (#66)
Closes #61
1 parent da29411 commit e3fd7d9

File tree

4 files changed

+69
-8
lines changed

4 files changed

+69
-8
lines changed

Installer/Program.cs

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,9 @@ public class BootstrapperOptions : SharedOptions
116116
[Option('m', "msi-path", Required = true, HelpText = "Path to the MSI package to embed")]
117117
public string MsiPath { get; set; }
118118

119+
[Option('w', "windows-app-sdk-path", Required = true, HelpText = "Path to the Windows App Sdk package to embed")]
120+
public string WindowsAppSdkPath { get; set; }
121+
119122
public new void Validate()
120123
{
121124
base.Validate();
@@ -124,6 +127,8 @@ public class BootstrapperOptions : SharedOptions
124127
throw new ArgumentException($"Logo PNG file not found at '{LogoPng}'", nameof(LogoPng));
125128
if (!SystemFile.Exists(MsiPath))
126129
throw new ArgumentException($"MSI package not found at '{MsiPath}'", nameof(MsiPath));
130+
if (!SystemFile.Exists(WindowsAppSdkPath))
131+
throw new ArgumentException($"Windows App Sdk package not found at '{WindowsAppSdkPath}'", nameof(WindowsAppSdkPath));
127132
}
128133
}
129134

@@ -337,16 +342,11 @@ private static int BuildBundle(BootstrapperOptions opts)
337342
{
338343
opts.Validate();
339344

340-
if (!DotNetRuntimePackagePayloads.TryGetValue(opts.Platform, out var payload))
345+
if (!DotNetRuntimePackagePayloads.TryGetValue(opts.Platform, out var dotNetRuntimePayload))
341346
throw new ArgumentException($"Invalid architecture '{opts.Platform}' specified", nameof(opts.Platform));
342347

343-
// TODO: it would be nice to include the WindowsAppRuntime but
344-
// Microsoft makes it difficult to check from a regular
345-
// installer:
346-
// https://learn.microsoft.com/en-us/windows/apps/windows-app-sdk/check-windows-app-sdk-versions
347-
// https://github.com/microsoft/WindowsAppSDK/discussions/2437
348348
var bundle = new Bundle(ProductName,
349-
new ExePackage
349+
new ExePackage // .NET Runtime
350350
{
351351
PerMachine = true,
352352
// Don't uninstall the runtime when the bundle is uninstalled.
@@ -362,7 +362,28 @@ private static int BuildBundle(BootstrapperOptions opts)
362362
// anyway. The MSI will fatally exit if the runtime really isn't
363363
// available, and the user can install it themselves.
364364
Vital = false,
365-
Payloads = [payload],
365+
Payloads = [dotNetRuntimePayload],
366+
},
367+
// TODO: right now we are including the Windows App Sdk in the bundle
368+
// and always install it
369+
// Microsoft makes it difficult to check if it exists from a regular installer:
370+
// https://learn.microsoft.com/en-us/windows/apps/windows-app-sdk/check-windows-app-sdk-versions
371+
// https://github.com/microsoft/WindowsAppSDK/discussions/2437
372+
new ExePackage // Windows App Sdk
373+
{
374+
PerMachine = true,
375+
Permanent = true,
376+
Cache = PackageCacheAction.remove,
377+
// There is no license agreement for this SDK.
378+
InstallArguments = "--quiet",
379+
Vital = false,
380+
Payloads =
381+
[
382+
new ExePackagePayload
383+
{
384+
SourceFile = opts.WindowsAppSdkPath
385+
}
386+
],
366387
},
367388
new MsiPackage(opts.MsiPath)
368389
{

scripts/Get-WindowsAppSdk.ps1

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# Usage: Get-WindowsAppSdk.ps1 -arch <x64|arm64>
2+
param (
3+
[ValidateSet("x64", "arm64")]
4+
[Parameter(Mandatory = $true)]
5+
[string] $arch
6+
)
7+
8+
function Download-File([string] $url, [string] $outputPath, [string] $etagFile) {
9+
Write-Host "Downloading '$url' to '$outputPath'"
10+
# We use `curl.exe` here because `Invoke-WebRequest` is notoriously slow.
11+
& curl.exe `
12+
--progress-bar `
13+
-v `
14+
--show-error `
15+
--fail `
16+
--location `
17+
--etag-compare $etagFile `
18+
--etag-save $etagFile `
19+
--output $outputPath `
20+
$url
21+
if ($LASTEXITCODE -ne 0) { throw "Failed to download $url" }
22+
if (!(Test-Path $outputPath) -or (Get-Item $outputPath).Length -eq 0) {
23+
throw "Failed to download '$url', output file '$outputPath' is missing or empty"
24+
}
25+
}
26+
27+
# Download the Windows App Sdk binary from Microsoft for this platform if we don't have
28+
# it yet (or it's different).
29+
$windowsAppSdkMajorVersion = "1.6"
30+
$windowsAppSdkFullVersion = "1.6.250228001"
31+
$windowsAppSdkPath = Join-Path $PSScriptRoot "files\windows-app-sdk-$($arch).exe"
32+
$windowsAppSdkUri = "https://aka.ms/windowsappsdk/$($windowsAppSdkMajorVersion)/$($windowsAppSdkFullVersion)/windowsappruntimeinstall-$($arch).exe"
33+
$windowsAppSdkEtagFile = $windowsAppSdkPath + ".etag"
34+
Download-File $windowsAppSdkUri $windowsAppSdkPath $windowsAppSdkEtagFile

scripts/Publish.ps1

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,10 @@ Copy-Item $mutagenAgentsSrcPath $mutagenAgentsDestPath
175175
if ($LASTEXITCODE -ne 0) { throw "Failed to build MSI" }
176176
Add-CoderSignature $msiOutputPath
177177

178+
$getWindowsAppSdk = Join-Path $scriptRoot "Get-WindowsAppSdk.ps1"
179+
& $getWindowsAppSdk -arch $arch
180+
$windowsAppSdkPath = Join-Path $scriptRoot "files\windows-app-sdk-$($arch).exe"
181+
178182
# Build the bootstrapper
179183
& dotnet.exe run --project .\Installer\Installer.csproj -c Release -- `
180184
build-bootstrapper `
@@ -184,6 +188,7 @@ Add-CoderSignature $msiOutputPath
184188
--output-path $outputPath `
185189
--icon-file "App\coder.ico" `
186190
--msi-path $msiOutputPath `
191+
--windows-app-sdk-path $windowsAppSdkPath `
187192
--logo-png "scripts\files\logo.png"
188193
if ($LASTEXITCODE -ne 0) { throw "Failed to build bootstrapper" }
189194

scripts/files/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
mutagen-*.tar.gz
22
mutagen-*.exe
33
*.etag
4+
windows-app-sdk-*.exe

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy