Skip to content

Added MSIX installer creation option #1187

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 39 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
806dd66
Initial commit to new MSIX method
jmjaffe37 May 13, 2025
521e1a5
Cleaned up code, now fully able to download + sign from URL
jmjaffe37 May 13, 2025
7d0b325
Added info to README.md
jmjaffe37 May 13, 2025
5e7630e
Updated comments
jmjaffe37 May 13, 2025
b54560a
Renamed scripts
jmjaffe37 May 13, 2025
e0e54ac
Added way to name output files
jmjaffe37 May 13, 2025
39fe8cd
updated header
jmjaffe37 May 14, 2025
37f76a0
Added debug
jmjaffe37 May 14, 2025
1293a6a
readded _msix_logos
jmjaffe37 May 14, 2025
5319200
Updated headers and defaults
jmjaffe37 May 14, 2025
957653c
Updated README.md + header comments
jmjaffe37 May 14, 2025
2f4dcfb
Testing full ver num
jmjaffe37 May 14, 2025
74180cd
Removed debug
jmjaffe37 May 14, 2025
10f4ef8
Updated comments, inputs, order, and spelling
jmjaffe37 May 14, 2025
9accacf
First attempt to move to helper files and functions
jmjaffe37 May 16, 2025
765b378
Cleaned up code + fixed typos
jmjaffe37 May 16, 2025
b1928ae
Updated input order
jmjaffe37 May 16, 2025
c297ee7
Added commas back
jmjaffe37 May 16, 2025
9078a94
Added headers
jmjaffe37 May 16, 2025
d629cb2
Updated manifest file
jmjaffe37 May 16, 2025
ec05c00
Cleaned up spelling and grammar
jmjaffe37 May 16, 2025
c195025
Updated Max_TestedVersion in AppXManifest.xml file
jmjaffe37 May 16, 2025
fe670ae
Updated intro to explain windows versions needed
jmjaffe37 May 16, 2025
ead4102
Added info on MSIX Core
jmjaffe37 May 16, 2025
c55cde4
Testing verbosity
jmjaffe37 May 16, 2025
a8f4af9
Enabled verbosity and updated comments + header
jmjaffe37 May 16, 2025
27ac527
Added comments
jmjaffe37 May 16, 2025
d19e034
Ensuring error is thrown on failure
jmjaffe37 May 16, 2025
d328801
Added License specification, updated README
jmjaffe37 May 16, 2025
81b4025
Updated AppXManifest.xml to allow for running javaw from cli
jmjaffe37 May 16, 2025
7850397
Renamed Clean-targetFolder
jmjaffe37 May 16, 2025
c218625
Added jshell back
jmjaffe37 May 19, 2025
e06a2dc
Test removing visual elements
jmjaffe37 May 19, 2025
0e259e1
Now using 3 different templates
jmjaffe37 May 19, 2025
00ebded
Now ensuring input version has corresponding AppXManifest.xml template
jmjaffe37 May 19, 2025
9dc7f5c
updated Helpers.ps1
jmjaffe37 May 19, 2025
b26c9b6
Updated jdk11 appxmanifest.xml
jmjaffe37 May 20, 2025
ac3203f
Now using Appx commands in README.md
jmjaffe37 May 20, 2025
bbbd252
Updated info on the -AllUsers flag
jmjaffe37 May 20, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
306 changes: 306 additions & 0 deletions msix/CreateMsix.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,306 @@
<#
.SYNOPSIS
Script to handle a zip file by either copying it from a local location or downloading it from a URL.

.DESCRIPTION
This script automates the process of creating an MSIX package for OpenJDK distributions. It accepts either a local zip file path or a URL to a zip file (containing a zip file of the JDK binaries), extracts the contents, and prepares the necessary folder structure. The script generates an AppXManifest.xml file using provided metadata, copies required configuration files, and uses Windows SDK tools to package the files into an MSIX installer. Optionally, it can sign the resulting MSIX package if a signing certificate and password are provided. The script supports customization of package metadata such as display name, description, vendor, and output file name.

.PARAMETER ZipFilePath
Optional. The local path to a zip file to be copied and unzipped.

.PARAMETER ZipFileUrl
Optional. The URL of a zip file to be downloaded and unzipped.

.PARAMETER PackageName
Optional. The name of the package. Cannot contain spaces or underscores.
IMPORTANT: This needs to be consistent with previous releases for upgrades to work as expected
Note: The output file will be named: $PackageName.msix
If not provided, a default name will have the following format: "OpenJDK${ProductMajorVersion}U-jdk-$Arch-windows-hotspot-$ProductMajorVersion"

.PARAMETER Vendor
Optional. Default: Eclipse Adoptium

.PARAMETER VendorBranding
Optional. Helps determine default values for $MSIXDisplayName and $Description,
but goes unused if those are both provided.
Default: Eclipse Temurin

.PARAMETER MsixDisplayName
Optional. Example: "Eclipse Temurin 17.0.15+6 (x64)".
This is the display name of the MSIX package.
Default: "$VendorBranding $ProductMajorVersion.$ProductMinorVersion.$ProductMaintenanceVersion+$ProductBuildNumber ($Arch)".

.PARAMETER Description
Optional. Example: "Eclipse Temurin Development Kit with Hotspot".
Default: $VendorBranding

.PARAMETER ProductMajorVersion
Example: if the version is 17.0.15+6, this is 17

.PARAMETER ProductMinorVersion
Example: if the version is 17.0.15+6, this is 0

.PARAMETER ProductMaintenanceVersion
Example: if the version is 17.0.15+6, this is 15

.PARAMETER ProductBuildNumber
Example: if the version is 17.0.15+6, this is 6

.PARAMETER Arch
Valid architectures: x86, x64, arm, arm64, x86a64, neutral

.PARAMETER PublisherCN
Set this to everything on the right side of your `CN=` field in your .pfx file.
This may include additional fields in the name, such as 'O=...', 'L=...', 'S=...', and/or others.

.PARAMETER SigningCertPath
Optional. The path to the signing certificate (.pfx) file used to sign the package.
If not provided, the script will not sign the package.

.PARAMETER SigningPassword
Optional. The password for the signing certificate.
Only needed if the SigningCertPath is provided.

.PARAMETER OutputFileName
Optional. The name of the output file.
If not provided, a default name will be generated based of the following format:
"OpenJDK${ProductMajorVersion}U-jdk-$Arch-windows-hotspot-$ProductMajorVersion.$ProductMinorVersion.$ProductMaintenanceVersion_$ProductBuildNumber.msix"

.PARAMETER License
Optional. The URL to the license file.
Default: "https://www.gnu.org/licenses/old-licenses/lgpl-2.0.html"

.PARAMETER VerboseTools
Optional. If set to $true, the script will output verbose messages.
Default: $false

.EXAMPLE
# Only mandatory inputs are defined here
.\CreateMsix.ps1 `
-ZipFilePath "C:\path\to\file.zip" `
-PackageName "OpenJDK17U-jdk-x64-windows-hotspot" `
-PublisherCN "ExamplePublisher" `
-ProductMajorVersion 17 `
-ProductMinorVersion 0 `
-ProductMaintenanceVersion 15 `
-ProductBuildNumber 6 `
-Arch "x64" `

.EXAMPLE
# All inputs are defined here
.\CreateMsix.ps1 `
# Mandatory inputs
-ZipFileUrl "https://example.com/file.zip" `
-PackageName "OpenJDK21U-jdk-x64-windows-hotspot" `
-PublisherCN "ExamplePublisher" `
-ProductMajorVersion 21 `
-ProductMinorVersion 0 `
-ProductMaintenanceVersion 7 `
-ProductBuildNumber 6 `
-Arch "aarch64" `
# Optional inputs: These are the defaults that will be used if not specified
-Vendor "Eclipse Adoptium" `
-VendorBranding "Eclipse Temurin" `
-MsixDisplayName "Eclipse Temurin 17.0.15+6 (x64)" `
-Description "Eclipse Temurin" `
# Optional Inputs: omitting these inputs will cause their associated process to be skipped
-SigningCertPath "C:\path\to\cert.pfx"
-SigningPassword "your cert's password"
-OutputFileName "OpenJDK21U-jdk_x64_windows_hotspot_21.0.7_6.msix" `

.NOTES
Ensure that you have downloaded the Windows SDK (typically through installing Visual Studio). For more information, please see the #Dependencies section of the README.md file. After doing so, please modify the following environment variables if the defaults shown below are not correct:
$Env:WIN_SDK_FULL_VERSION = "10.0.22621.0"
$Env:WIN_SDK_MAJOR_VERSION = "10"
#>

param (
[Parameter(Mandatory = $false)]
[string]$ZipFilePath,

[Parameter(Mandatory = $false)]
[string]$ZipFileUrl,

[Parameter(Mandatory = $true)]
[string]$PackageName,

[Parameter(Mandatory = $true)]
[string]$PublisherCN,

[Parameter(Mandatory = $true)]
[int]$ProductMajorVersion,

[Parameter(Mandatory = $true)]
[int]$ProductMinorVersion,

[Parameter(Mandatory = $true)]
[int]$ProductMaintenanceVersion,

[Parameter(Mandatory = $true)]
[int]$ProductBuildNumber,

[Parameter(Mandatory = $true)]
[string]$Arch,

[Parameter(Mandatory = $false)]
[string]$Vendor = "Eclipse Adoptium",

[Parameter(Mandatory = $false)]
[string]$VendorBranding = "Eclipse Temurin",

[Parameter(Mandatory = $false)]
[string]$MsixDisplayName = "",

[Parameter(Mandatory = $false)]
[string]$OutputFileName,

[Parameter(Mandatory = $false)]
[string]$Description = "",

[Parameter(Mandatory = $false)]
[string]$SigningCertPath,

[Parameter(Mandatory = $false)]
[string]$SigningPassword,

[Parameter(Mandatory = $false)]
[string]$License = "https://www.gnu.org/licenses/old-licenses/lgpl-2.0.html",

[Parameter(Mandatory = $false)]
[Alias("v")]
[switch]$VerboseTools
)

# Get the path to msix folder (parent directory of this script)
$MsixDirPath = Split-Path -Parent $MyInvocation.MyCommand.Path

# Find and source the Helpers.ps1 script located in the scripts folder to get access to helper functions
$HelpersScriptPath = Join-Path -Path $MsixDirPath -ChildPath "scripts\Helpers.ps1"
if (-not (Test-Path -Path $HelpersScriptPath)) {
throw "Error: The Helpers.ps1 script was not found at '$HelpersScriptPath'."
}
. $HelpersScriptPath
# Validate the inputs
## Ensure that we have an AppXManifestTemplate.xml file corresponding to the provided jdk major version
ValidateMajorVersion -majorVersion $ProductMajorVersion

## Ensure that either a local zip file path or a URL is provided, but not both
ValidateZipFileInput -ZipFilePath $ZipFilePath -ZipFileUrl $ZipFileUrl
## Ensure that both or neither of the signing inputs are provided
ValidateSigningInput -SigningCertPath $SigningCertPath -SigningPassword $SigningPassword

# Set default values if optional parameters are not provided
$MsixDisplayName = SetDefaultIfEmpty `
-InputValue $MsixDisplayName `
-DefaultValue "$VendorBranding $ProductMajorVersion.$ProductMinorVersion.$ProductMaintenanceVersion+$ProductBuildNumber ($Arch)"

$Description = SetDefaultIfEmpty `
-InputValue $Description `
-DefaultValue "$VendorBranding"

$OutputFileName = SetDefaultIfEmpty `
-InputValue $OutputFileName `
-DefaultValue "OpenJDK${ProductMajorVersion}U-jdk-$Arch-windows-hotspot-$ProductMajorVersion.$ProductMinorVersion.$ProductMaintenanceVersion_$ProductBuildNumber.msix"

# Ensure SetupEnv.ps1 exists, then source it for access to functions
$SetupEnvScriptPath = Join-Path -Path $MsixDirPath -ChildPath "scripts\SetupEnv.ps1"
if (-not (Test-Path -Path $SetupEnvScriptPath)) {
throw "Error: The SetupEnv.ps1 script was not found at '$SetupEnvScriptPath'."
}
. $SetupEnvScriptPath
# Get the path to the Windows SDK tools
$WindowsSdkPath = Get-WindowsSdkPath `
-WIN_SDK_FULL_VERSION $Env:WIN_SDK_FULL_VERSION `
-WIN_SDK_MAJOR_VERSION $Env:WIN_SDK_MAJOR_VERSION `
-Arch $Arch
Write-Host "Windows SDK path: $WindowsSdkPath"

# Clean the srce, workspace, and output folders
$srcFolder = Clear-TargetFolder `
-TargetFolder (Join-Path -Path $MsixDirPath -ChildPath "src") `
-ExcludeSubfolder "_msix_logos"
$workspaceFolder = Clear-TargetFolder -TargetFolder (Join-Path -Path $MsixDirPath -ChildPath "workspace")
$outputFolder = Clear-TargetFolder -TargetFolder (Join-Path -Path $MsixDirPath -ChildPath "output")
Write-Host "Folders cleaned: $srcFolder, $workspaceFolder, $outputFolder"

# Download zip file if a URL is provided, otherwise use the local path
if ($ZipFileUrl) {
Write-Host "Downloading zip file from URL: $ZipFileUrl"
$ZipFilePath = DownloadFileFromUrl -Url $ZipFileUrl -DestinationDirectory $workspaceFolder
}
Write-Host "Using ZipFilePath: $ZipFilePath"
UnzipFile -ZipFilePath $ZipFilePath -DestinationPath $workspaceFolder

# Move contents of the unzipped file to $srcFolder
$unzippedFolder = Join-Path -Path $workspaceFolder -ChildPath (Get-ChildItem -Path $workspaceFolder -Directory | Select-Object -First 1).Name
Move-Item -Path (Join-Path -Path $unzippedFolder -ChildPath "*") -Destination $srcFolder -Force
Remove-Item -Path $unzippedFolder -Recurse -Force

$appxTemplate = Join-Path -Path $MsixDirPath -ChildPath "templates\AppXManifestTemplate${ProductMajorVersion}.xml"
$content = Get-Content -Path $appxTemplate

# Replace all instances of placeholders with the provided values
$updatedContent = $content `
-replace "\{VENDOR\}", $Vendor `
-replace "\{MSIX_DISPLAYNAME\}", $MsixDisplayName `
-replace "\{PACKAGE_NAME\}", $PackageName `
-replace "\{DESCRIPTION\}", "$Description using license: $License" `
-replace "\{PRODUCT_MAJOR_VERSION\}", $ProductMajorVersion `
-replace "\{PRODUCT_MINOR_VERSION\}", $ProductMinorVersion `
-replace "\{PRODUCT_MAINTENANCE_VERSION\}", $ProductMaintenanceVersion `
-replace "\{PRODUCT_BUILD_NUMBER\}", $ProductBuildNumber `
-replace "\{ARCH\}", $Arch `
-replace "\{PUBLISHER_CN\}", $PublisherCN


# Write the updated content to the new AppXManifest.xml file
$appxManifestPath = Join-Path -Path $srcFolder -ChildPath "AppXManifest.xml"
Set-Content -Path $appxManifestPath -Value $updatedContent
Write-Host "AppXManifest.xml created at '$appxManifestPath'"

# Copy pri_config.xml to the target folder (path from SetupEnv.ps1)
$priConfig = Join-Path -Path $MsixDirPath -ChildPath "templates\pri_config.xml"
Copy-Item -Path $priConfig -Destination $srcFolder -Force
Write-Host "pri_config.xml copied to '$srcFolder'"

# Set EXTRA_ARGS to '/v' if VerboseTools is specified
if ($VerboseTools) {
$EXTRA_ARGS = '/v'
}
else {
$EXTRA_ARGS = ''
}

# Create _resources.pri file based on pri_config.xml
& "$WindowsSdkPath\makepri.exe" new $EXTRA_ARGS `
/Overwrite `
/ProjectRoot $srcFolder `
/ConfigXml "$srcFolder\pri_config.xml" `
/OutputFile "$srcFolder\_resources.pri" `
/MappingFile appx

CheckForError -ErrorMessage "Error: makepri.exe failed to create _resources.pri file."

# Create the MSIX package
& "$WindowsSdkPath\makeappx.exe" pack $EXTRA_ARGS `
/overwrite `
/d "$srcFolder" `
/p "$outputFolder\$OutputFileName"

CheckForError -ErrorMessage "Error: makeappx.exe failed to create the MSIX package."

# Sign the MSIX package if a signing certificate is provided
if ($SigningCertPath) {
& "$WindowsSdkPath\signtool.exe" sign $EXTRA_ARGS `
/fd SHA256 `
/a `
/f $SigningCertPath `
/p "$SigningPassword" `
"$outputFolder\$OutputFileName"

CheckForError -ErrorMessage "Error: signtool.exe failed to sign the MSIX package."
Write-Host "MSIX package signed successfully."
}
else {
Write-Host "SigningCertPath not provided. Skipping signing process."
}
Loading