Compare commits

...

3 Commits

Author SHA1 Message Date
vanzue
b893c307f0 polish 2025-07-21 09:52:49 +08:00
vanzue
1a5bc36dd7 fix comment from copilot 2025-07-21 09:44:54 +08:00
vanzue
113054e9cb polish 2025-07-11 16:22:36 +08:00
2 changed files with 99 additions and 27 deletions

View File

@@ -4,46 +4,74 @@ Build and package PowerToys (CmdPal and installer) for a specific platform and c
.DESCRIPTION
This script automates the end-to-end build and packaging process for PowerToys, including:
- Restoring and building all necessary solutions (CmdPal, BugReportTool, StylesReportTool, etc.)
- Restoring and building all necessary solutions (CmdPal, BugReportTool, etc.)
- Cleaning up old output
- Signing generated .msix packages
- Building the WiX-based MSI and bootstrapper installers
It is designed to work in local development.
The cert used to sign the packages is generated by
.PARAMETER Platform
Specifies the target platform for the build (e.g., 'arm64', 'x64'). Default is 'arm64'.
Specifies the target platform for the build (e.g., 'arm64', 'x64'). Default is 'x64'.
.PARAMETER Configuration
Specifies the build configuration (e.g., 'Debug', 'Release'). Default is 'Release'.
.PARAMETER PerUser
Specifies whether to build a per-user installer (true) or machine-wide installer (false). Default is true (per-user).
.EXAMPLE
.\build-installer.ps1
Runs the installer build pipeline for ARM64 Release (default).
.EXAMPLE
.\build-installer.ps1 -Platform x64 -Configuration Release
Runs the pipeline for x64 Debug.
Runs the pipeline for x64 Release.
.EXAMPLE
.\build-installer.ps1 -Platform x64 -Configuration Release -PerUser false
Runs the pipeline for x64 Release with machine-wide installer.
.NOTES
- Requires MSBuild, WiX Toolset, and Git to be installed and accessible from your environment.
- Make sure to run this script from a Developer PowerShell (e.g., VS2022 Developer PowerShell).
- Generated MSIX files will be signed using cert-sign-package.ps1.
- This script will clean previous outputs under the build directories and installer directory (except *.exe files).
- First time run need admin permission to trust the certificate.
- The built installer will be placed under: installer/PowerToysSetup/[Platform]/[Configuration]/UserSetup
- The built installer will be placed under: installer/PowerToysSetup/[Platform]/[Configuration]/User[Machine]Setup
relative to the solution root directory.
- The installer can't be run right after the build, I need to copy it to another file before it can be run.
- To run the full installation in other machines, call "./cert-management.ps1" to export the cert used to sign the packages.
And trust the cert in the target machine.
#>
param (
[string]$Platform = 'arm64',
[string]$Configuration = 'Release'
[string]$Platform = 'x64',
[string]$Configuration = 'Release',
[string]$PerUser = 'true'
)
$repoRoot = Resolve-Path "$PSScriptRoot\..\.."
Set-Location $repoRoot
# Find the PowerToys repository root automatically
$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Definition
$repoRoot = $scriptDir
# Navigate up from the script location to find the repo root
# Script is typically in tools\build, so go up two levels
while ($repoRoot -and -not (Test-Path (Join-Path $repoRoot "PowerToys.sln"))) {
$parentDir = Split-Path -Parent $repoRoot
if ($parentDir -eq $repoRoot) {
# Reached the root of the drive, PowerToys.sln not found
Write-Error "Could not find PowerToys repository root. Make sure this script is in the PowerToys repository."
exit 1
}
$repoRoot = $parentDir
}
if (-not $repoRoot -or -not (Test-Path (Join-Path $repoRoot "PowerToys.sln"))) {
Write-Error "Could not locate PowerToys.sln. Please ensure this script is run from within the PowerToys repository."
exit 1
}
Write-Host "PowerToys repository root detected: $repoRoot"
function RunMSBuild {
param (
@@ -55,6 +83,7 @@ function RunMSBuild {
$Solution
"/p:Platform=`"$Platform`""
"/p:Configuration=$Configuration"
"/p:CIBuild=true"
'/verbosity:normal'
'/clp:Summary;PerformanceSummary;ErrorsOnly;WarningsOnly'
'/nologo'
@@ -62,13 +91,18 @@ function RunMSBuild {
$cmd = $base + ($ExtraArgs -split ' ')
Write-Host ("[MSBUILD] {0} {1}" -f $Solution, ($cmd -join ' '))
& msbuild.exe @cmd
if ($LASTEXITCODE -ne 0) {
Write-Error ("Build failed: {0} {1}" -f $Solution, $ExtraArgs)
exit $LASTEXITCODE
# Run MSBuild from the repository root directory
Push-Location $repoRoot
try {
& msbuild.exe @cmd
if ($LASTEXITCODE -ne 0) {
Write-Error ("Build failed: {0} {1}" -f $Solution, $ExtraArgs)
exit $LASTEXITCODE
}
} finally {
Pop-Location
}
}
function RestoreThenBuild {
@@ -81,9 +115,9 @@ function RestoreThenBuild {
}
Write-Host ("Make sure wix is installed and available")
& "$PSScriptRoot\ensure-wix.ps1"
& (Join-Path $PSScriptRoot "ensure-wix.ps1")
Write-Host ("[PIPELINE] Start | Platform={0} Configuration={1}" -f $Platform, $Configuration)
Write-Host ("[PIPELINE] Start | Platform={0} Configuration={1} PerUser={2}" -f $Platform, $Configuration, $PerUser)
Write-Host ''
$cmdpalOutputPath = Join-Path $repoRoot "$Platform\$Configuration\WinUI3Apps\CmdPal"
@@ -93,7 +127,7 @@ if (Test-Path $cmdpalOutputPath) {
Remove-Item $cmdpalOutputPath -Recurse -Force -ErrorAction Ignore
}
RestoreThenBuild '.\PowerToys.sln'
RestoreThenBuild 'PowerToys.sln'
$msixSearchRoot = Join-Path $repoRoot "$Platform\$Configuration"
$msixFiles = Get-ChildItem -Path $msixSearchRoot -Recurse -Filter *.msix |
@@ -101,22 +135,27 @@ Select-Object -ExpandProperty FullName
if ($msixFiles.Count) {
Write-Host ("[SIGN] .msix file(s): {0}" -f ($msixFiles -join '; '))
& "$PSScriptRoot\cert-sign-package.ps1" -TargetPaths $msixFiles
& (Join-Path $PSScriptRoot "cert-sign-package.ps1") -TargetPaths $msixFiles
}
else {
Write-Warning "[SIGN] No .msix files found in $msixSearchRoot"
}
RestoreThenBuild '.\tools\BugReportTool\BugReportTool.sln'
RestoreThenBuild '.\tools\StylesReportTool\StylesReportTool.sln'
RestoreThenBuild 'tools\BugReportTool\BugReportTool.sln'
RestoreThenBuild 'tools\StylesReportTool\StylesReportTool.sln'
Write-Host '[CLEAN] installer (keep *.exe)'
git clean -xfd -e '*.exe' -- .\installer\ | Out-Null
Push-Location $repoRoot
try {
git clean -xfd -e '*.exe' -- .\installer\ | Out-Null
} finally {
Pop-Location
}
RunMSBuild '.\installer\PowerToysSetup.sln' '/t:restore /p:RestorePackagesConfig=true'
RunMSBuild 'installer\PowerToysSetup.sln' '/t:restore /p:RestorePackagesConfig=true'
RunMSBuild '.\installer\PowerToysSetup.sln' '/m /t:PowerToysInstaller /p:PerUser=true'
RunMSBuild 'installer\PowerToysSetup.sln' "/m /t:PowerToysInstaller /p:PerUser=$PerUser"
RunMSBuild '.\installer\PowerToysSetup.sln' '/m /t:PowerToysBootstrapper /p:PerUser=true'
RunMSBuild 'installer\PowerToysSetup.sln' "/m /t:PowerToysBootstrapper /p:PerUser=$PerUser"
Write-Host '[PIPELINE] Completed'

View File

@@ -152,4 +152,37 @@ function Export-CertificateFiles {
if (-not $CerPath -and -not $PfxPath) {
Write-Warning "No output path specified. Nothing was exported."
}
}
# Main execution when script is run directly
if ($MyInvocation.InvocationName -ne '.') {
Write-Host "=== PowerToys Certificate Management ===" -ForegroundColor Green
Write-Host ""
# Ensure certificate exists and is trusted
Write-Host "Checking for existing certificate or creating new one..." -ForegroundColor Yellow
$cert = EnsureCertificate
if ($cert) {
# Export the certificate to a .cer file
$exportPath = Join-Path (Get-Location) "PowerToys-CodeSigning.cer"
Write-Host ""
Write-Host "Exporting certificate..." -ForegroundColor Yellow
Export-CertificateFiles -Certificate $cert -CerPath $exportPath
Write-Host ""
Write-Host "=== IMPORTANT NOTES ===" -ForegroundColor Red
Write-Host "The certificate has been exported to: $exportPath" -ForegroundColor White
Write-Host ""
Write-Host "To use this certificate for code signing, you need to:" -ForegroundColor Yellow
Write-Host "1. Import this certificate into 'Trusted People' store" -ForegroundColor White
Write-Host "2. Import this certificate into 'Trusted Root Certification Authorities' store" -ForegroundColor White
Write-Host "Certificate Details:" -ForegroundColor Green
Write-Host "Subject: $($cert.Subject)" -ForegroundColor White
Write-Host "Thumbprint: $($cert.Thumbprint)" -ForegroundColor White
Write-Host "Valid Until: $($cert.NotAfter)" -ForegroundColor White
} else {
Write-Error "Failed to create or find certificate. Please check the error messages above."
exit 1
}
}