Remove MSI from publishing pipeline (#27213)

Co-authored-by: Justin Chung <chungjustin@microsoft.com>
Co-authored-by: Aditya Patwardhan <adityap@microsoft.com>
This commit is contained in:
Justin Chung
2026-04-16 15:01:35 -04:00
committed by GitHub
co-authored by Justin Chung Aditya Patwardhan
parent 30d14eafaa
commit 72be78e6be
24 changed files with 53 additions and 1746 deletions
+4 -12
View File
@@ -91,7 +91,7 @@ To run the link-checker, follow these steps:
1. Issues marked as [`First-Time-Issue`][first-time-issue],
are identified as being easy and a great way to learn about this project and making
contributions.
### Finding or creating an issue
1. Follow the instructions in [Contributing to Issues][contribute-issues] to find or open an issue.
@@ -264,18 +264,10 @@ Please see PowerShell [Testing Guidelines - Running Tests Outside of CI][running
* Our CI contains automated spell checking and link checking for Markdown files. If there is any false-positive,
[run the spell checker command-line tool in interactive mode](#spell-checking-documentation)
to add words to the `.spelling` file.
* Our packaging test may not pass and ask you to update `files.wxs` file if you add/remove/update nuget package references or add/remove assert files.
You could update the file manually in accordance with messages in the test log file. Or you can use automatically generated file. To get the file you should build the msi package locally:
```powershell
Import-Module .\build.psm1
Start-PSBuild -Clean -CrossGen -PSModuleRestore -Runtime win7-x64 -Configuration Release -ReleaseTag <release tag>
Import-Module .\tools\packaging
Start-PSPackage -Type msi -ReleaseTag <release tag> -WindowsRuntime 'win7-x64' -SkipReleaseChecks
```
Last command will report where new file is located.
You could update the `.spelling` file manually in accordance with messages in the test log file, or
[run the spell checker command-line tool in interactive mode](#spell-checking-documentation)
to add the false-positive words directly.
#### Pull Request - Workflow
@@ -83,7 +83,7 @@ PowerShell code in GitHub Actions YAML files should be kept minimal. Move code t
**Examples**:
- `Start-PSPackage` - Create packages
- `New-MSIPackage` - Create Windows MSI
- `New-MSIXPackage` - Create Windows MSIX
- `New-DotnetSdkContainerFxdPackage` - Create container packages
**When NOT to use**:
@@ -161,9 +161,9 @@ jobs:
}
$packageTypes = switch ($runtime) {
'x64' { @('msi', 'zip', 'msix') }
'x86' { @('msi', 'zip', 'msix') }
'arm64' { @('msi', 'zip', 'msix') }
'x64' { @('zip', 'msix') }
'x86' { @('zip', 'msix') }
'arm64' { @('zip', 'msix') }
'fxdependent' { 'fxdependent' }
'fxdependentWinDesktop' { 'fxdependent-win-desktop' }
'minsize' { 'min-size' }
@@ -193,9 +193,9 @@ jobs:
Write-Verbose -Verbose "runtime = '$(Runtime)'"
$packageTypes = switch ($runtime) {
'x64' { @('msi', 'zip', 'msix') }
'x86' { @('msi', 'zip', 'msix') }
'arm64' { @('msi', 'zip', 'msix') }
'x64' { @('zip', 'msix') }
'x86' { @('zip', 'msix') }
'arm64' { @('zip', 'msix') }
'fxdependent' { 'fxdependent' }
'fxdependentWinDesktop' { 'fxdependent-win-desktop' }
'minsize' { 'min-size' }
@@ -205,13 +205,6 @@ jobs:
New-Item -ItemType Directory -Path $(ob_outputDirectory) -Force
}
if ($packageTypes -contains 'msi') {
$msiPkgNameFilter = "powershell-*.msi"
$msiPkgPath = Get-ChildItem -Path $(Pipeline.Workspace) -Filter $msiPkgNameFilter -Recurse -File | Select-Object -ExpandProperty FullName
Write-Verbose -Verbose "unsigned msiPkgPath: $msiPkgPath"
Copy-Item -Path $msiPkgPath -Destination '$(ob_outputDirectory)' -Force -Verbose
}
if ($packageTypes -contains 'zip' -or $packageTypes -contains 'fxdependent' -or $packageTypes -contains 'min-size' -or $packageTypes -contains 'fxdependent-win-desktop') {
$zipPkgNameFilter = "powershell-*.zip"
$zipPkgPath = Get-ChildItem -Path $(Pipeline.Workspace) -Filter $zipPkgNameFilter -Recurse -File | Select-Object -ExpandProperty FullName
+5 -104
View File
@@ -67,110 +67,25 @@ jobs:
- template: /.pipelines/templates/install-dotnet.yml@self
# Import build.psm1 and bootstrap packaging dependencies (WiX Toolset)
# Import build.psm1 and bootstrap packaging dependencies
- pwsh: |
$repoRoot = "$env:REPOROOT"
Import-Module "$repoRoot\build.psm1"
Import-Module "$repoRoot\tools\packaging"
Write-Verbose -Verbose "Modules imported successfully"
# Install WiX Toolset for EXE package creation
$isArm64 = '$(Runtime)' -eq 'arm64'
$env:RUNTIME = '$(Runtime)'
Start-PSBootstrap -Scenario Package
displayName: 'Import modules and install WiX Toolset'
displayName: 'Import modules'
env:
ob_restore_phase: true
# Sign MSI packages
- task: onebranch.pipeline.signing@1
displayName: Sign MSI packages
inputs:
command: 'sign'
signing_profile: external_distribution
files_to_sign: '**\*.msi'
search_root: '$(Pipeline.Workspace)'
# Create EXE package from signed MSI (for x64, x86, arm64 only)
- pwsh: |
$runtime = '$(Runtime)'
Write-Verbose -Verbose "runtime = '$(Runtime)'"
$repoRoot = "$env:REPOROOT"
Import-Module "$repoRoot\build.psm1"
Import-Module "$repoRoot\tools\packaging"
$noExeRuntimes = @('fxdependent', 'fxdependentWinDesktop', 'minsize')
if ($runtime -in $noExeRuntimes) {
Write-Verbose -Verbose "No EXE generated for $runtime"
return
}
$version = '$(Version)'
$msiLocation = Get-ChildItem -Path $(Pipeline.Workspace) -Recurse -Filter "powershell-*$runtime.msi" | Select-Object -ExpandProperty FullName
Write-Verbose -Verbose "msiLocation: $msiLocation"
Set-Location $repoRoot
$exePath = New-ExePackage -ProductVersion $version -ProductTargetArchitecture $runtime -MsiLocationPath $msiLocation
Write-Verbose -Verbose "setting vso[task.setvariable variable=exePath]$exePath"
Write-Host "##vso[task.setvariable variable=exePath]$exePath"
Write-Verbose -Verbose "exePath: $exePath"
$enginePath = Join-Path -Path '$(System.ArtifactsDirectory)\unsignedEngine' -ChildPath engine.exe
Expand-ExePackageEngine -ExePath $exePath -EnginePath $enginePath -ProductTargetArchitecture $runtime
displayName: 'Make exe and expand package'
# Sign EXE engine
- task: onebranch.pipeline.signing@1
displayName: Sign exe engine
inputs:
command: 'sign'
signing_profile: $(msft_3rd_party_cert_id)
files_to_sign: '$(System.ArtifactsDirectory)\unsignedEngine\*.exe'
search_root: '$(Pipeline.Workspace)'
# Compress signed EXE engine back into package
- pwsh: |
$runtime = '$(Runtime)'
Write-Verbose -Verbose "runtime = '$(Runtime)'"
$repoRoot = "$env:REPOROOT"
Import-Module "$repoRoot\build.psm1"
Import-Module "$repoRoot\tools\packaging"
$noExeRuntimes = @('fxdependent', 'fxdependentWinDesktop', 'minsize')
if ($runtime -in $noExeRuntimes) {
Write-Verbose -Verbose "No EXE generated for $runtime"
return
}
$exePath = '$(exePath)'
$enginePath = Join-Path -Path '$(System.ArtifactsDirectory)\unsignedEngine' -ChildPath engine.exe
$enginePath | Get-AuthenticodeSignature | out-string | Write-Verbose -verbose
Compress-ExePackageEngine -ExePath $exePath -EnginePath $enginePath -ProductTargetArchitecture $runtime
displayName: Compress signed exe package
# Sign final EXE packages
- task: onebranch.pipeline.signing@1
displayName: Sign exe packages
inputs:
command: 'sign'
signing_profile: external_distribution
files_to_sign: '**\*.exe'
search_root: '$(Pipeline.Workspace)'
# Copy all signed packages to output directory
- pwsh: |
$runtime = '$(Runtime)'
Write-Verbose -Verbose "runtime = '$(Runtime)'"
$packageTypes = switch ($runtime) {
'x64' { @('msi', 'zip', 'msix', 'exe') }
'x86' { @('msi', 'zip', 'msix', 'exe') }
'arm64' { @('msi', 'zip', 'msix', 'exe') }
'x64' { @('zip', 'msix') }
'x86' { @('zip', 'msix') }
'arm64' { @('zip', 'msix') }
'fxdependent' { 'fxdependent' }
'fxdependentWinDesktop' { 'fxdependent-win-desktop' }
'minsize' { 'min-size' }
@@ -180,20 +95,6 @@ jobs:
New-Item -ItemType Directory -Path $(ob_outputDirectory) -Force
}
if ($packageTypes -contains 'msi') {
$msiPkgNameFilter = "powershell-*.msi"
$msiPkgPath = Get-ChildItem -Path $(Pipeline.Workspace) -Filter $msiPkgNameFilter -Recurse -File | Select-Object -ExpandProperty FullName
Write-Verbose -Verbose "signed msiPkgPath: $msiPkgPath"
Copy-Item -Path $msiPkgPath -Destination '$(ob_outputDirectory)' -Force -Verbose
}
if ($packageTypes -contains 'exe') {
$exePkgNameFilter = "powershell-*.exe"
$exePkgPath = Get-ChildItem -Path $(Pipeline.Workspace) -Filter $exePkgNameFilter -Recurse -File | Select-Object -ExpandProperty FullName
Write-Verbose -Verbose "signed exePkgPath: $exePkgPath"
Copy-Item -Path $exePkgPath -Destination '$(ob_outputDirectory)' -Force -Verbose
}
if ($packageTypes -contains 'zip' -or $packageTypes -contains 'fxdependent' -or $packageTypes -contains 'min-size' -or $packageTypes -contains 'fxdependent-win-desktop') {
$zipPkgNameFilter = "powershell-*.zip"
$zipPkgPath = Get-ChildItem -Path $(Pipeline.Workspace) -Filter $zipPkgNameFilter -Recurse -File | Select-Object -ExpandProperty FullName
@@ -43,6 +43,13 @@ jobs:
$exefiles | Remove-Item -Force -Verbose
}
# The .msi packages should not be uploaded to GitHub release.
$msifiles = Get-ChildItem -Path $Path -Filter *.msi
if ($msifiles) {
Write-Verbose -Verbose "Remove .msi packages:"
$msifiles | Remove-Item -Force -Verbose
}
$OutputPath = Join-Path $Path 'hashes.sha256'
$packages = Get-ChildItem -Path $Path -Include * -Recurse -File
$checksums = $packages |
@@ -94,8 +94,8 @@ jobs:
- pwsh: |
$message = @()
Get-ChildItem $(System.ArtifactsDirectory)\* -recurse -include *.zip, *.msi | ForEach-Object {
if($_.Name -notmatch 'PowerShell-\d+\.\d+\.\d+\-([a-z]*.\d+\-)?win\-(fxdependent|x64|arm64|x86|fxdependentWinDesktop)\.(msi|zip){1}')
Get-ChildItem $(System.ArtifactsDirectory)\* -recurse -include *.zip | ForEach-Object {
if($_.Name -notmatch 'PowerShell-\d+\.\d+\.\d+\-([a-z]*.\d+\-)?win\-(fxdependent|x64|arm64|x86|fxdependentWinDesktop)\.(zip){1}')
{
$messageInstance = "$($_.Name) is not a valid package name"
$message += $messageInstance
@@ -104,7 +104,7 @@ jobs:
}
if($message.count -gt 0){throw ($message | out-string)}
displayName: Validate Zip and MSI Package Names
displayName: Validate Zip Package Names
- pwsh: |
$message = @()
+7 -13
View File
@@ -149,10 +149,8 @@ jobs:
buildType: 'current'
artifact: drop_windows_package_package_win_arm64
itemPattern: |
**/*.msi
**/*.msix
**/*.zip
**/*.exe
targetPath: '$(Build.ArtifactStagingDirectory)/downloads'
displayName: Download windows arm64 packages
@@ -185,10 +183,8 @@ jobs:
buildType: 'current'
artifact: drop_windows_package_package_win_x64
itemPattern: |
**/*.msi
**/*.msix
**/*.zip
**/*.exe
targetPath: '$(Build.ArtifactStagingDirectory)/downloads'
displayName: Download windows x64 packages
@@ -197,10 +193,8 @@ jobs:
buildType: 'current'
artifact: drop_windows_package_package_win_x86
itemPattern: |
**/*.msi
**/*.msix
**/*.zip
**/*.exe
targetPath: '$(Build.ArtifactStagingDirectory)/downloads'
displayName: Download windows x86 packages
@@ -246,17 +240,17 @@ jobs:
- pwsh: |
Write-Verbose -Verbose "Copying Github Release files in $(Build.ArtifactStagingDirectory)/downloads to use in Release Pipeline"
Write-Verbose -Verbose "Creating output directory for GitHub Release files: $(ob_outputDirectory)/GitHubPackages"
New-Item -Path $(ob_outputDirectory)/GitHubPackages -ItemType Directory -Force
Get-ChildItem -Path "$(Build.ArtifactStagingDirectory)/downloads/*" -Recurse |
Where-Object { $_.Extension -notin '.msix', '.nupkg' -and $_.Name -notmatch '-gc'} |
Get-ChildItem -Path "$(Build.ArtifactStagingDirectory)/downloads/*" -Recurse |
Where-Object { $_.Extension -notin '.msix', '.nupkg' -and $_.Name -notmatch '-gc'} |
Copy-Item -Destination $(ob_outputDirectory)/GitHubPackages -Recurse -Verbose
Write-Verbose -Verbose "Creating output directory for NuGet packages: $(ob_outputDirectory)/NuGetPackages"
New-Item -Path $(ob_outputDirectory)/NuGetPackages -ItemType Directory -Force
Get-ChildItem -Path "$(Build.ArtifactStagingDirectory)/downloads/*" -Recurse |
Where-Object { $_.Extension -eq '.nupkg' } |
Get-ChildItem -Path "$(Build.ArtifactStagingDirectory)/downloads/*" -Recurse |
Where-Object { $_.Extension -eq '.nupkg' } |
Copy-Item -Destination $(ob_outputDirectory)/NuGetPackages -Recurse -Verbose
displayName: Copy downloads to Artifacts
@@ -395,7 +389,7 @@ jobs:
}
# To use -Include parameter, we need to use \* to get all files
$files = Get-ChildItem -Path $downloadsDirectory\* -Include @("*.deb", "*.tar.gz", "*.rpm", "*.msi", "*.zip", "*.pkg")
$files = Get-ChildItem -Path $downloadsDirectory\* -Include @("*.deb", "*.tar.gz", "*.rpm", "*.zip", "*.pkg")
Write-Verbose -Verbose "files to upload."
$files | Write-Verbose -Verbose
@@ -1,70 +0,0 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
param(
[ValidateSet('Hang', 'Fail')]
$TestHook
)
$waitTimeoutSeconds = 300
switch ($TestHook) {
'Hang' {
$waitTimeoutSeconds = 10
$jobScript = { Start-Sleep -Seconds 600 }
}
'Fail' {
$jobScript = { throw "This job script should fail" }
}
default {
$jobScript = {
# This registers Microsoft Update via a predefined GUID with the Windows Update Agent.
# https://learn.microsoft.com/windows/win32/wua_sdk/opt-in-to-microsoft-update
$serviceManager = (New-Object -ComObject Microsoft.Update.ServiceManager)
$isRegistered = $serviceManager.QueryServiceRegistration('7971f918-a847-4430-9279-4a52d1efe18d').Service.IsRegisteredWithAu
if (!$isRegistered) {
Write-Verbose -Verbose "Opting into Microsoft Update as the Automatic Update Service"
# 7 is the combination of asfAllowPendingRegistration, asfAllowOnlineRegistration, asfRegisterServiceWithAU
# AU means Automatic Updates
$null = $serviceManager.AddService2('7971f918-a847-4430-9279-4a52d1efe18d', 7, '')
}
else {
Write-Verbose -Verbose "Microsoft Update is already registered for Automatic Updates"
}
$isRegistered = $serviceManager.QueryServiceRegistration('7971f918-a847-4430-9279-4a52d1efe18d').Service.IsRegisteredWithAu
# Return if it was successful, which is the opposite of Pending.
return $isRegistered
}
}
}
Write-Verbose "Running job script: $jobScript" -Verbose
$job = Start-ThreadJob -ScriptBlock $jobScript
Write-Verbose "Waiting on Job for $waitTimeoutSeconds seconds" -Verbose
$null = Wait-Job -Job $job -Timeout $waitTimeoutSeconds
if ($job.State -ne 'Running') {
Write-Verbose "Job finished. State: $($job.State)" -Verbose
$result = Receive-Job -Job $job -Verbose
Write-Verbose "Result: $result" -Verbose
if ($result) {
Write-Verbose "Registration succeeded" -Verbose
exit 0
}
else {
Write-Verbose "Registration failed" -Verbose
# at the time this was written, the MSI is ignoring the exit code
exit 1
}
}
else {
Write-Verbose "Job timed out" -Verbose
Write-Verbose "Stopping Job. State: $($job.State)" -Verbose
Stop-Job -Job $job
# at the time this was written, the MSI is ignoring the exit code
exit 258
}
-206
View File
@@ -1,206 +0,0 @@
{\rtf1\adeflang1025\ansi\ansicpg1252\uc1\adeff0\deff0\stshfdbch0\stshfloch31506\stshfhich31506\stshfbi31506\deflang1033\deflangfe1033\themelang1033\themelangfe0\themelangcs0{\fonttbl{\f0\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f34\fbidi \froman\fcharset0\fprq2{\*\panose 02040503050406030204}Cambria Math;}
{\f37\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0502020204030204}Calibri;}{\flomajor\f31500\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}
{\fdbmajor\f31501\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fhimajor\f31502\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0302020204030204}Calibri Light;}
{\fbimajor\f31503\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\flominor\f31504\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}
{\fdbminor\f31505\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fhiminor\f31506\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0502020204030204}Calibri;}
{\fbiminor\f31507\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f1032\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\f1033\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}
{\f1035\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\f1036\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\f1037\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}
{\f1038\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\f1039\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\f1040\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}
{\f1372\fbidi \froman\fcharset238\fprq2 Cambria Math CE;}{\f1373\fbidi \froman\fcharset204\fprq2 Cambria Math Cyr;}{\f1375\fbidi \froman\fcharset161\fprq2 Cambria Math Greek;}{\f1376\fbidi \froman\fcharset162\fprq2 Cambria Math Tur;}
{\f1379\fbidi \froman\fcharset186\fprq2 Cambria Math Baltic;}{\f1380\fbidi \froman\fcharset163\fprq2 Cambria Math (Vietnamese);}{\f1402\fbidi \fswiss\fcharset238\fprq2 Calibri CE;}{\f1403\fbidi \fswiss\fcharset204\fprq2 Calibri Cyr;}
{\f1405\fbidi \fswiss\fcharset161\fprq2 Calibri Greek;}{\f1406\fbidi \fswiss\fcharset162\fprq2 Calibri Tur;}{\f1407\fbidi \fswiss\fcharset177\fprq2 Calibri (Hebrew);}{\f1408\fbidi \fswiss\fcharset178\fprq2 Calibri (Arabic);}
{\f1409\fbidi \fswiss\fcharset186\fprq2 Calibri Baltic;}{\f1410\fbidi \fswiss\fcharset163\fprq2 Calibri (Vietnamese);}{\flomajor\f31508\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}
{\flomajor\f31509\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\flomajor\f31511\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\flomajor\f31512\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}
{\flomajor\f31513\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\flomajor\f31514\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\flomajor\f31515\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}
{\flomajor\f31516\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fdbmajor\f31518\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fdbmajor\f31519\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}
{\fdbmajor\f31521\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fdbmajor\f31522\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fdbmajor\f31523\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}
{\fdbmajor\f31524\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fdbmajor\f31525\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fdbmajor\f31526\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}
{\fhimajor\f31528\fbidi \fswiss\fcharset238\fprq2 Calibri Light CE;}{\fhimajor\f31529\fbidi \fswiss\fcharset204\fprq2 Calibri Light Cyr;}{\fhimajor\f31531\fbidi \fswiss\fcharset161\fprq2 Calibri Light Greek;}
{\fhimajor\f31532\fbidi \fswiss\fcharset162\fprq2 Calibri Light Tur;}{\fhimajor\f31533\fbidi \fswiss\fcharset177\fprq2 Calibri Light (Hebrew);}{\fhimajor\f31534\fbidi \fswiss\fcharset178\fprq2 Calibri Light (Arabic);}
{\fhimajor\f31535\fbidi \fswiss\fcharset186\fprq2 Calibri Light Baltic;}{\fhimajor\f31536\fbidi \fswiss\fcharset163\fprq2 Calibri Light (Vietnamese);}{\fbimajor\f31538\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}
{\fbimajor\f31539\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fbimajor\f31541\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fbimajor\f31542\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}
{\fbimajor\f31543\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fbimajor\f31544\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fbimajor\f31545\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}
{\fbimajor\f31546\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\flominor\f31548\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\flominor\f31549\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}
{\flominor\f31551\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\flominor\f31552\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\flominor\f31553\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}
{\flominor\f31554\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\flominor\f31555\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\flominor\f31556\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}
{\fdbminor\f31558\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fdbminor\f31559\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fdbminor\f31561\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}
{\fdbminor\f31562\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fdbminor\f31563\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fdbminor\f31564\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}
{\fdbminor\f31565\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fdbminor\f31566\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fhiminor\f31568\fbidi \fswiss\fcharset238\fprq2 Calibri CE;}
{\fhiminor\f31569\fbidi \fswiss\fcharset204\fprq2 Calibri Cyr;}{\fhiminor\f31571\fbidi \fswiss\fcharset161\fprq2 Calibri Greek;}{\fhiminor\f31572\fbidi \fswiss\fcharset162\fprq2 Calibri Tur;}
{\fhiminor\f31573\fbidi \fswiss\fcharset177\fprq2 Calibri (Hebrew);}{\fhiminor\f31574\fbidi \fswiss\fcharset178\fprq2 Calibri (Arabic);}{\fhiminor\f31575\fbidi \fswiss\fcharset186\fprq2 Calibri Baltic;}
{\fhiminor\f31576\fbidi \fswiss\fcharset163\fprq2 Calibri (Vietnamese);}{\fbiminor\f31578\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fbiminor\f31579\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}
{\fbiminor\f31581\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fbiminor\f31582\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fbiminor\f31583\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}
{\fbiminor\f31584\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fbiminor\f31585\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fbiminor\f31586\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}}
{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;
\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;\red0\green0\blue0;\red0\green0\blue0;\chyperlink\ctint255\cshade255\red5\green99\blue193;\red96\green94\blue92;\red225\green223\blue221;}
{\*\defchp \f31506\fs24 }{\*\defpap \ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 }\noqfpromote {\stylesheet{\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1
\af0\afs24\alang1025 \ltrch\fcs0 \f31506\fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \snext0 \sqformat \spriority0 Normal;}{\*\cs10 \additive \sunhideused \spriority1 Default Paragraph Font;}{\*
\ts11\tsrowd\trftsWidthB3\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\trcbpat1\trcfpat1\tblind0\tblindtype3\tsvertalt\tsbrdrt\tsbrdrl\tsbrdrb\tsbrdrr\tsbrdrdgl\tsbrdrdgr\tsbrdrh\tsbrdrv
\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af31506\afs24\alang1025 \ltrch\fcs0 \f31506\fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \snext11 \ssemihidden \sunhideused Normal Table;}{\*
\cs15 \additive \rtlch\fcs1 \af0 \ltrch\fcs0 \ul\cf19 \sbasedon10 \sunhideused \styrsid11998831 Hyperlink;}{\*\cs16 \additive \rtlch\fcs1 \af0 \ltrch\fcs0 \cf20\chshdng0\chcfpat0\chcbpat21 \sbasedon10 \ssemihidden \sunhideused \styrsid11998831
Unresolved Mention;}{\s17\ql \li0\ri0\sb100\sa100\sbauto1\saauto1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs24\alang1025 \ltrch\fcs0 \fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033
\sbasedon0 \snext17 \ssemihidden \sunhideused \styrsid11998831 Normal (Web);}}{\*\pgptbl {\pgp\ipgp0\itap0\li0\ri0\sb0\sa0}{\pgp\ipgp0\itap0\li0\ri0\sb0\sa0}{\pgp\ipgp0\itap0\li0\ri0\sb0\sa0}}{\*\rsidtbl \rsid203718\rsid534261\rsid10121125\rsid11155465
\rsid11998831\rsid15422468\rsid15613908}{\mmathPr\mmathFont34\mbrkBin0\mbrkBinSub0\msmallFrac0\mdispDef1\mlMargin0\mrMargin0\mdefJc1\mwrapIndent1440\mintLim0\mnaryLim1}{\info{\author Travis Plunk}{\operator Travis Plunk}
{\creatim\yr2021\mo2\dy19\hr9\min23}{\revtim\yr2021\mo2\dy19\hr12\min33}{\version4}{\edmins5}{\nofpages1}{\nofwords75}{\nofchars430}{\nofcharsws504}{\vern6021}}{\*\xmlnstbl {\xmlns1 http://schemas.microsoft.com/office/word/2003/wordml}}
\paperw12240\paperh15840\margl1440\margr1440\margt1440\margb1440\gutter0\ltrsect
\widowctrl\ftnbj\aenddoc\trackmoves0\trackformatting1\donotembedsysfont1\relyonvml0\donotembedlingdata0\grfdocevents0\validatexml1\showplaceholdtext0\ignoremixedcontent0\saveinvalidxml0\showxmlerrors1\noxlattoyen
\expshrtn\noultrlspc\dntblnsbdb\nospaceforul\formshade\horzdoc\dgmargin\dghspace180\dgvspace180\dghorigin1440\dgvorigin1440\dghshow1\dgvshow1
\jexpand\viewkind1\viewscale100\pgbrdrhead\pgbrdrfoot\splytwnine\ftnlytwnine\htmautsp\nolnhtadjtbl\useltbaln\alntblind\lytcalctblwd\lyttblrtgr\lnbrkrule\nobrkwrptbl\snaptogridincell\allowfieldendsel\wrppunct
\asianbrkrule\rsidroot11998831\newtblstyruls\nogrowautofit\usenormstyforlist\noindnmbrts\felnbrelev\nocxsptable\indrlsweleven\noafcnsttbl\afelev\utinl\hwelev\spltpgpar\notcvasp\notbrkcnstfrctbl\notvatxbx\krnprsnet\cachedcolbal \nouicompat \fet0
{\*\wgrffmtfilter 2450}\nofeaturethrottle1\ilfomacatclnup0\ltrpar \sectd \ltrsect\linex0\endnhere\sectlinegrid360\sectdefaultcl\sftnbj {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang
{\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang {\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang
{\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}
\pard\plain \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid15422468 \rtlch\fcs1 \af0\afs24\alang1025 \ltrch\fcs0 \f31506\fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af0
\ltrch\fcs0 \insrsid15422468\charrsid15422468 This application is licensed under the\~}{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid11155465 HYPERLINK "https://aka.ms/PowerShellLicense"}{\rtlch\fcs1 \af0 \ltrch\fcs0
\insrsid11155465\charrsid15422468 {\*\datafield
00d0c9ea79f9bace118c8200aa004ba90b0200000003000000e0c9ea79f9bace118c8200aa004ba90b5a000000680074007400700073003a002f002f0061006b0061002e006d0073002f0050006f007700650072005300680065006c006c004c006900630065006e00730065000000795881f43b1d7f48af2c825dc4852763
0000000085ab000000}}}{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs15\ul\cf19\insrsid15422468\charrsid15422468 MIT License}}}\sectd \ltrsect\linex0\endnhere\sectlinegrid360\sectdefaultcl\sftnbj {\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid15422468\charrsid15422468
.
\par You may review the\~}{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid11155465 HYPERLINK "https://aka.ms/PowerShellThirdPartyNotices"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid11155465\charrsid15422468 {\*\datafield
00d0c9ea79f9bace118c8200aa004ba90b0200000003000000e0c9ea79f9bace118c8200aa004ba90b6e000000680074007400700073003a002f002f0061006b0061002e006d0073002f0050006f007700650072005300680065006c006c0054006800690072006400500061007200740079004e006f007400690063006500
73000000795881f43b1d7f48af2c825dc48527630000000085ab000000}}}{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs15\ul\cf19\insrsid15422468\charrsid15422468 ThirdPartyNotices}}}\sectd \ltrsect\linex0\endnhere\sectlinegrid360\sectdefaultcl\sftnbj {\rtlch\fcs1 \af0
\ltrch\fcs0 \insrsid15422468\charrsid15422468 .
\par }\pard \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid15422468\charrsid15422468 This application collects telemetry under the\~}{\field\fldedit{\*\fldinst {\rtlch\fcs1
\af0 \ltrch\fcs0 \insrsid534261 HYPERLINK "https://aka.ms/PrivacyPolicy"}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid534261 {\*\datafield
00d0c9ea79f9bace118c8200aa004ba90b0200000003000000e0c9ea79f9bace118c8200aa004ba90b52000000680074007400700073003a002f002f0061006b0061002e006d0073002f00500072006900760061006300790050006f006c006900630079000000795881f43b1d7f48af2c825dc48527630000000085ab0000}
}}{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs15\ul\cf19\insrsid15422468\charrsid15422468 Microsoft Privacy Statement}}}\sectd \ltrsect\linex0\endnhere\sectlinegrid360\sectdefaultcl\sftnbj {\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid15422468\charrsid15422468
. To opt out, see\~}{\field\fldedit{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid11155465 HYPERLINK "https://aka.ms/PowerShellTelemetryOptOut" \\o "Original URL:https://github.com/PowerShell/PowerS
hell/blob/master/README.md#telemetryClick to follow link."}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid11155465\charrsid15422468 {\*\datafield
10d0c9ea79f9bace118c8200aa004ba90b0200000003000000e0c9ea79f9bace118c8200aa004ba90b6a000000680074007400700073003a002f002f0061006b0061002e006d0073002f0050006f007700650072005300680065006c006c00540065006c0065006d0065007400720079004f00700074004f00750074000000
795881f43b1d7f48af2c825dc48527630000000085ab000000}}}{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs15\ul\cf19\insrsid15422468\charrsid15422468 here}}}\sectd \ltrsect\linex0\endnhere\sectlinegrid360\sectdefaultcl\sftnbj {\rtlch\fcs1 \af0 \ltrch\fcs0
\insrsid15422468\charrsid15422468 .}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid11998831
\par }{\*\themedata 504b030414000600080000002100e9de0fbfff0000001c020000130000005b436f6e74656e745f54797065735d2e786d6cac91cb4ec3301045f748fc83e52d4a
9cb2400825e982c78ec7a27cc0c8992416c9d8b2a755fbf74cd25442a820166c2cd933f79e3be372bd1f07b5c3989ca74aaff2422b24eb1b475da5df374fd9ad
5689811a183c61a50f98f4babebc2837878049899a52a57be670674cb23d8e90721f90a4d2fa3802cb35762680fd800ecd7551dc18eb899138e3c943d7e503b6
b01d583deee5f99824e290b4ba3f364eac4a430883b3c092d4eca8f946c916422ecab927f52ea42b89a1cd59c254f919b0e85e6535d135a8de20f20b8c12c3b0
0c895fcf6720192de6bf3b9e89ecdbd6596cbcdd8eb28e7c365ecc4ec1ff1460f53fe813d3cc7f5b7f020000ffff0300504b030414000600080000002100a5d6
a7e7c0000000360100000b0000005f72656c732f2e72656c73848fcf6ac3300c87ef85bd83d17d51d2c31825762fa590432fa37d00e1287f68221bdb1bebdb4f
c7060abb0884a4eff7a93dfeae8bf9e194e720169aaa06c3e2433fcb68e1763dbf7f82c985a4a725085b787086a37bdbb55fbc50d1a33ccd311ba548b6309512
0f88d94fbc52ae4264d1c910d24a45db3462247fa791715fd71f989e19e0364cd3f51652d73760ae8fa8c9ffb3c330cc9e4fc17faf2ce545046e37944c69e462
a1a82fe353bd90a865aad41ed0b5b8f9d6fd010000ffff0300504b0304140006000800000021006b799616830000008a0000001c0000007468656d652f746865
6d652f7468656d654d616e616765722e786d6c0ccc4d0ac3201040e17da17790d93763bb284562b2cbaebbf600439c1a41c7a0d29fdbd7e5e38337cedf14d59b
4b0d592c9c070d8a65cd2e88b7f07c2ca71ba8da481cc52c6ce1c715e6e97818c9b48d13df49c873517d23d59085adb5dd20d6b52bd521ef2cdd5eb9246a3d8b
4757e8d3f729e245eb2b260a0238fd010000ffff0300504b030414000600080000002100b6f4679893070000c9200000160000007468656d652f7468656d652f
7468656d65312e786d6cec59cd8b1bc915bf07f23f347d97f5d5ad8fc1f2a24fcfda33b6b164873dd648a5eef2547789aad28cc56208de532e81c026e49085bd
ed21842cecc22eb9e48f31d8249b3f22afaa5bdd5552c99e191c3061463074977eefd5afde7bf5de53d5ddcf5e26d4bbc05c1096f6fcfa9d9aefe174ce16248d
7afeb3d9a4d2f13d2151ba4094a5b8e76fb0f03fbbf7eb5fdd454732c609f6403e1547a8e7c752ae8eaa5531876124eeb0154ee1bb25e30992f0caa3ea82a34b
d09bd06aa3566b55134452df4b51026a1f2f97648ebd9952e9dfdb2a1f53784da5500373caa74a35b6243476715e5708b11143cabd0b447b3eccb3609733fc52
fa1e4542c2173dbfa6fffceabdbb5574940b517940d6909be8bf5c2e17589c37f49c3c3a2b260d823068f50bfd1a40e53e6edc1eb7c6ad429f06a0f91c569a71
b175b61bc320c71aa0ecd1a17bd41e35eb16ded0dfdce3dc0fd5c7c26b50a63fd8c34f2643b0a285d7a00c1feee1c3417730b2f56b50866fede1dbb5fe28685b
fa3528a6243ddf43d7c25673b85d6d0159327aec8477c360d26ee4ca4b144443115d6a8a254be5a1584bd00bc6270050408a24493db959e1259a43140f112567
9c7827248a21f056286502866b8ddaa4d684ffea13e827ed5174849121ad780113b137a4f87862cec94af6fc07a0d537206f7ffef9cdeb1fdfbcfee9cd575fbd
79fdf77c6eadca923b466964cafdf2dd1ffef3cd6fbd7ffff0ed2f5fff319b7a172f4cfcbbbffdeedd3ffef93ef5b0e2d2146ffff4fdbb1fbf7ffbe7dfffebaf
5f3bb4f7393a33e1339260e13dc297de5396c0021dfcf119bf9ec42c46c494e8a791402952b338f48f656ca11f6d10450edc00db767cce21d5b880f7d72f2cc2
d398af2571687c182716f094313a60dc6985876a2ec3ccb3751ab927e76b13f714a10bd7dc43945a5e1eaf579063894be530c616cd2714a5124538c5d253dfb1
738c1dabfb8210cbaea764ce99604be97d41bc01224e93ccc899154da5d03149c02f1b1741f0b7659bd3e7de8051d7aa47f8c246c2de40d4417e86a965c6fb68
2d51e252394309350d7e8264ec2239ddf0b9891b0b099e8e3065de78818570c93ce6b05ec3e90f21cdb8dd7e4a37898de4929cbb749e20c64ce4889d0f6394ac
5cd829496313fbb938871045de13265df05366ef10f50e7e40e941773f27d872f787b3c133c8b026a53240d4376beef0e57dccacf89d6ee8126157aae9f3c44a
b17d4e9cd131584756689f604cd1255a60ec3dfbdcc160c05696cd4bd20f62c82ac7d815580f901dabea3dc5027a25d5dcece7c91322ac909de2881de073bad9
493c1b9426881fd2fc08bc6eda7c0ca52e7105c0633a3f37818f08f480102f4ea33c16a0c308ee835a9fc4c82a60ea5db8e375c32dff5d658fc1be7c61d1b8c2
be04197c6d1948eca6cc7b6d3343d49aa00c9819822ec3956e41c4727f29a28aab165b3be596f6a62ddd00dd91d5f42424fd6007b4d3fb84ffbbde073a8cb77f
f9c6b10f3e4ebfe3566c25ab6b763a8792c9f14e7f7308b7dbd50c195f904fbfa919a175fa04431dd9cf58b73dcd6d4fe3ffdff73487f6f36d2773a8dfb8ed64
7ce8306e3b99fc70e5e3743265f3027d8d3af0c80e7af4b14f72f0d46749289dca0dc527421ffc08f83db398c0a092d3279eb838055cc5f0a8ca1c4c60e1228e
b48cc799fc0d91f134462b381daafb4a492472d591f0564cc0a1911e76ea5678ba4e4ed9223becacd7d5c16656590592e5782d2cc6e1a04a66e856bb3cc02bd4
6bb6913e68dd1250b2d721614c6693683a48b4b783ca48fa58178ce620a157f65158741d2c3a4afdd6557b2c805ae115f8c1edc1cff49e1f06200242701e07cd
f942f92973f5d6bbda991fd3d3878c69450034d8db08283ddd555c0f2e4fad2e0bb52b78da2261849b4d425b46377822869fc17974aad1abd0b8aeafbba54b2d
7aca147a3e08ad9246bbf33e1637f535c8ede6069a9a9982a6de65cf6f35430899395af5fc251c1ac363b282d811ea3717a211dcbccc25cf36fc4d32cb8a0b39
4222ce0cae934e960d122231f728497abe5a7ee1069aea1ca2b9d51b90103e59725d482b9f1a3970baed64bc5ce2b934dd6e8c284b67af90e1b35ce1fc568bdf
1cac24d91adc3d8d1797de195df3a708422c6cd795011744c0dd413db3e682c0655891c8caf8db294c79da356fa3740c65e388ae62945714339967709dca0b3a
faadb081f196af190c6a98242f8467912ab0a651ad6a5a548d8cc3c1aafb6121653923699635d3ca2aaa6abab39835c3b60cecd8f26645de60b53531e434b3c2
67a97b37e576b7b96ea74f28aa0418bcb09fa3ea5ea12018d4cac92c6a8af17e1a56393b1fb56bc776811fa07695226164fdd656ed8edd8a1ae19c0e066f54f9
416e376a6168b9ed2bb5a5f5adb979b1cdce5e40f2184197bba6526857c2c92e47d0104d754f92a50dd8222f65be35e0c95b73d2f3bfac85fd60d80887955a27
1c57826650ab74c27eb3d20fc3667d1cd66ba341e31514161927f530bbb19fc00506dde4f7f67a7cefee3ed9ded1dc99b3a4caf4dd7c5513d777f7f5c6e1bb7b
8f40d2f9b2d598749bdd41abd26df627956034e854bac3d6a0326a0ddba3c9681876ba9357be77a1c141bf390c5ae34ea5551f0e2b41aba6e877ba9576d068f4
8376bf330efaaff23606569ea58fdc16605ecdebde7f010000ffff0300504b0304140006000800000021000dd1909fb60000001b010000270000007468656d65
2f7468656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73848f4d0ac2301484f78277086f6fd3ba109126dd88d0add40384e4350d36
3f2451eced0dae2c082e8761be9969bb979dc9136332de3168aa1a083ae995719ac16db8ec8e4052164e89d93b64b060828e6f37ed1567914b284d262452282e
3198720e274a939cd08a54f980ae38a38f56e422a3a641c8bbd048f7757da0f19b017cc524bd62107bd5001996509affb3fd381a89672f1f165dfe514173d985
0528a2c6cce0239baa4c04ca5bbabac4df000000ffff0300504b01022d0014000600080000002100e9de0fbfff0000001c020000130000000000000000000000
0000000000005b436f6e74656e745f54797065735d2e786d6c504b01022d0014000600080000002100a5d6a7e7c0000000360100000b00000000000000000000
000000300100005f72656c732f2e72656c73504b01022d00140006000800000021006b799616830000008a0000001c0000000000000000000000000019020000
7468656d652f7468656d652f7468656d654d616e616765722e786d6c504b01022d0014000600080000002100b6f4679893070000c92000001600000000000000
000000000000d60200007468656d652f7468656d652f7468656d65312e786d6c504b01022d00140006000800000021000dd1909fb60000001b01000027000000
000000000000000000009d0a00007468656d652f7468656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73504b050600000000050005005d010000980b00000000}
{\*\colorschememapping 3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d3822207374616e64616c6f6e653d22796573223f3e0d0a3c613a636c724d
617020786d6c6e733a613d22687474703a2f2f736368656d61732e6f70656e786d6c666f726d6174732e6f72672f64726177696e676d6c2f323030362f6d6169
6e22206267313d226c743122207478313d22646b3122206267323d226c743222207478323d22646b322220616363656e74313d22616363656e74312220616363
656e74323d22616363656e74322220616363656e74333d22616363656e74332220616363656e74343d22616363656e74342220616363656e74353d22616363656e74352220616363656e74363d22616363656e74362220686c696e6b3d22686c696e6b2220666f6c486c696e6b3d22666f6c486c696e6b222f3e}
{\*\latentstyles\lsdstimax376\lsdlockeddef0\lsdsemihiddendef0\lsdunhideuseddef0\lsdqformatdef0\lsdprioritydef99{\lsdlockedexcept \lsdqformat1 \lsdpriority0 \lsdlocked0 Normal;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 1;
\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 2;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 3;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 4;
\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 5;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 6;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 7;
\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 8;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 9;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 1;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 5;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 6;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 7;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 8;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 9;
\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 1;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 2;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 3;
\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 4;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 5;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 6;
\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 7;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 8;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 9;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Normal Indent;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 footnote text;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 annotation text;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 header;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 footer;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index heading;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority35 \lsdlocked0 caption;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 table of figures;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 envelope address;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 envelope return;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 footnote reference;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 annotation reference;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 line number;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 page number;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 endnote reference;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 endnote text;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 table of authorities;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 macro;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 toa heading;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Bullet;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Number;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List 3;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List 5;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Bullet 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Bullet 3;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Bullet 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Bullet 5;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Number 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Number 3;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Number 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Number 5;\lsdqformat1 \lsdpriority10 \lsdlocked0 Title;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Closing;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Signature;\lsdsemihidden1 \lsdunhideused1 \lsdpriority1 \lsdlocked0 Default Paragraph Font;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text Indent;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Continue;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Continue 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Continue 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Continue 4;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Continue 5;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Message Header;\lsdqformat1 \lsdpriority11 \lsdlocked0 Subtitle;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Salutation;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Date;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text First Indent;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text First Indent 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Note Heading;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text Indent 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text Indent 3;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Block Text;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Hyperlink;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 FollowedHyperlink;\lsdqformat1 \lsdpriority22 \lsdlocked0 Strong;
\lsdqformat1 \lsdpriority20 \lsdlocked0 Emphasis;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Document Map;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Plain Text;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 E-mail Signature;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Top of Form;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Bottom of Form;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Normal (Web);\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Acronym;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Address;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Cite;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Code;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Definition;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Keyboard;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Preformatted;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Sample;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Typewriter;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Variable;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 annotation subject;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 No List;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Outline List 1;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Outline List 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Outline List 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Balloon Text;\lsdpriority39 \lsdlocked0 Table Grid;
\lsdsemihidden1 \lsdlocked0 Placeholder Text;\lsdqformat1 \lsdpriority1 \lsdlocked0 No Spacing;\lsdpriority60 \lsdlocked0 Light Shading;\lsdpriority61 \lsdlocked0 Light List;\lsdpriority62 \lsdlocked0 Light Grid;
\lsdpriority63 \lsdlocked0 Medium Shading 1;\lsdpriority64 \lsdlocked0 Medium Shading 2;\lsdpriority65 \lsdlocked0 Medium List 1;\lsdpriority66 \lsdlocked0 Medium List 2;\lsdpriority67 \lsdlocked0 Medium Grid 1;\lsdpriority68 \lsdlocked0 Medium Grid 2;
\lsdpriority69 \lsdlocked0 Medium Grid 3;\lsdpriority70 \lsdlocked0 Dark List;\lsdpriority71 \lsdlocked0 Colorful Shading;\lsdpriority72 \lsdlocked0 Colorful List;\lsdpriority73 \lsdlocked0 Colorful Grid;\lsdpriority60 \lsdlocked0 Light Shading Accent 1;
\lsdpriority61 \lsdlocked0 Light List Accent 1;\lsdpriority62 \lsdlocked0 Light Grid Accent 1;\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 1;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 1;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 1;
\lsdsemihidden1 \lsdlocked0 Revision;\lsdqformat1 \lsdpriority34 \lsdlocked0 List Paragraph;\lsdqformat1 \lsdpriority29 \lsdlocked0 Quote;\lsdqformat1 \lsdpriority30 \lsdlocked0 Intense Quote;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 1;
\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 1;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 1;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 1;\lsdpriority70 \lsdlocked0 Dark List Accent 1;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 1;
\lsdpriority72 \lsdlocked0 Colorful List Accent 1;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 1;\lsdpriority60 \lsdlocked0 Light Shading Accent 2;\lsdpriority61 \lsdlocked0 Light List Accent 2;\lsdpriority62 \lsdlocked0 Light Grid Accent 2;
\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 2;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 2;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 2;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 2;
\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 2;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 2;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 2;\lsdpriority70 \lsdlocked0 Dark List Accent 2;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 2;
\lsdpriority72 \lsdlocked0 Colorful List Accent 2;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 2;\lsdpriority60 \lsdlocked0 Light Shading Accent 3;\lsdpriority61 \lsdlocked0 Light List Accent 3;\lsdpriority62 \lsdlocked0 Light Grid Accent 3;
\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 3;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 3;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 3;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 3;
\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 3;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 3;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 3;\lsdpriority70 \lsdlocked0 Dark List Accent 3;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 3;
\lsdpriority72 \lsdlocked0 Colorful List Accent 3;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 3;\lsdpriority60 \lsdlocked0 Light Shading Accent 4;\lsdpriority61 \lsdlocked0 Light List Accent 4;\lsdpriority62 \lsdlocked0 Light Grid Accent 4;
\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 4;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 4;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 4;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 4;
\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 4;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 4;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 4;\lsdpriority70 \lsdlocked0 Dark List Accent 4;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 4;
\lsdpriority72 \lsdlocked0 Colorful List Accent 4;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 4;\lsdpriority60 \lsdlocked0 Light Shading Accent 5;\lsdpriority61 \lsdlocked0 Light List Accent 5;\lsdpriority62 \lsdlocked0 Light Grid Accent 5;
\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 5;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 5;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 5;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 5;
\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 5;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 5;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 5;\lsdpriority70 \lsdlocked0 Dark List Accent 5;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 5;
\lsdpriority72 \lsdlocked0 Colorful List Accent 5;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 5;\lsdpriority60 \lsdlocked0 Light Shading Accent 6;\lsdpriority61 \lsdlocked0 Light List Accent 6;\lsdpriority62 \lsdlocked0 Light Grid Accent 6;
\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 6;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 6;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 6;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 6;
\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 6;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 6;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 6;\lsdpriority70 \lsdlocked0 Dark List Accent 6;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 6;
\lsdpriority72 \lsdlocked0 Colorful List Accent 6;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 6;\lsdqformat1 \lsdpriority19 \lsdlocked0 Subtle Emphasis;\lsdqformat1 \lsdpriority21 \lsdlocked0 Intense Emphasis;
\lsdqformat1 \lsdpriority31 \lsdlocked0 Subtle Reference;\lsdqformat1 \lsdpriority32 \lsdlocked0 Intense Reference;\lsdqformat1 \lsdpriority33 \lsdlocked0 Book Title;\lsdsemihidden1 \lsdunhideused1 \lsdpriority37 \lsdlocked0 Bibliography;
\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority39 \lsdlocked0 TOC Heading;\lsdpriority41 \lsdlocked0 Plain Table 1;\lsdpriority42 \lsdlocked0 Plain Table 2;\lsdpriority43 \lsdlocked0 Plain Table 3;\lsdpriority44 \lsdlocked0 Plain Table 4;
\lsdpriority45 \lsdlocked0 Plain Table 5;\lsdpriority40 \lsdlocked0 Grid Table Light;\lsdpriority46 \lsdlocked0 Grid Table 1 Light;\lsdpriority47 \lsdlocked0 Grid Table 2;\lsdpriority48 \lsdlocked0 Grid Table 3;\lsdpriority49 \lsdlocked0 Grid Table 4;
\lsdpriority50 \lsdlocked0 Grid Table 5 Dark;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 1;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 1;
\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 1;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 1;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 1;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 1;
\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 1;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 2;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 2;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 2;
\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 2;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 2;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 2;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 2;
\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 3;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 3;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 3;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 3;
\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 3;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 3;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 3;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 4;
\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 4;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 4;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 4;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 4;
\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 4;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 4;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 5;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 5;
\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 5;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 5;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 5;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 5;
\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 5;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 6;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 6;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 6;
\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 6;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 6;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 6;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 6;
\lsdpriority46 \lsdlocked0 List Table 1 Light;\lsdpriority47 \lsdlocked0 List Table 2;\lsdpriority48 \lsdlocked0 List Table 3;\lsdpriority49 \lsdlocked0 List Table 4;\lsdpriority50 \lsdlocked0 List Table 5 Dark;
\lsdpriority51 \lsdlocked0 List Table 6 Colorful;\lsdpriority52 \lsdlocked0 List Table 7 Colorful;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 1;\lsdpriority47 \lsdlocked0 List Table 2 Accent 1;\lsdpriority48 \lsdlocked0 List Table 3 Accent 1;
\lsdpriority49 \lsdlocked0 List Table 4 Accent 1;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 1;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 1;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 1;
\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 2;\lsdpriority47 \lsdlocked0 List Table 2 Accent 2;\lsdpriority48 \lsdlocked0 List Table 3 Accent 2;\lsdpriority49 \lsdlocked0 List Table 4 Accent 2;
\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 2;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 2;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 2;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 3;
\lsdpriority47 \lsdlocked0 List Table 2 Accent 3;\lsdpriority48 \lsdlocked0 List Table 3 Accent 3;\lsdpriority49 \lsdlocked0 List Table 4 Accent 3;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 3;
\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 3;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 3;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 4;\lsdpriority47 \lsdlocked0 List Table 2 Accent 4;
\lsdpriority48 \lsdlocked0 List Table 3 Accent 4;\lsdpriority49 \lsdlocked0 List Table 4 Accent 4;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 4;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 4;
\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 4;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 5;\lsdpriority47 \lsdlocked0 List Table 2 Accent 5;\lsdpriority48 \lsdlocked0 List Table 3 Accent 5;
\lsdpriority49 \lsdlocked0 List Table 4 Accent 5;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 5;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 5;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 5;
\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 6;\lsdpriority47 \lsdlocked0 List Table 2 Accent 6;\lsdpriority48 \lsdlocked0 List Table 3 Accent 6;\lsdpriority49 \lsdlocked0 List Table 4 Accent 6;
\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 6;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 6;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 6;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Mention;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Smart Hyperlink;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Hashtag;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Unresolved Mention;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Smart Link;}}{\*\datastore }}
-654
View File
@@ -1,654 +0,0 @@
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<!-- The URL for add/remove programs -->
<!-- TBD:Point to the actual release -->
<?define InfoURL="https://github.com/PowerShell/PowerShell" ?>
<?define ProductSimpleVersionWithNameAndOptionalArchitecture = "$(var.ProductName) $(var.SimpleProductVersion) ($(sys.BUILDARCH))"?>
<?if $(var.IsPreview)=True?>
<?define PwshPath = "[VersionFolder]preview"?>
<?define IconPath = "assets\Powershell_av_colors.ico"?>
<?else?>
<?define PwshPath = "[VersionFolder]"?>
<?define IconPath = "assets\Powershell_black.ico"?>
<?endif?>
<!-- UpgradeCode GUID MUST REMAIN SAME THROUGHOUT ALL VERSIONS, otherwise, updates won't occur. -->
<?if $(sys.BUILDARCH)=x64?>
<?define ExplorerContextMenuDialogText = "&$(var.ProductName) $(var.SimpleProductVersion)"?>
<?define UpgradeCodePreview = "39243d76-adaf-42b1-94fb-16ecf83237c8"?>
<?define UpgradeCodeRelease = "31ab5147-9a97-4452-8443-d9709f0516e1"?>
<?if $(var.IsPreview)=True?>
<?define UpgradeCode = $(var.UpgradeCodePreview)?>
<?else?>
<?define UpgradeCode = $(var.UpgradeCodeRelease)?>
<?endif?>
<?elseif $(sys.BUILDARCH) = "ARM64"?>
<?define ExplorerContextMenuDialogText = "&$(var.ProductName) $(var.SimpleProductVersion) ($(sys.BUILDARCH))"?>
<?define UpgradeCodePreview = "f064cf16-97b7-4550-b392-ce0f4a6823a3"?>
<?define UpgradeCodeRelease = "75c68ab2-09d8-46b8-b697-d829bdd4c94f"?>
<?if $(var.IsPreview)=True?>
<?define UpgradeCode = $(var.UpgradeCodePreview)?>
<?else?>
<?define UpgradeCode = $(var.UpgradeCodeRelease)?>
<?endif?>
<?else?>
<?define ExplorerContextMenuDialogText = "&$(var.ProductName) $(var.SimpleProductVersion) ($(sys.BUILDARCH))"?>
<?define UpgradeCodePreview = "86abcfbd-1ccc-4a88-b8b2-0facfde29094"?>
<?define UpgradeCodeRelease = "1d00683b-0f84-4db8-a64f-2f98ad42fe06"?>
<?if $(var.IsPreview)=True?>
<?define UpgradeCode = $(var.UpgradeCodePreview)?>
<?else?>
<?define UpgradeCode = $(var.UpgradeCodeRelease)?>
<?endif?>
<?endif?>
<!-- Explorer context submenu entries. The ampersand denotes the keyboard shortcut. -->
<?define ExplorerContextSubMenuDialogText = "Open &here"?>
<?define ExplorerContextSubMenuElevatedDialogText = "Open here as &Administrator"?>
<!-- ps1 context submenu entries. -->
<?define PowerShellFileContextSubMenuDialogText = "Run with $(var.ProductName) $(var.SimpleProductVersion)"?>
<!-- Registry location to save installer properties. -->
<?if $(var.IsPreview)=True?>
<?define InstallerPropertiesKey = "Software\Microsoft\PowerShellCore\PreviewInstallerProperties"?>
<?else?>
<?define InstallerPropertiesKey = "Software\Microsoft\PowerShellCore\InstallerProperties"?>
<?endif?>
<Product
Id="*"
Name="PowerShell $(var.SimpleProductVersion)-$(sys.BUILDARCH)"
Language="1033"
Version="$(var.ProductVersion)"
Manufacturer="Microsoft Corporation"
UpgradeCode="$(var.UpgradeCode)">
<!-- Properties About The Package -->
<Package Id="*" Keywords="Installer" Platform="$(sys.BUILDARCH)" InstallerVersion="200" Compressed="yes" InstallScope="perMachine" Description="PowerShell package" Comments="PowerShell for every system" />
<!-- Add PowerShell icon for executable -->
<Icon Id="PowerShellExe.ico" SourceFile="$(var.IconPath)" />
<!-- Add PowerShell icon in Add/Remove Programs -->
<Property Id="ARPPRODUCTICON" Value="PowerShellExe.ico" />
<!-- Set properties for add/remove programs -->
<Property Id="ARPHELPLINK" Value="$(var.InfoURL)" />
<!-- custom images -->
<WixVariable Id="WixUIBannerBmp" Value="assets\wix\WixUIBannerBmp.png" />
<WixVariable Id="WixUIDialogBmp" Value="assets\wix\WixUIDialogBmp.png" />
<WixVariable Id="WixUIExclamationIco" Value="assets\wix\WixUIInfoIco.png" />
<WixVariable Id="WixUIInfoIco" Value="assets\ps_black_32x32.ico" />
<Property Id="WIXUI_EXITDIALOGOPTIONALCHECKBOXTEXT" Value="Open $(var.ProductName)" />
<!-- Default value of Checkbox of starting PowerShell after installation -->
<Property Id="WixShellExecTarget" Value="[VersionFolder]pwsh.exe"/>
<!-- This changes the default setting from "reinstall if the file is a newer version" to "reinstall if the file is a different version" -->
<Property Id="REINSTALLMODE" Value="dmus"/>
<CustomAction Id="LaunchApplication" BinaryKey="WixCA" DllEntry="WixShellExec" Impersonate="yes" />
<!-- Property Initialization -->
<!--
Each property below will undergo the following steps in the
initial sequence (`InstallUISequence` if the UI is shown
or `InstallExecuteSequence` if the UI is skipped):
1. Load the value that was used in the previous installation into a separate property.
2. `..._SetFromSaved`: If the property does not have a value (meaning it
was not specified on the command line) and there is a value from the
previous installation, use the value from the previous installation.
3. `..._SetDefault`: If the property does not have a value (meaning it was not specified
on the command line _and_ there wasn't a value from a previous installation), and
the property has a default value, then set the property to the default value.
4. `..._DeleteIfOff`: For "boolean" properties, if the property value is not `1`, then delete
the property. This needs to be done so that the checkbox in the UI is not initially checked.
If the property exists, the checkbox will be initially checked regardless of the property value.
Then in the `InstallExecuteSequence`:
1. `..._SetToOffIfMissing`: For boolean properties, if the property does not exist, it is set
to `0`. This ensures that the property value that is saved to the registry is not blank.
If blank values are saved to the registry, then the `..._SetFromSaved` step won't run because
a blank property value is indistinguishable from a property value that does not exist.
When using "boolean" properties, always check if the property value is equal `1`, instead
of just checking if the property exists. For example, use `FOO=1` instead of just `FOO`.
-->
<!-- Property: INSTALLFOLDER -->
<Property Id="PREVIOUS_INSTALLFOLDER">
<RegistrySearch Id="GetSavedInstallFolder" Root="HKLM" Key="$(var.InstallerPropertiesKey)" Name="InstallFolder" Type="raw" />
</Property>
<SetProperty Id="INSTALLFOLDER" Action="InstallFolder_SetFromSaved" After="AppSearch" Value="[PREVIOUS_INSTALLFOLDER]" Sequence="first">
not INSTALLFOLDER and PREVIOUS_INSTALLFOLDER
</SetProperty>
<!-- Property: ADD_PATH -->
<Property Id="PREVIOUS_ADD_PATH">
<RegistrySearch Id="GetSavedAddToPath" Root="HKLM" Key="$(var.InstallerPropertiesKey)" Name="AddToPath" Type="raw" />
</Property>
<SetProperty Id="ADD_PATH" Action="AddToPath_SetFromSaved" After="AppSearch" Value="[PREVIOUS_ADD_PATH]" Sequence="first">
not ADD_PATH and PREVIOUS_ADD_PATH
</SetProperty>
<SetProperty Id="ADD_PATH" Action="AddToPath_SetDefault" After="AddToPath_SetFromSaved" Value="1" Sequence="first">
not ADD_PATH
</SetProperty>
<SetProperty Id="ADD_PATH" Action="AddToPath_DeleteIfOff" After="AddToPath_SetDefault" Value="{}" Sequence="first">
ADD_PATH&lt;&gt;1
</SetProperty>
<SetProperty Id="ADD_PATH" Action="AddToPath_SetToOffIfMissing" Before="InstallInitialize" Value="0" Sequence="execute">
not ADD_PATH
</SetProperty>
<!-- Property: REGISTER_MANIFEST -->
<Property Id="PREVIOUS_REGISTER_MANIFEST">
<RegistrySearch Id="GetSavedRegisterManifest" Root="HKLM" Key="$(var.InstallerPropertiesKey)" Name="RegisterManifest" Type="raw" />
</Property>
<SetProperty Id="REGISTER_MANIFEST" Action="RegisterManifest_SetFromSaved" After="AppSearch" Value="[PREVIOUS_REGISTER_MANIFEST]" Sequence="first">
not REGISTER_MANIFEST and PREVIOUS_REGISTER_MANIFEST
</SetProperty>
<SetProperty Id="REGISTER_MANIFEST" Action="RegisterManifest_SetDefault" After="RegisterManifest_SetFromSaved" Value="1" Sequence="first">
not REGISTER_MANIFEST
</SetProperty>
<SetProperty Id="REGISTER_MANIFEST" Action="RegisterManifest_DeleteIfOff" After="RegisterManifest_SetDefault" Value="{}" Sequence="first">
REGISTER_MANIFEST&lt;&gt;1
</SetProperty>
<SetProperty Id="REGISTER_MANIFEST" Action="RegisterManifest_SetToOffIfMissing" Before="InstallInitialize" Value="0" Sequence="execute">
not REGISTER_MANIFEST
</SetProperty>
<!-- Property: ENABLE_PSREMOTING -->
<Property Id="PREVIOUS_ENABLE_PSREMOTING">
<RegistrySearch Id="GetSavedEnablePsRemoting" Root="HKLM" Key="$(var.InstallerPropertiesKey)" Name="EnablePsRemoting" Type="raw" />
</Property>
<SetProperty Id="ENABLE_PSREMOTING" Action="EnablePsRemoting_SetFromSaved" After="AppSearch" Value="[PREVIOUS_ENABLE_PSREMOTING]" Sequence="first">
not ENABLE_PSREMOTING and PREVIOUS_ENABLE_PSREMOTING
</SetProperty>
<SetProperty Id="ENABLE_PSREMOTING" Action="EnablePsRemoting_DeleteIfOff" After="EnablePsRemoting_SetFromSaved" Value="{}" Sequence="first">
ENABLE_PSREMOTING&lt;&gt;1
</SetProperty>
<SetProperty Id="ENABLE_PSREMOTING" Action="EnablePsRemoting_SetToOffIfMissing" Before="InstallInitialize" Value="0" Sequence="execute">
not ENABLE_PSREMOTING
</SetProperty>
<!-- Property: DISABLE_TELEMETRY -->
<Property Id="PREVIOUS_DISABLE_TELEMETRY">
<RegistrySearch Id="GetSavedDisableTelemetry" Root="HKLM" Key="$(var.InstallerPropertiesKey)" Name="DisableTelemetry" Type="raw" />
</Property>
<SetProperty Id="DISABLE_TELEMETRY" Action="DisableTelemetry_SetFromSaved" After="AppSearch" Value="[PREVIOUS_DISABLE_TELEMETRY]" Sequence="first">
not DISABLE_TELEMETRY and PREVIOUS_DISABLE_TELEMETRY
</SetProperty>
<SetProperty Id="DISABLE_TELEMETRY" Action="DisableTelemetry_DeleteIfOff" After="DisableTelemetry_SetFromSaved" Value="{}" Sequence="first">
DISABLE_TELEMETRY&lt;&gt;1
</SetProperty>
<SetProperty Id="DISABLE_TELEMETRY" Action="DisableTelemetry_SetToOffIfMissing" Before="InstallInitialize" Value="0" Sequence="execute">
not DISABLE_TELEMETRY
</SetProperty>
<!-- Property: ADD_EXPLORER_CONTEXT_MENU_OPENPOWERSHELL -->
<Property Id="PREVIOUS_ADD_EXPLORER_CONTEXT_MENU_OPENPOWERSHELL">
<RegistrySearch Id="GetSavedAddExplorerContextMenuOpenPowerShell" Root="HKLM" Key="$(var.InstallerPropertiesKey)" Name="AddExplorerContextMenuOpenPowerShell" Type="raw" />
</Property>
<SetProperty Id="ADD_EXPLORER_CONTEXT_MENU_OPENPOWERSHELL" Action="AddExplorerContextMenuOpenPowerShell_SetFromSaved" After="AppSearch" Value="[PREVIOUS_ADD_EXPLORER_CONTEXT_MENU_OPENPOWERSHELL]" Sequence="first">
not ADD_EXPLORER_CONTEXT_MENU_OPENPOWERSHELL and PREVIOUS_ADD_EXPLORER_CONTEXT_MENU_OPENPOWERSHELL
</SetProperty>
<SetProperty Id="ADD_EXPLORER_CONTEXT_MENU_OPENPOWERSHELL" Action="AddExplorerContextMenuOpenPowerShell_DeleteIfOff" After="AddExplorerContextMenuOpenPowerShell_SetFromSaved" Value="{}" Sequence="first">
ADD_EXPLORER_CONTEXT_MENU_OPENPOWERSHELL&lt;&gt;1
</SetProperty>
<SetProperty Id="ADD_EXPLORER_CONTEXT_MENU_OPENPOWERSHELL" Action="AddExplorerContextMenuOpenPowerShell_SetToOffIfMissing" Before="InstallInitialize" Value="0" Sequence="execute">
not ADD_EXPLORER_CONTEXT_MENU_OPENPOWERSHELL
</SetProperty>
<!-- Property: ADD_FILE_CONTEXT_MENU_RUNPOWERSHELL -->
<Property Id="PREVIOUS_ADD_FILE_CONTEXT_MENU_RUNPOWERSHELL">
<RegistrySearch Id="GetSavedAddFileContextMenuRunPowerShell" Root="HKLM" Key="$(var.InstallerPropertiesKey)" Name="AddFileContextMenuRunPowerShell" Type="raw" />
</Property>
<SetProperty Id="ADD_FILE_CONTEXT_MENU_RUNPOWERSHELL" Action="AddFileContextMenuRunPowerShell_SetFromSaved" After="AppSearch" Value="[PREVIOUS_ADD_FILE_CONTEXT_MENU_RUNPOWERSHELL]" Sequence="first">
not ADD_FILE_CONTEXT_MENU_RUNPOWERSHELL and PREVIOUS_ADD_FILE_CONTEXT_MENU_RUNPOWERSHELL
</SetProperty>
<SetProperty Id="ADD_FILE_CONTEXT_MENU_RUNPOWERSHELL" Action="AddFileContextMenuRunPowerShell_DeleteIfOff" After="AddFileContextMenuRunPowerShell_SetFromSaved" Value="{}" Sequence="first">
ADD_FILE_CONTEXT_MENU_RUNPOWERSHELL&lt;&gt;1
</SetProperty>
<SetProperty Id="ADD_FILE_CONTEXT_MENU_RUNPOWERSHELL" Action="AddFileContextMenuRunPowerShell_SetToOffIfMissing" Before="InstallInitialize" Value="0" Sequence="execute">
not ADD_FILE_CONTEXT_MENU_RUNPOWERSHELL
</SetProperty>
<!-- Property: USE_MU -->
<Property Id="PREVIOUS_USE_MU">
<RegistrySearch Id="GetSavedUseMU" Root="HKLM" Key="$(var.InstallerPropertiesKey)" Name="UseMU" Type="raw" />
</Property>
<SetProperty Id="USE_MU" Action="UseMU_SetFromSaved" After="AppSearch" Value="[PREVIOUS_USE_MU]" Sequence="first">
not USE_MU and PREVIOUS_USE_MU
</SetProperty>
<SetProperty Id="USE_MU" Action="UseMU_SetDefault" After="UseMU_SetFromSaved" Value="1" Sequence="first">
not USE_MU
</SetProperty>
<SetProperty Id="USE_MU" Action="UseMU_DeleteIfOff" After="UseMU_SetDefault" Value="{}" Sequence="first">
USE_MU&lt;&gt;1
</SetProperty>
<SetProperty Id="USE_MU" Action="UseMU_SetToOffIfMissing" Before="InstallInitialize" Value="0" Sequence="execute">
not USE_MU
</SetProperty>
<!-- Property: ENABLE_MU -->
<Property Id="PREVIOUS_ENABLE_MU">
<RegistrySearch Id="GetSavedEnableMU" Root="HKLM" Key="$(var.InstallerPropertiesKey)" Name="EnableMU" Type="raw" />
</Property>
<SetProperty Id="ENABLE_MU" Action="EnableMU_SetFromSaved" After="AppSearch" Value="[PREVIOUS_ENABLE_MU]" Sequence="first">
not ENABLE_MU and PREVIOUS_ENABLE_MU
</SetProperty>
<SetProperty Id="ENABLE_MU" Action="EnableMU_SetDefault" After="EnableMU_SetFromSaved" Value="1" Sequence="first">
not ENABLE_MU
</SetProperty>
<SetProperty Id="ENABLE_MU" Action="EnableMU_DeleteIfOff" After="EnableMU_SetDefault" Value="{}" Sequence="first">
ENABLE_MU&lt;&gt;1
</SetProperty>
<SetProperty Id="ENABLE_MU" Action="EnableMU_SetToOffIfMissing" Before="InstallInitialize" Value="0" Sequence="execute">
not ENABLE_MU
</SetProperty>
<!-- End Property Initialization -->
<SetProperty Id="RegisterManifest"
Before="RegisterManifest"
Sequence="execute"
Value="&quot;[VersionFolder]pwsh.exe&quot; -NoProfile -ExecutionPolicy Bypass -File &quot;[VersionFolder]RegisterManifest.ps1&quot;" />
<CustomAction Id="RegisterManifest"
BinaryKey="WixCA"
DllEntry="CAQuietExec"
Execute="deferred"
Return="ignore"
Impersonate="no" />
<SetProperty Id="EnablePSRemoting"
Before="EnablePSRemoting"
Sequence="execute"
Value="&quot;[VersionFolder]pwsh.exe&quot; -NoProfile -ExecutionPolicy Bypass -Command &quot;Enable-PSRemoting&quot;" />
<CustomAction Id="EnablePSRemoting"
BinaryKey="WixCA"
DllEntry="CAQuietExec"
Execute="deferred"
Return="ignore"
Impersonate="no" />
<SetProperty Id="EnableMU"
Before="EnableMU"
Sequence="execute"
Value="&quot;[VersionFolder]pwsh.exe&quot; -NoProfile -ExecutionPolicy Bypass -File &quot;[VersionFolder]RegisterMicrosoftUpdate.ps1&quot;" />
<CustomAction Id="EnableMU"
BinaryKey="WixCA"
DllEntry="CAQuietExec"
Execute="deferred"
Return="ignore"
Impersonate="no" />
<InstallExecuteSequence>
<!-- Do not remove shortcuts on upgrade to preserve user shortcuts pinned to Taskbar, see https://stackoverflow.com/a/33402698/1810304 -->
<RemoveShortcuts>Installed AND NOT UPGRADINGPRODUCTCODE</RemoveShortcuts>
<Custom Action="RegisterManifest" After="InstallFiles">
<![CDATA[NOT Installed AND (REGISTER_MANIFEST=1)]]>
</Custom>
<Custom Action="EnablePSRemoting" After="InstallFiles">
<![CDATA[NOT Installed AND (ENABLE_PSREMOTING=1)]]>
</Custom>
<Custom Action="EnableMU" After="InstallFiles">
<![CDATA[NOT Installed AND (ENABLE_MU=1)]]>
</Custom>
</InstallExecuteSequence>
<UI>
<Dialog Id="MyExitDialog" Width="370" Height="270" Title="!(loc.ExitDialog_Title)">
<Control Id="Bitmap" Type="Bitmap" X="0" Y="0" Width="370" Height="234" TabSkip="yes" Text="!(loc.ExitDialogBitmap)" />
<Control Id="Title" Type="Text" X="135" Y="20" Width="220" Height="60" Transparent="yes" NoPrefix="yes" Text="{\WixUI_Font_Bigger}!(loc.Error1707)" TabSkip="yes" />
<Control Id="Description" Type="Text" X="135" Y="70" Width="220" Height="20" Transparent="yes" NoPrefix="yes" Text="!(loc.ExitDialogDescription)" TabSkip="yes" />
<!-- divider between check boxes and button row -->
<Control Id="BottomLine" Type="Line" X="0" Y="234" Width="370" Height="0" TabSkip="yes" />
<!-- Button row -->
<!-- Checkbox to allow starting PowerShell after the installation (in UI mode only) -->
<Control Id="LaunchCheckBox" Type="CheckBox" X="10" Y="243" Width="170" Height="17" Property="LAUNCHAPPONEXIT" Hidden="yes" CheckBoxValue="1" Text="Launch $(var.ProductName)" >
<Condition Action="show">NOT Installed</Condition>
</Control>
<Control Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17" Disabled="yes" Text="!(loc.WixUIBack)" />
<Control Id="Finish" Type="PushButton" X="236" Y="243" Width="56" Height="17" Default="yes" Cancel="yes" Text="!(loc.WixUIFinish)" />
<Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Disabled="yes" Text="!(loc.WixUICancel)" />
</Dialog>
<InstallUISequence>
<Show Dialog="MyExitDialog" OnExit="success" />
</InstallUISequence>
<AdminUISequence>
<Show Dialog="MyExitDialog" OnExit="success" />
</AdminUISequence>
<Publish Dialog="MyExitDialog" Control="Finish" Event="EndDialog" Value="Return" Order="999">1</Publish>
</UI>
<UI>
<Publish Dialog="MyExitDialog" Control="Finish" Order="1" Event="DoAction" Value="LaunchApplication">LAUNCHAPPONEXIT=1</Publish>
</UI>
<!-- Prerequisites -->
<Condition Message="Supported only on Windows 8.1 and above">
<![CDATA[ Installed OR MsiNTProductType <> 1 OR VersionNT >= 603 ]]>
</Condition>
<Condition Message="Supported only on Windows Server 2012 and above">
<![CDATA[ Installed OR MsiNTProductType = 1 OR VersionNT >= 602 ]]>
</Condition>
<!-- Information About When Older Versions Are Trying To Be Installed-->
<MajorUpgrade AllowSameVersionUpgrades="yes" DowngradeErrorMessage="A newer version of $(var.ProductName) is already installed." />
<!-- Embed Cabinet Files in Product-->
<MediaTemplate EmbedCab="yes" />
<!-- In Your Wix Setup Project, Add A Reference To WixUIExtension.dll -->
<UIRef Id="CustomWixUI_InstallDir" />
<!-- Features are mandatory. Need At Least One. -->
<Feature Id="ProductFeature" Title="PowerShell" Level="1">
<ComponentGroupRef Id="ApplicationFiles"/>
<ComponentRef Id="ApplicationProgramsMenuShortcut"/>
<ComponentRef Id="MURegistryEntries"/>
<ComponentRef Id="RegistryEntries"/>
<?if $(var.IsPreview)!=True?>
<ComponentRef Id="AppPath"/>
<?endif?>
<ComponentRef Id="SetPath"/>
<ComponentRef Id="Telemetry"/>
<ComponentRef Id="DisableTelemetry"/>
<ComponentRef Id="ExplorerContextMenu"/>
<ComponentRef Id="PowerShellFileContextMenu"/>
<ComponentRef Id="SaveInstallerProperties"/>
</Feature>
<!-- We need to show EULA, and provide option to customize download location -->
<Property Id="WIXUI_INSTALLDIR" Value="INSTALLFOLDER" />
<!-- Need to get the Windows product name from the registry -->
<Property Id="WINDOWS_PRODUCT_NAME">
<RegistrySearch Id="ProductName" Root="HKLM" Type="raw" Key="SOFTWARE\Microsoft\Windows NT\CurrentVersion" Name="ProductName" />
</Property>
<!-- Prerequisite check for Windows Universal C runtime -->
<Property Id="UNIVERSAL_C_RUNTIME_INSTALLED" Secure="yes">
<DirectorySearch Id="WindowsDirectory" Path="[WindowsFolder]">
<DirectorySearch Id="System32" Path="System32">
<FileSearch Id="ucrtbase" Name="ucrtbase.dll"/>
</DirectorySearch>
</DirectorySearch>
</Property>
<Condition Message="$(var.ProductName) requires the Universal C Runtime to be installed to enable remoting over WinRM. You can find a download link to it here: https://aka.ms/pscore6-prereq">
<![CDATA[Installed OR UNIVERSAL_C_RUNTIME_INSTALLED]]>
</Condition>
<!-- Prerequisite check for Windows Management Framework -->
<Property Id="PWRSHPLUGIN_VERSION" Secure="yes">
<DirectorySearchRef Id="System32" Parent="WindowsDirectory" Path="System32">
<FileSearch Id="pwrshplugin" Name="pwrshplugin.dll" MinVersion="6.3.9600.16383"/>
</DirectorySearchRef>
</Property>
<Condition Message="$(var.ProductName) requires the Windows Management Framework 4.0 or newer to be installed to enable remoting over WinRM. You can find download links here: https://aka.ms/pscore6-prereq">
<![CDATA[Installed OR PWRSHPLUGIN_VERSION ]]>
</Condition>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="$(var.ProductProgFilesDir)">
<Directory Id="INSTALLFOLDER" Name="PowerShell">
<Directory Id="VersionFolder" Name="$(var.SimpleProductVersion)">
<Component Id="Telemetry" Guid="{80520f20-471d-4d08-adc8-bab637627b39}" KeyPath="yes">
<!-- Should retain component GUID since this is a shared, non-file, non-registry resource. -->
<Environment Id="PowerShellDistributionChannel" Action="create" Name="POWERSHELL_DISTRIBUTION_CHANNEL" Permanent="no" System="yes" Value="MSI:[WINDOWS_PRODUCT_NAME]"/>
</Component>
<Component Id="MURegistryEntries">
<Condition>USE_MU=1</Condition>
<!-- Create registry key to allow opt-out of MU servicing without opting out of MU completely. We don't want to uninstall because it's used by both Preview and Stable and the detection relies on PS7 being installed for this to take effect. -->
<RegistryKey Root="HKLM" Key="Software\Microsoft\PowerShellCore" Action="create" ForceCreateOnInstall="yes">
<RegistryValue Type="integer" Value="1" Name="UseMU" KeyPath="yes"/>
</RegistryKey>
</Component>
<Component Id="RegistryEntries">
<!-- create key for easy detection of a particular version of a powershell core package
The upgrade code is used in the key because it will change when we allow SxS -->
<RegistryKey Root="HKLM" Key="Software\Microsoft\PowerShellCore\InstalledVersions\$(var.UpgradeCode)" ForceCreateOnInstall="yes" ForceDeleteOnUninstall="yes">
<RegistryValue Type="string" Value="$(var.ProductSemanticVersion)" Name="SemanticVersion" KeyPath="yes"/>
<RegistryValue Type="string" Value="[VersionFolder]" Name="InstallLocation" />
<RegistryValue Type="string" Value="[ProductCode]" Name="ProductCode" />
</RegistryKey>
</Component>
<?if $(var.IsPreview)!=True?>
<Component Id="AppPath">
<!-- register ourselves in application registry so can be started using just Win+R `pwsh.exe` -->
<RegistryKey Root="HKLM" Key="Software\Microsoft\Windows\CurrentVersion\App Paths\pwsh.exe" ForceCreateOnInstall="yes" ForceDeleteOnUninstall="yes">
<!-- As a shared path, the last one to install will overwrite any previous value. It also needs to be in its own component to properly ref-count and be removed when appropriate. -->
<RegistryValue Type="string" Value="[VersionFolder]pwsh.exe" KeyPath="yes"/>
</RegistryKey>
</Component>
<?endif?>
<Component Id="DisableTelemetry" Guid="{E86F5C91-3721-4C5C-A31F-1F0A5A468573}" KeyPath="yes">
<Condition>DISABLE_TELEMETRY=1</Condition>
<Environment Id="PowerShellTelemetryOptout" Action="set" Name="POWERSHELL_TELEMETRY_OPTOUT" Permanent="no" System="yes" Value="1"/>
</Component>
<!-- add ourselves to %PATH% so pwsh.exe can be started from Windows PowerShell or cmd.exe -->
<Component Id="SetPath">
<Condition>ADD_PATH=1</Condition>
<Environment Id="PATH" Action="set" Name="PATH" Part="last" Permanent="no" System="yes" Value="$(var.PwshPath)"/>
<!-- Can't use a shared component GUID here either since the path we add to PATH varies on the actual directory path. Use a key that represents this same path. -->
<RegistryKey Root="HKLM" Key="Software\Microsoft\PowerShellCore\InstalledVersions\$(var.UpgradeCode)">
<RegistryValue Type="string" Name="InstallDir" Value="[VersionFolder]" KeyPath="yes"/>
</RegistryKey>
</Component>
<!-- Explorer context menu with 2 submenus to open PowerShell normally or as an Administrator.
See https://blogs.msdn.microsoft.com/andrew_richards/2017/03/01/enhancing-the-open-command-prompt-here-shift-right-click-context-menu-experience/ for details -->
<Component Id="ExplorerContextMenu">
<Condition>ADD_EXPLORER_CONTEXT_MENU_OPENPOWERSHELL=1</Condition>
<!-- When clicking on background in Explorer -->
<RegistryKey Root="HKCR" Key="Directory\Background\shell\$(var.ProductName)$(var.SimpleProductVersion)$(sys.BUILDARCH)">
<RegistryValue Type="string" Name="MUIVerb" Value="$(var.ExplorerContextMenuDialogText)"/>
<RegistryValue Type="string" Name="Icon" Value="[VersionFolder]pwsh.exe"/>
<RegistryValue Type="string" Name="ExtendedSubCommandsKey" Value="Directory\ContextMenus\$(var.ProductName)$(var.SimpleProductVersion)$(sys.BUILDARCH)" KeyPath="yes"/>
</RegistryKey>
<!-- When clicking on Drive in Explorer -->
<RegistryKey Root="HKCR" Key="Drive\shell\$(var.ProductName)$(var.SimpleProductVersion)$(sys.BUILDARCH)">
<RegistryValue Type="string" Name="MUIVerb" Value="$(var.ExplorerContextMenuDialogText)"/>
<RegistryValue Type="string" Name="Icon" Value="[VersionFolder]pwsh.exe"/>
<RegistryValue Type="string" Name="ExtendedSubCommandsKey" Value="Directory\ContextMenus\$(var.ProductName)$(var.SimpleProductVersion)$(sys.BUILDARCH)"/>
</RegistryKey>
<!-- When clicking on Desktop background in Explorer -->
<RegistryKey Root="HKCR" Key="DesktopBackground\shell\$(var.ProductName)$(var.SimpleProductVersion)$(sys.BUILDARCH)">
<RegistryValue Type="string" Name="MUIVerb" Value="$(var.ExplorerContextMenuDialogText)"/>
<RegistryValue Type="string" Name="Icon" Value="[VersionFolder]pwsh.exe"/>
<RegistryValue Type="string" Name="ExtendedSubCommandsKey" Value="Directory\ContextMenus\$(var.ProductName)$(var.SimpleProductVersion)$(sys.BUILDARCH)"/>
</RegistryKey>
<!-- When clicking on folder in Explorer -->
<RegistryKey Root="HKCR" Key="Directory\shell\$(var.ProductName)$(var.SimpleProductVersion)$(sys.BUILDARCH)">
<RegistryValue Type="string" Name="MUIVerb" Value="$(var.ExplorerContextMenuDialogText)"/>
<RegistryValue Type="string" Name="Icon" Value="[VersionFolder]pwsh.exe"/>
<RegistryValue Type="string" Name="ExtendedSubCommandsKey" Value="Directory\ContextMenus\$(var.ProductName)$(var.SimpleProductVersion)$(sys.BUILDARCH)"/>
</RegistryKey>
<!-- When being in a Library folder in Explorer -->
<RegistryKey Root="HKCR" Key="LibraryFolder\background\shell\$(var.ProductName)$(var.SimpleProductVersion)$(sys.BUILDARCH)">
<RegistryValue Type="string" Name="MUIVerb" Value="$(var.ExplorerContextMenuDialogText)"/>
<RegistryValue Type="string" Name="Icon" Value="[VersionFolder]pwsh.exe"/>
<RegistryValue Type="string" Name="ExtendedSubCommandsKey" Value="Directory\ContextMenus\$(var.ProductName)$(var.SimpleProductVersion)$(sys.BUILDARCH)"/>
</RegistryKey>
<!-- Sub menus to open PowerShell at the current location either as a normal shell or as Administrator -->
<RegistryKey Root="HKCR" Key="Directory\ContextMenus\$(var.ProductName)$(var.SimpleProductVersion)$(sys.BUILDARCH)\shell\openpwsh">
<RegistryValue Type="string" Name="MUIVerb" Value="$(var.ExplorerContextSubMenuDialogText)"/>
<RegistryValue Type="string" Name="Icon" Value="[VersionFolder]pwsh.exe"/>
</RegistryKey>
<RegistryKey Root="HKCR" Key="Directory\ContextMenus\$(var.ProductName)$(var.SimpleProductVersion)$(sys.BUILDARCH)\shell\openpwsh\command">
<RegistryValue Type="string" Value="[VersionFolder]pwsh.exe -NoExit -RemoveWorkingDirectoryTrailingCharacter -WorkingDirectory &quot;%V!&quot; -Command &quot;$host.UI.RawUI.WindowTitle = '$(var.ProductName) $(var.SimpleProductVersion) ($(sys.BUILDARCH))'&quot;"/>
</RegistryKey>
<RegistryKey Root="HKCR" Key="Directory\ContextMenus\$(var.ProductName)$(var.SimpleProductVersion)$(sys.BUILDARCH)\shell\runas">
<RegistryValue Type="string" Name="MUIVerb" Value="$(var.ExplorerContextSubMenuElevatedDialogText)"/>
<RegistryValue Type="string" Name="Icon" Value="[VersionFolder]pwsh.exe"/>
<RegistryValue Type="string" Value="" Name="HasLUAShield"/>
</RegistryKey>
<RegistryKey Root="HKCR" Key="Directory\ContextMenus\$(var.ProductName)$(var.SimpleProductVersion)$(sys.BUILDARCH)\shell\runas\command">
<RegistryValue Type="string" Value="[VersionFolder]pwsh.exe -NoExit -RemoveWorkingDirectoryTrailingCharacter -WorkingDirectory &quot;%V!&quot; -Command &quot;$host.UI.RawUI.WindowTitle = '$(var.ProductName) $(var.SimpleProductVersion) ($(sys.BUILDARCH))'&quot;"/>
</RegistryKey>
<RemoveRegistryKey Id="RemoveOldOpenKey" Root="HKCR" Key="Directory\ContextMenus\$(var.ProductName)$(var.SimpleProductVersion)$(sys.BUILDARCH)\shell\open" Action="removeOnInstall"/>
</Component>
<Component Id="PowerShellFileContextMenu">
<Condition>ADD_FILE_CONTEXT_MENU_RUNPOWERSHELL=1</Condition>
<!-- When right-clicking ps1 file -->
<RegistryKey Root="HKCR" Key="Microsoft.PowerShellScript.1\Shell\$(var.ProductName)$(var.SimpleProductVersion)$(sys.BUILDARCH)">
<RegistryValue Type="string" Name="MUIVerb" Value="$(var.PowerShellFileContextSubMenuDialogText)"/>
<RegistryValue Type="string" Name="Icon" Value="[VersionFolder]pwsh.exe" KeyPath="yes"/>
<RegistryKey Key="Command">
<RegistryValue Type="string" Value="[VersionFolder]pwsh.exe -Command &quot;$host.UI.RawUI.WindowTitle = '$(var.ProductName) $(var.SimpleProductVersion) ($(sys.BUILDARCH))'; &amp; '%1'&quot;"/>
</RegistryKey>
</RegistryKey>
</Component>
<Component Id="SaveInstallerProperties" Permanent="yes">
<RegistryValue Root="HKLM" Key="$(var.InstallerPropertiesKey)" Name="InstallFolder" Value="[INSTALLFOLDER]" Type="string" />
<RegistryValue Root="HKLM" Key="$(var.InstallerPropertiesKey)" Name="AddToPath" Value="[ADD_PATH]" Type="string" />
<RegistryValue Root="HKLM" Key="$(var.InstallerPropertiesKey)" Name="RegisterManifest" Value="[REGISTER_MANIFEST]" Type="string" />
<RegistryValue Root="HKLM" Key="$(var.InstallerPropertiesKey)" Name="EnablePSRemoting" Value="[ENABLE_PSREMOTING]" Type="string" />
<RegistryValue Root="HKLM" Key="$(var.InstallerPropertiesKey)" Name="DisableTelemetry" Value="[DISABLE_TELEMETRY]" Type="string" />
<RegistryValue Root="HKLM" Key="$(var.InstallerPropertiesKey)" Name="AddExplorerContextMenuOpenPowerShell" Value="[ADD_EXPLORER_CONTEXT_MENU_OPENPOWERSHELL]" Type="string" />
<RegistryValue Root="HKLM" Key="$(var.InstallerPropertiesKey)" Name="AddFileContextMenuRunPowerShell" Value="[ADD_FILE_CONTEXT_MENU_RUNPOWERSHELL]" Type="string" />
<RegistryValue Root="HKLM" Key="$(var.InstallerPropertiesKey)" Name="UseMU" Value="[USE_MU]" Type="string" />
<RegistryValue Root="HKLM" Key="$(var.InstallerPropertiesKey)" Name="EnableMU" Value="[ENABLE_MU]" Type="string" />
</Component>
</Directory>
</Directory>
</Directory>
<Directory Id="ProgramMenuFolder">
<Directory Id="ApplicationProgramsFolder" Name="$(var.ProductName)">
<Component Id="ApplicationProgramsMenuShortcut">
<Shortcut Id="PowerShell_ProgramsMenuShortcut"
Name="$(var.ProductSimpleVersionWithNameAndOptionalArchitecture)"
Description="$(var.ProductSimpleVersionWithNameAndOptionalArchitecture)"
Target="[VersionFolder]pwsh.exe"
Arguments="-WorkingDirectory ~" />
<RemoveFolder Id="ApplicationProgramsFolder" On="uninstall"/>
<!-- HKMU is HKLM when installing perMachine and HKCU when installing perUser-->
<RegistryValue Root="HKMU" Key="Software\Microsoft\PowerShellCore\ProgramsMenuShortcut\$(var.SimpleProductVersion)" Name="installed" Type="integer" Value="1" KeyPath="yes"/>
</Component>
</Directory>
</Directory>
</Directory>
</Product>
<!-- Explorer Context Menu Dialog -->
<Fragment>
<UI>
<Dialog Id="ExplorerContextMenuDialog" Width="370" Height="270" Title="!(loc.ExitDialog_Title)">
<!-- Banner -->
<Control Id="BannerBitmap" Type="Bitmap" X="0" Y="0" Width="370" Height="44" TabSkip="yes" Text="!(loc.InstallDirDlgBannerBitmap)"/>
<Control Id="Title" Type="Text" X="15" Y="6" Width="200" Height="15" Transparent="yes" NoPrefix="yes" Text="{\WixUI_Font_Title}Optional Actions" TabSkip="yes" />
<Control Id="Description" Type="Text" X="25" Y="23" Width="280" Height="15" Transparent="yes" NoPrefix="yes" Text="Initialization and Customization" TabSkip="yes" />
<Control Id="BannerLine" Type="Line" X="0" Y="44" Width="370" Height="0" TabSkip="yes" />
<!-- If the checkboxes are defined first, then they are first in the tab order and can be ticked and unticked using the spacebar -->
<Control Id="AddToPathCheckBox" Type="CheckBox" X="20" Y="60" Width="290" Height="17" Property="ADD_PATH" CheckBoxValue="1" Text="Add $(var.ProductName) to Path Environment Variable"/>
<Control Id="RegisterManifestCheckBox" Type="CheckBox" X="20" Y="80" Width="290" Height="17" Property="REGISTER_MANIFEST" CheckBoxValue="1" Text="Register Windows Event Logging Manifest"/>
<Control Id="EnablePSRemotingCheckBox" Type="CheckBox" X="20" Y="100" Width="290" Height="17" Property="ENABLE_PSREMOTING" CheckBoxValue="1" Text="Enable $(var.ProductName) remoting"/>
<Control Id="DisableTelemetry" Type="CheckBox" X="20" Y="120" Width="290" Height="17" Property="DISABLE_TELEMETRY" CheckBoxValue="1" Text="Disable Telemetry (Reboot or Restart of processes may be required)" ToolTip="Sets environment variable POWERSHELL_TELEMETRY_OPTOUT to 1, see https://go.microsoft.com/fwlink/?linkid=2242006"/>
<Control Id="ContextMenuOpenPowerShell" Type="CheckBox" X="20" Y="140" Width="290" Height="17" Property="ADD_EXPLORER_CONTEXT_MENU_OPENPOWERSHELL" CheckBoxValue="1" Text="Add '$(var.ExplorerContextSubMenuDialogText)' context menus to Explorer"/>
<Control Id="ContextMenuRunPowerShell" Type="CheckBox" X="20" Y="160" Width="290" Height="17" Property="ADD_FILE_CONTEXT_MENU_RUNPOWERSHELL" CheckBoxValue="1" Text="Add '$(var.PowerShellFileContextSubMenuDialogText)' context menu for PowerShell files"/>
<Control Id="LicenseLink" Type="Hyperlink" X="20" Y="190" Width="214" Height="17">
<Text><![CDATA[<a href="https://github.com/PowerShell/PowerShell/blob/master/LICENSE.txt">The application is distributed under the MIT license.</a>]]></Text>
</Control>
<Control Id="TpnLink" Type="Hyperlink" X="20" Y="210" Width="290" Height="17">
<Text><![CDATA[<a href="https://github.com/PowerShell/PowerShell/blob/master/ThirdPartyNotices.txt">Please review the ThirdPartyNotices.txt</a>]]></Text>
</Control>
<!-- divider and bottom buttons -->
<Control Id="BottomLine" Type="Line" X="0" Y="234" Width="370" Height="0" TabSkip="yes"/>
<Control Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17" Text="!(loc.WixUIBack)"/>
<Control Id="Next" Type="PushButton" X="236" Y="243" Width="56" Height="17" Cancel="yes" Default="yes" Text="!(loc.WixUINext)"/>
<Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Cancel="yes" Text="!(loc.WixUICancel)">
<Publish Event="SpawnDialog" Value="CancelDlg">1</Publish>
</Control>
</Dialog>
</UI>
</Fragment>
<!-- Microsoft Update Menu Dialog -->
<Fragment>
<UI>
<Dialog Id="MuDialog" Width="370" Height="270" Title="!(loc.ExitDialog_Title)">
<!-- Banner -->
<Control Id="BannerBitmap" Type="Bitmap" X="0" Y="0" Width="370" Height="44" TabSkip="yes" Text="!(loc.InstallDirDlgBannerBitmap)"/>
<Control Id="Title" Type="Text" X="15" Y="6" Width="200" Height="30" Transparent="yes" NoPrefix="yes" Text="{\WixUI_Font_Title}Use Microsoft Update to help keep your computer secure and up to date" TabSkip="yes" />
<Control Id="BannerLine" Type="Line" X="0" Y="44" Width="370" Height="0" TabSkip="yes" />
<Control Id="Description" Type="Text" X="25" Y="54" Width="280" Height="100" Transparent="yes" NoPrefix="yes" Text="Microsoft Update helps keep your computer secure and up to date for Windows and other Microsoft products, including PowerShell 7. Updates will be delivered based on your current update settings. You can review or change these settings from the Windows Update control panel." TabSkip="yes" />
<!-- If the checkboxes are defined first, then they are first in the tab order and can be ticked and unticked using the spacebar -->
<Control Id="UseMuCheckBox" Type="CheckBox" X="20" Y="100" Width="290" Height="27" Property="USE_MU" CheckBoxValue="1" Text="Enable updating PowerShell through Microsoft Update or WSUS (recommended)"/>
<Control Id="EnableMuCheckBox" Type="CheckBox" X="20" Y="130" Width="290" Height="17" Property="ENABLE_MU" CheckBoxValue="1" Text="Use Microsoft Update when I check for updates (recommended)">
</Control>
<Control Id="MuWarningText" Type="Text" X="20" Y="160" Width="290" Height="27" Text="Without Microsoft Update enabled, you will need to use another update solution like WSUS or SCCM in order to receive automatic updates.">
<Condition Action="hide"><![CDATA[ENABLE_MU="1" OR USE_MU<>"1"]]></Condition>
<Condition Action="show"><![CDATA[ENABLE_MU<>"1" AND USE_MU="1"]]></Condition>
</Control>
<Control Id="MuFAQ" Type="Hyperlink" X="20" Y="190" Width="214" Height="17">
<Text><![CDATA[<a href="https://aka.ms/PowerShell-Microsoft-Update-FAQ">See the Microsoft Update FAQ</a>]]></Text>
</Control>
<Control Id="PrivacyLink" Type="Hyperlink" X="20" Y="210" Width="290" Height="17">
<Text><![CDATA[<a href="https://aka.ms/PowerShell-Microsoft-Update-Privacy-Statement">Read the Microsoft Update Privacy Statement</a>]]></Text>
</Control>
<!-- divider and bottom buttons -->
<Control Id="BottomLine" Type="Line" X="0" Y="234" Width="370" Height="0" TabSkip="yes"/>
<Control Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17" Text="!(loc.WixUIBack)"/>
<Control Id="Next" Type="PushButton" X="236" Y="243" Width="56" Height="17" Cancel="yes" Default="yes" Text="!(loc.WixUINext)"/>
<Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Cancel="yes" Text="!(loc.WixUICancel)">
<Publish Event="SpawnDialog" Value="CancelDlg">1</Publish>
</Control>
</Dialog>
</UI>
</Fragment>
<!-- Customized version of WixUI_InstallDir, which is necessary to add custom dialogs. https://github.com/wixtoolset/wix3/blob/master/src/ext/UIExtension/wixlib/WixUI_InstallDir.wxs -->
<Fragment>
<UI Id="CustomWixUI_InstallDir">
<!--
First-time install dialog sequence:
- WixUI_WelcomeDlg
- WixUI_InstallDirDlg
- ExplorerContextMenuDialog
- MuDialog
- WixUI_VerifyReadyDlg
- WixUI_DiskCostDlg
Maintenance dialog sequence:
- WixUI_MaintenanceWelcomeDlg
- WixUI_MaintenanceTypeDlg
- WixUI_InstallDirDlg
- WixUI_VerifyReadyDlg
Patch dialog sequence:
- WixUI_WelcomeDlg
- WixUI_VerifyReadyDlg
-->
<TextStyle Id="WixUI_Font_Normal" FaceName="Tahoma" Size="8" />
<TextStyle Id="WixUI_Font_Bigger" FaceName="Tahoma" Size="12" />
<TextStyle Id="WixUI_Font_Title" FaceName="Tahoma" Size="9" Bold="yes" />
<Property Id="DefaultUIFont" Value="WixUI_Font_Normal" />
<Property Id="WixUI_Mode" Value="InstallDir" />
<DialogRef Id="BrowseDlg" />
<DialogRef Id="DiskCostDlg" />
<DialogRef Id="ErrorDlg" />
<DialogRef Id="FatalError" />
<DialogRef Id="FilesInUse" />
<DialogRef Id="MsiRMFilesInUse" />
<DialogRef Id="PrepareDlg" />
<DialogRef Id="ProgressDlg" />
<DialogRef Id="ResumeDlg" />
<DialogRef Id="UserExit" />
<DialogRef Id="ExplorerContextMenuDialog" />
<Publish Dialog="BrowseDlg" Control="OK" Event="DoAction" Value="WixUIValidatePath" Order="3">1</Publish>
<Publish Dialog="BrowseDlg" Control="OK" Event="SpawnDialog" Value="InvalidDirDlg" Order="4"><![CDATA[NOT WIXUI_DONTVALIDATEPATH AND WIXUI_INSTALLDIR_VALID<>"1"]]></Publish>
<Publish Dialog="WelcomeDlg" Control="Next" Event="NewDialog" Value="InstallDirDlg">NOT Installed</Publish>
<Publish Dialog="WelcomeDlg" Control="Next" Event="NewDialog" Value="VerifyReadyDlg">Installed AND PATCH</Publish>
<Publish Dialog="ExplorerContextMenuDialog" Control="Back" Event="NewDialog" Value="WelcomeDlg">1</Publish>
<Publish Dialog="ExplorerContextMenuDialog" Control="Next" Event="NewDialog" Value="MuDialog">1</Publish>
<Publish Dialog="MuDialog" Control="Back" Event="NewDialog" Value="ExplorerContextMenuDialog">1</Publish>
<Publish Dialog="MuDialog" Control="Next" Event="NewDialog" Value="VerifyReadyDlg" Order="2">1</Publish>
<Publish Dialog="InstallDirDlg" Control="Back" Event="NewDialog" Value="WelcomeDlg">1</Publish>
<Publish Dialog="InstallDirDlg" Control="Next" Event="SetTargetPath" Value="[WIXUI_INSTALLDIR]" Order="1">1</Publish>
<Publish Dialog="InstallDirDlg" Control="Next" Event="DoAction" Value="WixUIValidatePath" Order="2">NOT WIXUI_DONTVALIDATEPATH</Publish>
<Publish Dialog="InstallDirDlg" Control="Next" Event="SpawnDialog" Value="InvalidDirDlg" Order="3"><![CDATA[NOT WIXUI_DONTVALIDATEPATH AND WIXUI_INSTALLDIR_VALID<>"1"]]></Publish>
<Publish Dialog="InstallDirDlg" Control="Next" Event="NewDialog" Value="VerifyReadyDlg" Order="4">WIXUI_DONTVALIDATEPATH OR WIXUI_INSTALLDIR_VALID="1"</Publish>
<Publish Dialog="InstallDirDlg" Control="Next" Event="NewDialog" Value="ExplorerContextMenuDialog" Order="5">1</Publish>
<Publish Dialog="InstallDirDlg" Control="ChangeFolder" Property="_BrowseProperty" Value="[WIXUI_INSTALLDIR]" Order="1">1</Publish>
<Publish Dialog="InstallDirDlg" Control="ChangeFolder" Event="SpawnDialog" Value="BrowseDlg" Order="2">1</Publish>
<Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="MuDialog" Order="1">NOT Installed</Publish>
<Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="MaintenanceTypeDlg" Order="2">Installed AND NOT PATCH</Publish>
<Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="WelcomeDlg" Order="2">Installed AND PATCH</Publish>
<Publish Dialog="MaintenanceWelcomeDlg" Control="Next" Event="NewDialog" Value="MaintenanceTypeDlg">1</Publish>
<Publish Dialog="MaintenanceTypeDlg" Control="RepairButton" Event="NewDialog" Value="VerifyReadyDlg">1</Publish>
<Publish Dialog="MaintenanceTypeDlg" Control="RemoveButton" Event="NewDialog" Value="VerifyReadyDlg">1</Publish>
<Publish Dialog="MaintenanceTypeDlg" Control="Back" Event="NewDialog" Value="MaintenanceWelcomeDlg">1</Publish>
<Property Id="ARPNOMODIFY" Value="1" />
</UI>
<UIRef Id="WixUI_Common" />
</Fragment>
</Wix>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

-40
View File
@@ -1,40 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:bal="http://schemas.microsoft.com/wix/BalExtension">
<!-- UpgradeCode GUID MUST REMAIN SAME THROUGHOUT ALL VERSIONS, otherwise, updates won't occur. -->
<?if $(sys.BUILDARCH)=x64?>
<?define UpgradeCodePreview = "3C90221B-D500-43C6-A4A6-0BE6C2C1B317"?>
<?define UpgradeCodeRelease = "7A804CBB-648E-4276-9A58-081862DB1B99"?>
<?if $(var.IsPreview)=True?>
<?define UpgradeCode = $(var.UpgradeCodePreview)?>
<?else?>
<?define UpgradeCode = $(var.UpgradeCodeRelease)?>
<?endif?>
<?elseif $(sys.BUILDARCH) = "ARM64"?>
<?define ExplorerContextMenuDialogText = "&$(var.ProductName) $(var.SimpleProductVersion) ($(sys.BUILDARCH))"?>
<?define UpgradeCodePreview = "499e9123-48aa-41df-aa20-6f4d28b54722"?>
<?define UpgradeCodeRelease = "4cc0e36a-17db-4c84-b4f4-560a11e7ddb6"?>
<?if $(var.IsPreview)=True?>
<?define UpgradeCode = $(var.UpgradeCodePreview)?>
<?else?>
<?define UpgradeCode = $(var.UpgradeCodeRelease)?>
<?endif?>
<?else?>
<?define UpgradeCodePreview = "4A699A9C-E904-4024-BCD2-44E098A8C6BD"?>
<?define UpgradeCodeRelease = "ED46CB02-64B3-43FD-A63E-6CF269D8C21C"?>
<?if $(var.IsPreview)=True?>
<?define UpgradeCode = $(var.UpgradeCodePreview)?>
<?else?>
<?define UpgradeCode = $(var.UpgradeCodeRelease)?>
<?endif?>
<?endif?>
<Bundle Name="PowerShell $(var.WindowsVersion)-$(sys.BUILDARCH)" Version="$(var.WindowsVersion)" Manufacturer="Microsoft Corporation" UpgradeCode="$(var.UpgradeCode)">
<!-- See https://wixtoolset.org/documentation/manual/v3/bundle/wixstdba/ for a list of WiX standard bootstrapper types. -->
<BootstrapperApplicationRef Id="WixStandardBootstrapperApplication.RtfLicense">
<bal:WixStandardBootstrapperApplication LicenseFile="assets\wix\ExeLicense.rtf" LogoFile="assets\ps_black_32x32.ico" />
</BootstrapperApplicationRef>
<Chain>
<MsiPackage SourceFile="$(var.TargetPath)" Compressed="yes" />
</Chain>
</Bundle>
</Wix>
-5
View File
@@ -3003,11 +3003,6 @@ function Start-PSBootstrap {
$psInstallFile = [System.IO.Path]::Combine($PSScriptRoot, "tools", "install-powershell.ps1")
& $psInstallFile -AddToPath
}
if ($Scenario -eq 'Both' -or $Scenario -eq 'Package') {
Import-Module "$PSScriptRoot\tools\wix\wix.psm1"
$isArm64 = "$env:RUNTIME" -eq 'arm64'
Install-Wix -arm64:$isArm64
}
Write-LogGroupEnd -Title "Install Windows Dependencies"
}
+4 -8
View File
@@ -57,17 +57,13 @@ It **requires** that PowerShell Core has been built via `Start-PSBuild` from the
#### Windows
The `Start-PSPackage` function delegates to `New-MSIPackage` which creates a Windows Installer Package of PowerShell.
`Start-PSPackage` supports creating ZIP and MSIX packages for Windows.
When called without `-Type` on Windows, it defaults to creating both ZIP and MSIX packages.
The packages *must* be published in release mode,
so make sure `-Configuration Release` is specified when running `Start-PSBuild`.
It uses the Windows Installer XML Toolset (WiX) to generate a MSI package,
which copies the output of the published PowerShell files to a version-specific folder in Program Files,
and installs a shortcut in the Start Menu.
It can be uninstalled through `Programs and Features`.
Note that PowerShell is always self-contained, thus using it does not require installing it.
The output of `Start-PSBuild` includes a `powershell.exe` executable which can simply be launched.
The output of `Start-PSBuild` includes a `pwsh.exe` executable which can simply be launched.
#### Linux / macOS
@@ -169,8 +165,8 @@ Start-PSBuild -Clean -CrossGen -PSModuleRestore -Runtime win7-x64 -Configuration
```powershell
# Create packages for v6.0.0-beta.1 release targeting Windows universal package.
# 'win7-x64' / 'win7-x86' should be used for -WindowsRuntime.
Start-PSPackage -Type msi -ReleaseTag v6.0.0-beta.1 -WindowsRuntime 'win7-x64'
Start-PSPackage -Type zip -ReleaseTag v6.0.0-beta.1 -WindowsRuntime 'win7-x64'
Start-PSPackage -Type msix -ReleaseTag v6.0.0-beta.1 -WindowsRuntime 'win7-x64'
```
## NuGet Packages
@@ -33,7 +33,7 @@
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
<Content Include="..\..\LICENSE.txt;..\..\ThirdPartyNotices.txt;..\powershell-native\Install-PowerShellRemoting.ps1;..\PowerShell.Core.Instrumentation\PowerShell.Core.Instrumentation.man;..\PowerShell.Core.Instrumentation\RegisterManifest.ps1;..\..\assets\MicrosoftUpdate\RegisterMicrosoftUpdate.ps1;..\..\assets\GroupPolicy\PowerShellCoreExecutionPolicy.admx;..\..\assets\GroupPolicy\PowerShellCoreExecutionPolicy.adml;..\..\assets\GroupPolicy\InstallPSCorePolicyDefinitions.ps1">
<Content Include="..\..\LICENSE.txt;..\..\ThirdPartyNotices.txt;..\powershell-native\Install-PowerShellRemoting.ps1;..\PowerShell.Core.Instrumentation\PowerShell.Core.Instrumentation.man;..\PowerShell.Core.Instrumentation\RegisterManifest.ps1;..\..\assets\GroupPolicy\PowerShellCoreExecutionPolicy.admx;..\..\assets\GroupPolicy\PowerShellCoreExecutionPolicy.adml;..\..\assets\GroupPolicy\InstallPSCorePolicyDefinitions.ps1">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
@@ -2238,26 +2238,6 @@ function Start-PSPackage {
}
}
}
"msi" {
$TargetArchitecture = "x64"
if ($Runtime -match "-x86") {
$TargetArchitecture = "x86"
}
Write-Verbose "TargetArchitecture = $TargetArchitecture" -Verbose
$Arguments = @{
ProductNameSuffix = $NameSuffix
ProductSourcePath = $Source
ProductVersion = $Version
AssetsPath = "$RepoRoot\assets"
ProductTargetArchitecture = $TargetArchitecture
Force = $Force
}
if ($PSCmdlet.ShouldProcess("Create MSI Package")) {
New-MSIPackage @Arguments
}
}
"msix" {
$Arguments = @{
ProductNameSuffix = $NameSuffix
@@ -1,39 +0,0 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
Describe "Windows Installer" -Tags "Scenario" {
BeforeAll {
$skipTest = -not $IsWindows
$preRequisitesLink = 'https://aka.ms/pscore6-prereq'
$linkCheckTestCases = @(
@{ Name = "Universal C Runtime"; Url = $preRequisitesLink }
@{ Name = "WMF 4.0"; Url = "https://www.microsoft.com/download/details.aspx?id=40855" }
@{ Name = "WMF 5.0"; Url = "https://www.microsoft.com/download/details.aspx?id=50395" }
@{ Name = "WMF 5.1"; Url = "https://www.microsoft.com/download/details.aspx?id=54616" }
)
}
It "WiX (Windows Installer XML) file contains pre-requisites link $preRequisitesLink" -Skip:$skipTest {
$wixProductFile = Join-Path -Path $PSScriptRoot -ChildPath "..\..\..\assets\wix\Product.wxs"
(Get-Content $wixProductFile -Raw).Contains($preRequisitesLink) | Should -BeTrue
}
## Running 'Invoke-WebRequest' with WMF download URLs has been failing intermittently,
## because sometimes the URLs lead to a 'this download is no longer available' page.
## We use a retry logic here. Retry for 5 times with 1 second interval.
# It "Pre-Requisistes link for '<Name>' is reachable: <url>" -TestCases $linkCheckTestCases -Skip:$skipTest {
It "Pre-Requisistes link for '<Name>' is reachable: <url>" -TestCases $linkCheckTestCases -Pending {
param ($Url)
foreach ($i in 1..5) {
try {
$result = Invoke-WebRequest $Url -UseBasicParsing
break;
} catch {
Start-Sleep -Seconds 1
}
}
$result | Should -Not -Be $null
}
}
-28
View File
@@ -9,9 +9,6 @@ param (
[Parameter()]
[switch]$UseNuGetOrg,
[Parameter()]
[switch]$UpdateMSIPackaging,
[Parameter()]
[string]$RuntimeSourceFeed,
@@ -366,31 +363,6 @@ if ($dotnetUpdate.ShouldUpdate) {
Write-Verbose -Message "Updating project files completed." -Verbose
if ($UpdateMSIPackaging) {
if (-not $environment.IsWindows) {
throw "UpdateMSIPackaging can only be done on Windows"
}
Import-Module "$PSScriptRoot/../build.psm1" -Force
Import-Module "$PSScriptRoot/packaging" -Force
Start-PSBootstrap -Package
Start-PSBuild -Clean -Configuration Release -InteractiveAuth:$InteractiveAuth
$publishPath = Split-Path (Get-PSOutput)
Remove-Item -Path "$publishPath\*.pdb"
try {
Start-PSPackage -Type msi -SkipReleaseChecks -InformationVariable wxsData
} catch {
if ($_.Exception.Message -like "Current files to not match *") {
Copy-Item -Path $($wxsData.MessageData.NewFile) -Destination ($wxsData.MessageData.FilesWxsPath)
Write-Verbose -Message "Updating files.wxs file completed." -Verbose
} else {
throw $_
}
}
}
Update-DevContainer
}
else {
+12 -54
View File
@@ -241,7 +241,7 @@ function Install-CIPester
Write-Verbose "Checking for Pester module (required: $MinimumVersion - $MaximumVersion)" -Verbose
# Check if a compatible version of Pester is already installed
$installedPester = Get-Module -Name Pester -ListAvailable |
$installedPester = Get-Module -Name Pester -ListAvailable |
Where-Object { $_.Version -ge $MinimumVersion -and $_.Version -le $MaximumVersion } |
Sort-Object -Property Version -Descending |
Select-Object -First 1
@@ -616,20 +616,9 @@ function Invoke-CIFinish
Restore-PSOptions -PSOptionsPath "${buildFolder}/psoptions.json"
$preReleaseVersion = $env:CI_FINISH_RELASETAG
# Build packages $preReleaseVersion = "$previewPrefix-$previewLabel.$prereleaseIteration"
switch -regex ($Runtime){
default {
$runPackageTest = $true
$packageTypes = 'msi', 'zip', 'zip-pdb', 'msix'
}
'win-arm.*' {
$runPackageTest = $false
$packageTypes = 'msi', 'zip', 'zip-pdb', 'msix'
}
}
# Build packages
$packageTypes = 'zip', 'zip-pdb', 'msix'
Import-Module "$PSScriptRoot\wix\wix.psm1"
Install-Wix -arm64:$true
$packages = Start-PSPackage -Type $packageTypes -ReleaseTag $preReleaseVersion -SkipReleaseChecks -WindowsRuntime $Runtime
foreach ($package in $packages) {
@@ -641,40 +630,9 @@ function Invoke-CIFinish
if ($package -is [string]) {
$null = $artifacts.Add($package)
} elseif ($package -is [pscustomobject] -and $package.psobject.Properties['msi']) {
$null = $artifacts.Add($package.msi)
$null = $artifacts.Add($package.wixpdb)
}
}
if ($runPackageTest) {
# the packaging tests find the MSI package using env:PSMsiX64Path
$env:PSMsiX64Path = $artifacts | Where-Object { $_.EndsWith(".msi")}
$architechture = $Runtime.Split('-')[1]
$exePath = New-ExePackage -ProductVersion ($preReleaseVersion -replace '^v') -ProductTargetArchitecture $architechture -MsiLocationPath $env:PSMsiX64Path
Write-Verbose "exe Path: $exePath" -Verbose
$artifacts.Add($exePath)
$env:PSExePath = $exePath
$env:PSMsiChannel = $Channel
$env:PSMsiRuntime = $Runtime
# Install the latest Pester and import it
$maximumPesterVersion = '4.99'
Install-CIPester -MinimumVersion '4.0.0' -MaximumVersion $maximumPesterVersion -Force
Import-Module Pester -Force -MaximumVersion $maximumPesterVersion
$testResultPath = Join-Path -Path $env:TEMP -ChildPath "win-package-$channel-$runtime.xml"
# start the packaging tests and get the results
$packagingTestResult = Invoke-Pester -Script (Join-Path $repoRoot '.\test\packaging\windows\') -PassThru -OutputFormat NUnitXml -OutputFile $testResultPath
Publish-TestResults -Title "win-package-$channel-$runtime" -Path $testResultPath
# fail the CI job if the tests failed, or nothing passed
if (-not $packagingTestResult -is [pscustomobject] -or $packagingTestResult.FailedCount -ne 0 -or $packagingTestResult.PassedCount -eq 0) {
throw "Packaging tests failed ($($packagingTestResult.FailedCount) failed/$($packagingTestResult.PassedCount) passed)"
}
}
}
} catch {
Get-Error -InputObject $_
@@ -932,12 +890,12 @@ function New-LinuxPackage
} else {
"${env:BUILD_ARTIFACTSTAGINGDIRECTORY}"
}
# Ensure artifacts directory exists
if (-not (Test-Path $artifactsDir)) {
New-Item -ItemType Directory -Path $artifactsDir -Force | Out-Null
}
Write-Log -message "Artifacts directory: $artifactsDir"
Copy-Item $packageObj.FullName -Destination $artifactsDir -Force
}
@@ -950,7 +908,7 @@ function New-LinuxPackage
} else {
"${env:BUILD_ARTIFACTSTAGINGDIRECTORY}"
}
# Create and package Raspbian .tgz
# Build must be clean for Raspbian
Start-PSBuild -PSModuleRestore -Clean -Runtime linux-arm -Configuration 'Release'
@@ -1062,13 +1020,13 @@ Function Test-MergeConflictMarker
[string]$OutputPath,
[string]$SummaryPath
)
# Output results to GitHub Actions
if ($OutputPath) {
"files-checked=0" | Out-File -FilePath $OutputPath -Append -Encoding utf8
"conflicts-found=0" | Out-File -FilePath $OutputPath -Append -Encoding utf8
}
# Create GitHub Actions job summary
if ($SummaryPath) {
$summaryContent = @"
@@ -1097,11 +1055,11 @@ $Message
# Filter out *.cs files from merge conflict checking
$filesToCheck = @($File | Where-Object { $_ -notlike "*.cs" })
$filteredCount = $File.Count - $filesToCheck.Count
if ($filteredCount -gt 0) {
Write-Host "Filtered out $filteredCount *.cs file(s) from merge conflict checking" -ForegroundColor Yellow
}
if ($filesToCheck.Count -eq 0) {
Write-Host "No files to check after filtering (all files were *.cs)" -ForegroundColor Yellow
Write-NoFilesOutput -Message "All $filteredCount file(s) were filtered out (*.cs files are excluded from merge conflict checking)." -OutputPath $OutputPath -SummaryPath $SummaryPath
@@ -1135,14 +1093,14 @@ $Message
}
$filesChecked++
# Get relative path for display
$relativePath = if ($WorkspacePath -and $filePath.StartsWith($WorkspacePath)) {
$filePath.Substring($WorkspacePath.Length).TrimStart([System.IO.Path]::DirectorySeparatorChar, [System.IO.Path]::AltDirectorySeparatorChar)
} else {
$filePath
}
Write-Host " Checking: $relativePath" -ForegroundColor Gray
# Search for conflict markers using Select-String
-5
View File
@@ -4616,11 +4616,6 @@
"FileType": "Product",
"Architecture": null
},
{
"Pattern": "RegisterMicrosoftUpdate.ps1",
"FileType": "Product",
"Architecture": null
},
{
"Pattern": "System.Management.Automation.dll",
"FileType": "Product",
-3
View File
@@ -7,13 +7,10 @@
PowerShellVersion = "5.0"
CmdletsToExport = @()
FunctionsToExport = @(
'Compress-ExePackageEngine'
'Expand-ExePackageEngine'
'Expand-PSSignedBuild'
'Invoke-AzDevOpsLinuxPackageBuild'
'Invoke-AzDevOpsLinuxPackageCreation'
'New-DotnetSdkContainerFxdPackage'
'New-ExePackage'
'Start-PrepForGlobalToolNupkg'
'New-GlobalToolNupkgSource'
'New-GlobalToolNupkgFromSource'
+3 -467
View File
@@ -52,7 +52,7 @@ function Start-PSPackage {
[string]$Name = "powershell",
# Ubuntu, CentOS, Fedora, macOS, and Windows packages are supported
[ValidateSet("msix", "deb", "osxpkg", "rpm", "rpm-fxdependent", "rpm-fxdependent-arm64", "msi", "zip", "zip-pdb", "tar", "tar-arm", "tar-arm64", "tar-alpine", "fxdependent", "fxdependent-win-desktop", "min-size", "tar-alpine-fxdependent")]
[ValidateSet("msix", "deb", "osxpkg", "rpm", "rpm-fxdependent", "rpm-fxdependent-arm64", "zip", "zip-pdb", "tar", "tar-arm", "tar-arm64", "tar-alpine", "fxdependent", "fxdependent-win-desktop", "min-size", "tar-alpine-fxdependent")]
[string[]]$Type,
# Generate windows downlevel package
@@ -346,7 +346,7 @@ function Start-PSPackage {
} elseif ($Environment.IsMacOS) {
"osxpkg", "tar"
} elseif ($Environment.IsWindows) {
"msi", "msix"
"zip", "msix"
}
Write-Warning "-Type was not specified, continuing with $Type!"
}
@@ -493,34 +493,6 @@ function Start-PSPackage {
}
}
}
"msi" {
$TargetArchitecture = "x64"
$r2rArchitecture = "amd64"
if ($Runtime -match "-x86") {
$TargetArchitecture = "x86"
$r2rArchitecture = "i386"
}
elseif ($Runtime -match "-arm64")
{
$TargetArchitecture = "arm64"
$r2rArchitecture = "arm64"
}
Write-Verbose "TargetArchitecture = $TargetArchitecture" -Verbose
$Arguments = @{
ProductNameSuffix = $NameSuffix
ProductSourcePath = $Source
ProductVersion = $Version
AssetsPath = "$RepoRoot\assets"
ProductTargetArchitecture = $TargetArchitecture
Force = $Force
}
if ($PSCmdlet.ShouldProcess("Create MSI Package")) {
New-MSIPackage @Arguments
}
}
"msix" {
$Arguments = @{
ProductNameSuffix = $NameSuffix
@@ -3769,443 +3741,6 @@ function Get-NugetSemanticVersion
$packageSemanticVersion
}
# Get the paths to various WiX tools
function Get-WixPath
{
[CmdletBinding()]
param (
[bool] $IsProductArchitectureArm = $false
)
$wixToolsetBinPath = $IsProductArchitectureArm ? "${env:ProgramFiles(x86)}\Arm Support WiX Toolset *\bin" : "${env:ProgramFiles(x86)}\WiX Toolset *\bin"
Write-Verbose -Verbose "Ensure Wix Toolset is present on the machine @ $wixToolsetBinPath"
if (-not (Test-Path $wixToolsetBinPath))
{
if (!$IsProductArchitectureArm)
{
throw "The latest version of Wix Toolset 3.11 is required to create MSI package. Please install it from https://github.com/wixtoolset/wix3/releases"
}
else {
throw "The latest version of Wix Toolset 3.14 is required to create MSI package for arm. Please install it from https://aka.ms/ps-wix-3-14-zip"
}
}
## Get the latest if multiple versions exist.
$wixToolsetBinPath = (Get-ChildItem $wixToolsetBinPath).FullName | Sort-Object -Descending | Select-Object -First 1
Write-Verbose "Initialize Wix executables..."
$wixHeatExePath = Join-Path $wixToolsetBinPath "heat.exe"
$wixMeltExePath = Join-Path $wixToolsetBinPath "melt.exe"
$wixTorchExePath = Join-Path $wixToolsetBinPath "torch.exe"
$wixPyroExePath = Join-Path $wixToolsetBinPath "pyro.exe"
$wixCandleExePath = Join-Path $wixToolsetBinPath "Candle.exe"
$wixLightExePath = Join-Path $wixToolsetBinPath "Light.exe"
$wixInsigniaExePath = Join-Path $wixToolsetBinPath "Insignia.exe"
return [PSCustomObject] @{
WixHeatExePath = $wixHeatExePath
WixMeltExePath = $wixMeltExePath
WixTorchExePath = $wixTorchExePath
WixPyroExePath = $wixPyroExePath
WixCandleExePath = $wixCandleExePath
WixLightExePath = $wixLightExePath
WixInsigniaExePath = $wixInsigniaExePath
}
}
<#
.Synopsis
Creates a Windows installer MSI package and assumes that the binaries are already built using 'Start-PSBuild'.
This only works on a Windows machine due to the usage of WiX.
.EXAMPLE
# This example shows how to produce a Debug-x64 installer for development purposes.
cd $RootPathOfPowerShellRepo
Import-Module .\build.psm1; Import-Module .\tools\packaging\packaging.psm1
New-MSIPackage -Verbose -ProductSourcePath '.\src\powershell-win-core\bin\Debug\net8.0\win7-x64\publish' -ProductTargetArchitecture x64 -ProductVersion '1.2.3'
#>
function New-MSIPackage
{
[CmdletBinding()]
param (
# Name of the Product
[ValidateNotNullOrEmpty()]
[string] $ProductName = 'PowerShell',
# Suffix of the Name
[string] $ProductNameSuffix,
# Version of the Product
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[string] $ProductVersion,
# Source Path to the Product Files - required to package the contents into an MSI
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[string] $ProductSourcePath,
# File describing the MSI Package creation semantics
[ValidateNotNullOrEmpty()]
[ValidateScript( {Test-Path $_})]
[string] $ProductWxsPath = "$RepoRoot\assets\wix\Product.wxs",
# File describing the MSI Package creation semantics
[ValidateNotNullOrEmpty()]
[ValidateScript({Test-Path $_})]
[string] $BundleWxsPath = "$RepoRoot\assets\wix\bundle.wxs",
# Path to Assets folder containing artifacts such as icons, images
[ValidateNotNullOrEmpty()]
[ValidateScript( {Test-Path $_})]
[string] $AssetsPath = "$RepoRoot\assets",
# Architecture to use when creating the MSI
[Parameter(Mandatory = $true)]
[ValidateSet("x86", "x64", "arm64")]
[ValidateNotNullOrEmpty()]
[string] $ProductTargetArchitecture,
# Force overwrite of package
[Switch] $Force,
[string] $CurrentLocation = (Get-Location)
)
$wixPaths = Get-WixPath -IsProductArchitectureArm ($ProductTargetArchitecture -eq "arm64")
$windowsNames = Get-WindowsNames -ProductName $ProductName -ProductNameSuffix $ProductNameSuffix -ProductVersion $ProductVersion
$productSemanticVersionWithName = $windowsNames.ProductSemanticVersionWithName
$ProductSemanticVersion = $windowsNames.ProductSemanticVersion
$packageName = $windowsNames.PackageName
$ProductVersion = $windowsNames.ProductVersion
Write-Verbose "Create MSI for Product $productSemanticVersionWithName" -Verbose
Write-Verbose "ProductSemanticVersion = $productSemanticVersion" -Verbose
Write-Verbose "packageName = $packageName" -Verbose
Write-Verbose "ProductVersion = $ProductVersion" -Verbose
$simpleProductVersion = [string]([Version]$ProductVersion).Major
$isPreview = Test-IsPreview -Version $ProductSemanticVersion
if ($isPreview)
{
$simpleProductVersion += '-preview'
}
$staging = "$PSScriptRoot/staging"
New-StagingFolder -StagingPath $staging -PackageSourcePath $ProductSourcePath
$assetsInSourcePath = Join-Path $staging 'assets'
New-Item $assetsInSourcePath -type directory -Force | Write-Verbose
Write-Verbose "Place dependencies such as icons to $assetsInSourcePath"
Copy-Item "$AssetsPath\*.ico" $assetsInSourcePath -Force
$fileArchitecture = 'amd64'
$ProductProgFilesDir = "ProgramFiles64Folder"
if ($ProductTargetArchitecture -eq "x86")
{
$fileArchitecture = 'x86'
$ProductProgFilesDir = "ProgramFilesFolder"
}
elseif ($ProductTargetArchitecture -eq "arm64")
{
$fileArchitecture = 'arm64'
$ProductProgFilesDir = "ProgramFiles64Folder"
}
$wixFragmentPath = Join-Path $env:Temp "Fragment.wxs"
# cleanup any garbage on the system
Remove-Item -ErrorAction SilentlyContinue $wixFragmentPath -Force
$msiLocationPath = Join-Path $CurrentLocation "$packageName.msi"
$msiPdbLocationPath = Join-Path $CurrentLocation "$packageName.wixpdb"
if (!$Force.IsPresent -and (Test-Path -Path $msiLocationPath)) {
Write-Error -Message "Package already exists, use -Force to overwrite, path: $msiLocationPath" -ErrorAction Stop
}
Write-Log "Generating wxs file manifest..."
$arguments = @{
IsPreview = $isPreview
ProductSourcePath = $staging
ProductName = $ProductName
ProductVersion = $ProductVersion
SimpleProductVersion = $simpleProductVersion
ProductSemanticVersion = $ProductSemanticVersion
ProductVersionWithName = $productVersionWithName
ProductProgFilesDir = $ProductProgFilesDir
FileArchitecture = $fileArchitecture
}
$buildArguments = New-MsiArgsArray -Argument $arguments
Test-Bom -Path $staging -BomName windows -Architecture $ProductTargetArchitecture -Verbose
Start-NativeExecution -VerboseOutputOnError { & $wixPaths.wixHeatExePath dir $staging -dr VersionFolder -cg ApplicationFiles -ag -sfrag -srd -scom -sreg -out $wixFragmentPath -var var.ProductSourcePath $buildArguments -v}
Send-AzdoFile -Path $wixFragmentPath
$wixObjFragmentPath = Join-Path $env:Temp "Fragment.wixobj"
# cleanup any garbage on the system
Remove-Item -ErrorAction SilentlyContinue $wixObjFragmentPath -Force
Start-MsiBuild -WxsFile $ProductWxsPath, $wixFragmentPath -ProductTargetArchitecture $ProductTargetArchitecture -Argument $arguments -MsiLocationPath $msiLocationPath -MsiPdbLocationPath $msiPdbLocationPath
Remove-Item -ErrorAction SilentlyContinue $wixFragmentPath -Force
if ((Test-Path $msiLocationPath) -and (Test-Path $msiPdbLocationPath))
{
Write-Verbose "You can find the WixPdb @ $msiPdbLocationPath" -Verbose
Write-Verbose "You can find the MSI @ $msiLocationPath" -Verbose
[pscustomobject]@{
msi=$msiLocationPath
wixpdb=$msiPdbLocationPath
}
}
else
{
$errorMessage = "Failed to create $msiLocationPath"
throw $errorMessage
}
}
function Get-WindowsNames {
param(
# Name of the Product
[ValidateNotNullOrEmpty()]
[string] $ProductName = 'PowerShell',
# Suffix of the Name
[string] $ProductNameSuffix,
# Version of the Product
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[string] $ProductVersion
)
Write-Verbose -Message "Getting Windows Names for ProductName: $ProductName; ProductNameSuffix: $ProductNameSuffix; ProductVersion: $ProductVersion" -Verbose
$ProductSemanticVersion = Get-PackageSemanticVersion -Version $ProductVersion
$ProductVersion = Get-PackageVersionAsMajorMinorBuildRevision -Version $ProductVersion -IncrementBuildNumber
$productVersionWithName = $ProductName + '_' + $ProductVersion
$productSemanticVersionWithName = $ProductName + '-' + $ProductSemanticVersion
$packageName = $productSemanticVersionWithName
if ($ProductNameSuffix) {
$packageName += "-$ProductNameSuffix"
}
return [PSCustomObject]@{
PackageName = $packageName
ProductVersionWithName = $productVersionWithName
ProductSemanticVersion = $ProductSemanticVersion
ProductSemanticVersionWithName = $productSemanticVersionWithName
ProductVersion = $ProductVersion
}
}
function New-ExePackage {
param(
# Name of the Product
[ValidateNotNullOrEmpty()]
[string] $ProductName = 'PowerShell',
# Version of the Product
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[string] $ProductVersion,
# File describing the MSI Package creation semantics
[ValidateNotNullOrEmpty()]
[ValidateScript({Test-Path $_})]
[string] $BundleWxsPath = "$RepoRoot\assets\wix\bundle.wxs",
# Architecture to use when creating the MSI
[Parameter(Mandatory = $true)]
[ValidateSet("x86", "x64", "arm64")]
[ValidateNotNullOrEmpty()]
[string] $ProductTargetArchitecture,
# Location of the signed MSI
[Parameter(Mandatory = $true)]
[string]
$MsiLocationPath,
[string] $CurrentLocation = (Get-Location)
)
$productNameSuffix = "win-$ProductTargetArchitecture"
$windowsNames = Get-WindowsNames -ProductName $ProductName -ProductNameSuffix $productNameSuffix -ProductVersion $ProductVersion
$productSemanticVersionWithName = $windowsNames.ProductSemanticVersionWithName
$packageName = $windowsNames.PackageName
$isPreview = Test-IsPreview -Version $windowsNames.ProductSemanticVersion
Write-Verbose "Create EXE for Product $productSemanticVersionWithName" -verbose
Write-Verbose "packageName = $packageName" -Verbose
$exeLocationPath = Join-Path $CurrentLocation "$packageName.exe"
$exePdbLocationPath = Join-Path $CurrentLocation "$packageName.exe.wixpdb"
$windowsVersion = Get-WindowsVersion -packageName $packageName
Start-MsiBuild -WxsFile $BundleWxsPath -ProductTargetArchitecture $ProductTargetArchitecture -Argument @{
IsPreview = $isPreview
TargetPath = $MsiLocationPath
WindowsVersion = $windowsVersion
} -MsiLocationPath $exeLocationPath -MsiPdbLocationPath $exePdbLocationPath
return $exeLocationPath
}
<#
Allows you to extract the engine of exe package, mainly for signing
Any existing signature will be removed.
#>
function Expand-ExePackageEngine {
param(
# Location of the unsigned EXE
[Parameter(Mandatory = $true)]
[string]
$ExePath,
# Location to put the expanded engine.
[Parameter(Mandatory = $true)]
[string]
$EnginePath,
[Parameter(Mandatory = $true)]
[ValidateSet("x86", "x64", "arm64")]
[ValidateNotNullOrEmpty()]
[string] $ProductTargetArchitecture
)
<#
2. detach the engine from TestInstaller.exe:
insignia -ib TestInstaller.exe -o engine.exe
#>
$wixPaths = Get-WixPath -IsProductArchitectureArm ($ProductTargetArchitecture -eq "arm64")
$resolvedExePath = (Resolve-Path -Path $ExePath).ProviderPath
$resolvedEnginePath = [System.IO.Path]::GetFullPath($EnginePath)
Start-NativeExecution -VerboseOutputOnError { & $wixPaths.wixInsigniaExePath -ib $resolvedExePath -o $resolvedEnginePath}
}
<#
Allows you to replace the engine (installer) in the exe package.
Used to replace the engine with a signed version
#>
function Compress-ExePackageEngine {
param(
# Location of the unsigned EXE
[Parameter(Mandatory = $true)]
[string]
$ExePath,
# Location of the signed engine
[Parameter(Mandatory = $true)]
[string]
$EnginePath,
[Parameter(Mandatory = $true)]
[ValidateSet("x86", "x64", "arm64")]
[ValidateNotNullOrEmpty()]
[string] $ProductTargetArchitecture
)
<#
4. re-attach the signed engine.exe to the bundle:
insignia -ab engine.exe TestInstaller.exe -o TestInstaller.exe
#>
$wixPaths = Get-WixPath -IsProductArchitectureArm ($ProductTargetArchitecture -eq "arm64")
$resolvedEnginePath = (Resolve-Path -Path $EnginePath).ProviderPath
$resolvedExePath = (Resolve-Path -Path $ExePath).ProviderPath
Start-NativeExecution -VerboseOutputOnError { & $wixPaths.wixInsigniaExePath -ab $resolvedEnginePath $resolvedExePath -o $resolvedExePath}
}
function New-MsiArgsArray {
param(
[Parameter(Mandatory)]
[Hashtable]$Argument
)
$buildArguments = @()
foreach ($key in $Argument.Keys) {
$buildArguments += "-d$key=$($Argument.$key)"
}
return $buildArguments
}
function Start-MsiBuild {
param(
[string[]] $WxsFile,
[string[]] $Extension = @('WixUIExtension', 'WixUtilExtension', 'WixBalExtension'),
[string] $ProductTargetArchitecture,
[Hashtable] $Argument,
[string] $MsiLocationPath,
[string] $MsiPdbLocationPath
)
$outDir = $env:Temp
$wixPaths = Get-WixPath -IsProductArchitectureArm ($ProductTargetArchitecture -eq "arm64")
$extensionArgs = @()
foreach ($extensionName in $Extension) {
$extensionArgs += '-ext'
$extensionArgs += $extensionName
}
$buildArguments = New-MsiArgsArray -Argument $Argument
$objectPaths = @()
foreach ($file in $WxsFile) {
$fileName = [system.io.path]::GetFileNameWithoutExtension($file)
$objectPaths += Join-Path $outDir -ChildPath "${filename}.wixobj"
}
foreach ($file in $objectPaths) {
Remove-Item -ErrorAction SilentlyContinue $file -Force
Remove-Item -ErrorAction SilentlyContinue $file -Force
}
$resolvedWxsFiles = @()
foreach ($file in $WxsFile) {
$resolvedWxsFiles += (Resolve-Path -Path $file).ProviderPath
}
Write-Verbose "$resolvedWxsFiles" -Verbose
Write-Log "running candle..."
Start-NativeExecution -VerboseOutputOnError { & $wixPaths.wixCandleExePath $resolvedWxsFiles -out "$outDir\\" $extensionArgs -arch $ProductTargetArchitecture $buildArguments -v}
Write-Log "running light..."
# suppress ICE61, because we allow same version upgrades
# suppress ICE57, this suppresses an error caused by our shortcut not being installed per user
# suppress ICE40, REINSTALLMODE is defined in the Property table.
Start-NativeExecution -VerboseOutputOnError {& $wixPaths.wixLightExePath -sice:ICE61 -sice:ICE40 -sice:ICE57 -out $msiLocationPath -pdbout $msiPdbLocationPath $objectPaths $extensionArgs }
foreach($file in $objectPaths)
{
Remove-Item -ErrorAction SilentlyContinue $file -Force
Remove-Item -ErrorAction SilentlyContinue $file -Force
}
}
<#
.Synopsis
Creates a Windows AppX MSIX package and assumes that the binaries are already built using 'Start-PSBuild'.
@@ -4372,6 +3907,7 @@ function New-MSIXPackage
Write-Verbose "Creating msix package" -Verbose
Start-NativeExecution -VerboseOutputOnError { & $makeappx pack /o /v /h SHA256 /d $ProductSourcePath /p (Join-Path -Path $CurrentLocation -ChildPath "$packageName.msix") }
Write-Verbose "Created $packageName.msix" -Verbose
Join-Path -Path $CurrentLocation -ChildPath "$packageName.msix"
}
}