Compare commits

...

12 Commits

Author SHA1 Message Date
vanzue
df3e3cec1b Dev 2025-07-10 17:57:48 +08:00
vanzue
ec655f7dfd try luck 2025-07-07 12:00:29 +08:00
Kai Tao
d0fcd6aebb Fix wix build (#40387)
<!-- Enter a brief description/summary of your PR here. What does it
fix/what does it change/how was it tested (even manually, if necessary)?
-->
## Summary of the Pull Request

<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist

- [ ] **Closes:** #xxx
- [ ] **Communication:** I've discussed this with core contributors
already. If the work hasn't been agreed, this work might be rejected
- [ ] **Tests:** Added/updated and all pass
- [ ] **Localization:** All end-user-facing strings can be localized
- [ ] **Dev docs:** Added/updated
- [ ] **New binaries:** Added on the required places
- [ ] [JSON for
signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json)
for new binaries
- [ ] [WXS for
installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs)
for new binaries and localization folder
- [ ] [YML for CI
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml)
for new test projects
- [ ] [YML for signed
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml)
- [ ] **Documentation updated:** If checked, please file a pull request
on [our docs
repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys)
and link it here: #xxx

<!-- Provide a more detailed description of the PR, other things fixed,
or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments

<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
2025-07-04 10:09:08 +08:00
Peiyao Zhao
f3c05d7e93 [Installer] Remove unused wix related files (#40350)
<!-- Enter a brief description/summary of your PR here. What does it
fix/what does it change/how was it tested (even manually, if necessary)?
-->
## Summary of the Pull Request
Remove unused files when migrate to wix5.


<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist

- [ ] **Closes:** #xxx
- [ ] **Communication:** I've discussed this with core contributors
already. If the work hasn't been agreed, this work might be rejected
- [ ] **Tests:** Added/updated and all pass
- [ ] **Localization:** All end-user-facing strings can be localized
- [ ] **Dev docs:** Added/updated
- [ ] **New binaries:** Added on the required places
- [ ] [JSON for
signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json)
for new binaries
- [ ] [WXS for
installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs)
for new binaries and localization folder
- [ ] [YML for CI
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml)
for new test projects
- [ ] [YML for signed
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml)
- [ ] **Documentation updated:** If checked, please file a pull request
on [our docs
repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys)
and link it here: #xxx

<!-- Provide a more detailed description of the PR, other things fixed,
or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments

<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
2025-07-02 20:35:19 +08:00
Peiyao Zhao (from Dev Box)
fcdf6dab2f code update 2025-07-02 20:27:00 +08:00
Peiyao Zhao (from Dev Box)
a6abd967a6 Merge branch 'main' into feature/wix_migration 2025-07-02 11:26:13 +08:00
Peiyao Zhao (from Dev Box)
e6f574dd4d Merge branch 'main' into feature/wix_migration 2025-06-19 14:50:43 +08:00
Peiyao Zhao (from Dev Box)
6ec4f5ab0b Merge branch 'main' into feature/wix_migration 2025-05-22 14:59:48 +08:00
Peiyao Zhao (from Dev Box)
8106a82614 Merge branch 'main' into feature/wix_migration 2025-05-16 15:07:22 +08:00
Peiyao Zhao
f90fc35200 [Installer] Separate .wxs backup operation in PowerToysSetupCustomActions project (#39253) 2025-05-12 13:37:49 +08:00
Peiyao Zhao (from Dev Box)
8b651e0a2e Merge branch 'main' into feature/wix_migration 2025-05-05 11:15:28 +08:00
Peiyao Zhao
3394c756e3 [Installer] Init Wix migration project (#37652)
* fix conflict

* add .gitignore

* update expect.txt

* update

* update

* update

* fix build error

* test

* update pipeline

* fix pipeline build error

* fix spell-check

* fix pipelien build error

* fix pipeline errors

* update folder path to vnext

* fix

* revert update folder path to vnext, since this path is bound to wix tool

---------

Co-authored-by: Jerry Xu <n.xu@outlook.com>
2025-04-27 23:12:38 +08:00
114 changed files with 12789 additions and 122 deletions

View File

@@ -53,6 +53,8 @@ YVU
YVYU
zipfolder
CODEOWNERS
VNext
vnext
# FONTS

4
.gitignore vendored
View File

@@ -350,6 +350,10 @@ src/common/Telemetry/*.etl
# Generated installer file for Monaco source files.
/installer/PowerToysSetup/MonacoSRC.wxs
/installer/PowerToysSetupVNext/MonacoSRC.wxs
# MSBuildCache
/MSBuildCacheLogs/
# PowerToysInstaller Build Temp Files
installer/*/*.wxs.bk

View File

@@ -5,8 +5,12 @@
{
"MatchedPath": [
"PowerToysSetupCustomActions.dll",
"PowerToysSetupCustomActionsVNext.dll",
"PowerToys*Setup-*.exe",
"PowerToys*Setup-*.msi"
"PowerToys*Setup-*.msi",
"PowerToys*Setup-*.msi",
"PowerToys*SetupVNext-*.exe",
"PowerToys*SetupVNext-*.msi"
],
"SigningInfo": {
"Operations": [

View File

@@ -470,6 +470,21 @@ jobs:
additionalBuildOptions: ${{ parameters.additionalBuildOptions }}
buildUserInstaller: true # NOTE: This is the distinction between the above and below rules
- template: steps-build-installer-vnext.yml
parameters:
codeSign: ${{ parameters.codeSign }}
signingIdentity: ${{ parameters.signingIdentity }}
versionNumber: ${{ parameters.versionNumber }}
additionalBuildOptions: ${{ parameters.additionalBuildOptions }}
- template: steps-build-installer-vnext.yml
parameters:
codeSign: ${{ parameters.codeSign }}
signingIdentity: ${{ parameters.signingIdentity }}
versionNumber: ${{ parameters.versionNumber }}
additionalBuildOptions: ${{ parameters.additionalBuildOptions }}
buildUserInstaller: true # NOTE: This is the distinction between the above and below rules
# This saves ~1GiB per architecture. We won't need these later.
# Removes:
# - All .pdbs from any static libs .libs (which were only used during linking)
@@ -492,6 +507,13 @@ jobs:
flattenFolders: True
targetFolder: $(JobOutputDirectory)
- task: CopyFiles@2
displayName: Stage Installers
inputs:
contents: "**/PowerToys*SetupVNext-*.exe"
flattenFolders: True
targetFolder: $(JobOutputDirectory)
- task: CopyFiles@2
displayName: Stage Symbols
inputs:
@@ -525,6 +547,28 @@ jobs:
$machineHash | out-file -filepath $combinedMachinePath
displayName: Calculate file hashes
# Output config for installer vnext
- pwsh: |-
$p = "$(JobOutputDirectory)\"
$userHash = ((Get-Item $p\PowerToysUserSetupVNext*.exe | Get-FileHash).Hash);
$machineHash = ((Get-Item $p\PowerToysSetupVNext*.exe | Get-FileHash).Hash);
$userPlat = "hash_user_$(BuildPlatform).txt";
$machinePlat = "hash_machine_$(BuildPlatform).txt";
$combinedUserPath = $p + $userPlat;
$combinedMachinePath = $p + $machinePlat;
echo $p
echo $userPlat
echo $userHash
echo $combinedUserPath
echo $machinePlat
echo $machineHash
echo $combinedMachinePath
$userHash | out-file -filepath $combinedUserPath
$machineHash | out-file -filepath $combinedMachinePath
displayName: Calculate file hashes
# Publishing the GPO files
- pwsh: |-
New-Item "$(JobOutputDirectory)/gpo" -Type Directory

View File

@@ -0,0 +1,185 @@
parameters:
- name: versionNumber
type: string
default: "0.0.1"
- name: buildUserInstaller
type: boolean
default: false
- name: codeSign
type: boolean
default: false
- name: signingIdentity
type: object
default: {}
- name: additionalBuildOptions
type: string
default: ''
steps:
- pwsh: |-
& git clean -xfd -e *exe -- .\installer\
displayName: ${{replace(replace(parameters.buildUserInstaller,'True','👤'),'False','💻')}} Clean installer to reduce cross-contamination
- pwsh: |-
$IsPerUser = $${{ parameters.buildUserInstaller }}
$InstallerBuildSlug = "MachineSetup"
$InstallerBasename = "PowerToysSetupVNext"
If($IsPerUser) {
$InstallerBuildSlug = "UserSetup"
$InstallerBasename = "PowerToysUserSetupVNext"
}
$InstallerBasename += "-${{ parameters.versionNumber }}-$(BuildPlatform)"
Write-Host "##vso[task.setvariable variable=InstallerBuildSlug]$InstallerBuildSlug"
Write-Host "##vso[task.setvariable variable=InstallerRelativePath]$(BuildPlatform)\$(BuildConfiguration)\$InstallerBuildSlug"
Write-Host "##vso[task.setvariable variable=InstallerBasename]$InstallerBasename"
displayName: ${{replace(replace(parameters.buildUserInstaller,'True','👤'),'False','💻')}} Prepare Installer variables
# This dll needs to be built and signed before building the MSI.
- task: VSBuild@1
displayName: ${{replace(replace(parameters.buildUserInstaller,'True','👤'),'False','💻')}} Build PowerToysSetupCustomActionsVNext
inputs:
solution: "**/installer/PowerToysSetup.sln"
vsVersion: 17.0
msbuildArgs: >-
/t:PowerToysSetupCustomActionsVNext
/p:RunBuildEvents=true;PerUser=${{parameters.buildUserInstaller}};RestorePackagesConfig=true;CIBuild=true
-restore -graph
/bl:$(LogOutputDirectory)\installer-$(InstallerBuildSlug)-actions.binlog
${{ parameters.additionalBuildOptions }}
platform: $(BuildPlatform)
configuration: $(BuildConfiguration)
clean: true
msbuildArchitecture: x64
maximumCpuCount: true
- ${{ if eq(parameters.codeSign, true) }}:
- template: steps-esrp-signing.yml
parameters:
displayName: ${{replace(replace(parameters.buildUserInstaller,'True','👤'),'False','💻')}} Sign PowerToysSetupCustomActionsVNext
signingIdentity: ${{ parameters.signingIdentity }}
inputs:
FolderPath: 'installer/PowerToysSetupCustomActionsVNext/$(InstallerRelativePath)'
signType: batchSigning
batchSignPolicyFile: '$(build.sourcesdirectory)\.pipelines\ESRPSigning_installer.json'
ciPolicyFile: '$(build.sourcesdirectory)\.pipelines\CIPolicy.xml'
## INSTALLER START
#### MSI BUILDING AND SIGNING
- task: VSBuild@1
displayName: ${{replace(replace(parameters.buildUserInstaller,'True','👤'),'False','💻')}} Build VNext MSI
inputs:
solution: "**/installer/PowerToysSetup.sln"
vsVersion: 17.0
msbuildArgs: >-
-restore
/t:PowerToysInstallerVNext
/p:RunBuildEvents=false;PerUser=${{parameters.buildUserInstaller}};BuildProjectReferences=false;CIBuild=true
/bl:$(LogOutputDirectory)\installer-$(InstallerBuildSlug)-msi.binlog
${{ parameters.additionalBuildOptions }}
platform: $(BuildPlatform)
configuration: $(BuildConfiguration)
clean: false # don't undo our hard work above by deleting the CustomActions dll
msbuildArchitecture: x64
maximumCpuCount: true
- script: |-
"C:\Program Files (x86)\WiX Toolset v3.14\bin\dark.exe" -x $(build.sourcesdirectory)\extractedMsi installer\PowerToysSetupVNext\$(InstallerRelativePath)\$(InstallerBasename).msi
dir $(build.sourcesdirectory)\extractedMsi
displayName: "${{replace(replace(parameters.buildUserInstaller,'True','👤'),'False','💻')}} Extract and verify MSI"
# Check if deps.json files don't reference different dll versions.
- pwsh: |-
& '.pipelines/verifyDepsJsonLibraryVersions.ps1' -targetDir '$(build.sourcesdirectory)\extractedMsi\File'
displayName: ${{replace(replace(parameters.buildUserInstaller,'True','👤'),'False','💻')}} Audit deps.json in MSI extracted files
- ${{ if eq(parameters.codeSign, true) }}:
- pwsh: |-
& .pipelines/versionAndSignCheck.ps1 -targetDir '$(build.sourcesdirectory)\extractedMsi\File'
& .pipelines/versionAndSignCheck.ps1 -targetDir '$(build.sourcesdirectory)\extractedMsi\Binary'
git clean -xfd ./extractedMsi
displayName: ${{replace(replace(parameters.buildUserInstaller,'True','👤'),'False','💻')}} Verify all binaries are signed and versioned
- template: steps-esrp-signing.yml
parameters:
displayName: ${{replace(replace(parameters.buildUserInstaller,'True','👤'),'False','💻')}} Sign VNext MSI
signingIdentity: ${{ parameters.signingIdentity }}
inputs:
FolderPath: 'installer/PowerToysSetupVNext/$(InstallerRelativePath)'
signType: batchSigning
batchSignPolicyFile: '$(build.sourcesdirectory)\.pipelines\ESRPSigning_installer.json'
ciPolicyFile: '$(build.sourcesdirectory)\.pipelines\CIPolicy.xml'
#### END MSI
#### BOOTSTRAP BUILDING AND SIGNING
- task: VSBuild@1
displayName: ${{replace(replace(parameters.buildUserInstaller,'True','👤'),'False','💻')}} Build VNext Bootstrapper
inputs:
solution: "**/installer/PowerToysSetup.sln"
vsVersion: 17.0
msbuildArgs: >-
-restore
/t:PowerToysBootstrapperVNext
/p:PerUser=${{parameters.buildUserInstaller}};CIBuild=true
/bl:$(LogOutputDirectory)\installer-$(InstallerBuildSlug)-bootstrapper.binlog
-restore -graph
${{ parameters.additionalBuildOptions }}
platform: $(BuildPlatform)
configuration: $(BuildConfiguration)
clean: false # don't undo our hard work above by deleting the MSI
msbuildArchitecture: x64
maximumCpuCount: true
# The entirety of bundle unpacking/re-packing is unnecessary if we are not code signing it.
- ${{ if eq(parameters.codeSign, true) }}:
- script: |-
"C:\Program Files (x86)\WiX Toolset v3.14\bin\insignia.exe" -ib installer\PowerToysSetupVNext\$(InstallerRelativePath)\$(InstallerBasename).exe -o installer\engine.exe
displayName: "${{replace(replace(parameters.buildUserInstaller,'True','👤'),'False','💻')}} Insignia: Extract Engine from Bundle"
- template: steps-esrp-signing.yml
parameters:
displayName: ${{replace(replace(parameters.buildUserInstaller,'True','👤'),'False','💻')}} Sign WiX Engine
signingIdentity: ${{ parameters.signingIdentity }}
inputs:
FolderPath: "installer"
Pattern: engine.exe
signConfigType: inlineSignParams
inlineOperation: |
[
{
"KeyCode": "CP-230012",
"OperationCode": "SigntoolSign",
"Parameters": {
"OpusName": "Microsoft",
"OpusInfo": "http://www.microsoft.com",
"FileDigest": "/fd \"SHA256\"",
"PageHash": "/NPH",
"TimeStamp": "/tr \"http://rfc3161.gtm.corp.microsoft.com/TSS/HttpTspServer\" /td sha256"
},
"ToolName": "sign",
"ToolVersion": "1.0"
},
{
"KeyCode": "CP-230012",
"OperationCode": "SigntoolVerify",
"Parameters": {},
"ToolName": "sign",
"ToolVersion": "1.0"
}
]
- script: |-
"C:\Program Files (x86)\WiX Toolset v3.14\bin\insignia.exe" -ab installer\engine.exe installer\PowerToysSetupVNext\$(InstallerRelativePath)\$(InstallerBasename).exe -o installer\PowerToysSetupVNext\$(InstallerRelativePath)\$(InstallerBasename).exe
displayName: "${{replace(replace(parameters.buildUserInstaller,'True','👤'),'False','💻')}} Insignia: Merge Engine into Bundle"
- template: steps-esrp-signing.yml
parameters:
displayName: ${{replace(replace(parameters.buildUserInstaller,'True','👤'),'False','💻')}} Sign Final Bootstrapper
signingIdentity: ${{ parameters.signingIdentity }}
inputs:
FolderPath: 'installer/PowerToysSetupVNext/$(InstallerRelativePath)'
signType: batchSigning
batchSignPolicyFile: '$(build.sourcesdirectory)\.pipelines\ESRPSigning_installer.json'
ciPolicyFile: '$(build.sourcesdirectory)\.pipelines\CIPolicy.xml'
#### END BOOTSTRAP
## END INSTALLER

View File

@@ -104,6 +104,15 @@
<PackageVersion Include="WinUIEx" Version="2.2.0" />
<PackageVersion Include="WPF-UI" Version="3.0.5" />
<PackageVersion Include="WyHash" Version="1.0.5" />
<PackageVersion Include="WixToolset.Heat" Version="5.0.2" />
<PackageVersion Include="WixToolset.Firewall.wixext" Version="5.0.2" />
<PackageVersion Include="WixToolset.Util.wixext" Version="5.0.2" />
<PackageVersion Include="WixToolset.UI.wixext" Version="5.0.2" />
<PackageVersion Include="WixToolset.NetFx.wixext" Version="5.0.2" />
<PackageVersion Include="WixToolset.Bal.wixext" Version="5.0.2" />
<PackageVersion Include="WixToolset.BootstrapperApplicationApi" Version="5.0.2" />
<PackageVersion Include="WixToolset.Dtf.WindowsInstaller" Version="5.0.2" />
<PackageVersion Include="FireGiant.HeatWave.BuildTools.wixext" Version="5.0.2" />
</ItemGroup>
<ItemGroup Condition="'$(IsExperimentationLive)'!=''">
<!-- Additional dependencies used by experimentation -->

View File

@@ -1,5 +1,4 @@

Microsoft Visual Studio Solution File, Format Version 12.00
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.1.32414.318
MinimumVisualStudioVersion = 10.0.40219.1
@@ -17,6 +16,12 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Version", "..\src\common\ve
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "EtwTrace", "..\src\common\Telemetry\EtwTrace\EtwTrace.vcxproj", "{8F021B46-362B-485C-BFBA-CCF83E820CBD}"
EndProject
Project("{930C7802-8A8C-48F9-8165-68863BCCD9DD}") = "PowerToysInstallerVNext", "PowerToysSetupVNext\PowerToysInstallerVNext.wixproj", "{B6E94700-DF38-41F6-A3FD-18B69674AB1E}"
EndProject
Project("{930C7802-8A8C-48F9-8165-68863BCCD9DD}") = "PowerToysBootstrapperVNext", "PowerToysSetupVNext\PowerToysBootstrapperVNext.wixproj", "{DA4E9744-80BE-424C-B0F5-AFD8757DB575}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PowerToysSetupCustomActionsVNext", "PowerToysSetupCustomActionsVNext\PowerToysSetupCustomActionsVNext.vcxproj", "{B3A354B0-1E54-4B55-A962-FB5AF9330C19}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|ARM64 = Debug|ARM64
@@ -78,6 +83,29 @@ Global
{8F021B46-362B-485C-BFBA-CCF83E820CBD}.Release|ARM64.Build.0 = Release|ARM64
{8F021B46-362B-485C-BFBA-CCF83E820CBD}.Release|x64.ActiveCfg = Release|x64
{8F021B46-362B-485C-BFBA-CCF83E820CBD}.Release|x64.Build.0 = Release|x64
{B6E94700-DF38-41F6-A3FD-18B69674AB1E}.Debug|ARM64.ActiveCfg = Debug|ARM64
{B6E94700-DF38-41F6-A3FD-18B69674AB1E}.Debug|ARM64.Build.0 = Debug|ARM64
{B6E94700-DF38-41F6-A3FD-18B69674AB1E}.Debug|x64.ActiveCfg = Debug|x64
{B6E94700-DF38-41F6-A3FD-18B69674AB1E}.Debug|x64.Build.0 = Debug|x64
{B6E94700-DF38-41F6-A3FD-18B69674AB1E}.Release|ARM64.ActiveCfg = Release|ARM64
{B6E94700-DF38-41F6-A3FD-18B69674AB1E}.Release|ARM64.Build.0 = Release|ARM64
{B6E94700-DF38-41F6-A3FD-18B69674AB1E}.Release|x64.ActiveCfg = Release|x64
{B6E94700-DF38-41F6-A3FD-18B69674AB1E}.Release|x64.Build.0 = Release|x64
{DA4E9744-80BE-424C-B0F5-AFD8757DB575}.Debug|ARM64.ActiveCfg = Debug|ARM64
{DA4E9744-80BE-424C-B0F5-AFD8757DB575}.Debug|ARM64.Build.0 = Debug|ARM64
{DA4E9744-80BE-424C-B0F5-AFD8757DB575}.Debug|x64.ActiveCfg = Debug|x64
{DA4E9744-80BE-424C-B0F5-AFD8757DB575}.Debug|x64.Build.0 = Debug|x64
{DA4E9744-80BE-424C-B0F5-AFD8757DB575}.Release|ARM64.ActiveCfg = Release|ARM64
{DA4E9744-80BE-424C-B0F5-AFD8757DB575}.Release|ARM64.Build.0 = Release|ARM64
{DA4E9744-80BE-424C-B0F5-AFD8757DB575}.Release|x64.ActiveCfg = Release|x64
{DA4E9744-80BE-424C-B0F5-AFD8757DB575}.Release|x64.Build.0 = Release|x64
{B3A354B0-1E54-4B55-A962-FB5AF9330C19}.Debug|ARM64.ActiveCfg = Debug|ARM64
{B3A354B0-1E54-4B55-A962-FB5AF9330C19}.Debug|x64.ActiveCfg = Debug|x64
{B3A354B0-1E54-4B55-A962-FB5AF9330C19}.Debug|x64.Build.0 = Debug|x64
{B3A354B0-1E54-4B55-A962-FB5AF9330C19}.Release|ARM64.ActiveCfg = Release|ARM64
{B3A354B0-1E54-4B55-A962-FB5AF9330C19}.Release|ARM64.Build.0 = Release|ARM64
{B3A354B0-1E54-4B55-A962-FB5AF9330C19}.Release|x64.ActiveCfg = Release|x64
{B3A354B0-1E54-4B55-A962-FB5AF9330C19}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -85,4 +113,4 @@ Global
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {B7A3DA30-D443-40FF-AC51-988AD41E3962}
EndGlobalSection
EndGlobal
EndGlobal

View File

@@ -57,7 +57,7 @@ call powershell.exe -NonInteractive -executionpolicy Unrestricted -File $(MSBuil
call move /Y ..\..\..\WinAppSDK.wxs.bk ..\..\..\WinAppSDK.wxs
call move /Y ..\..\..\WinUI3Applications.wxs.bk ..\..\..\WinUI3Applications.wxs
call move /Y ..\..\..\Workspaces.wxs.bk ..\..\..\Workspaces.wxs
</PostBuildEvent>
</PostBuildEvent>
</PropertyGroup>
<PropertyGroup>
<Name>PowerToysInstaller</Name>

View File

@@ -14,4 +14,4 @@ msbuild !PTRoot!\src\modules\previewpane\MarkdownPreviewHandler\MarkdownPreviewH
msbuild !PTRoot!\src\modules\previewpane\SvgPreviewHandler\SvgPreviewHandler.csproj -t:Publish -p:Configuration="Release" -p:Platform="!PlatformArg!" -p:AppxBundle=Never -p:PowerToysRoot=!PTRoot! -p:VCRTForwarders-IncludeDebugCRT=false -p:PublishProfile=InstallationPublishProfile.pubxml -p:TargetFramework=net9.0-windows10.0.26100.0
msbuild !PTRoot!\src\modules\previewpane\SvgThumbnailProvider\SvgThumbnailProvider.csproj -t:Publish -p:Configuration="Release" -p:Platform="!PlatformArg!" -p:AppxBundle=Never -p:PowerToysRoot=!PTRoot! -p:VCRTForwarders-IncludeDebugCRT=false -p:PublishProfile=InstallationPublishProfile.pubxml -p:TargetFramework=net9.0-windows10.0.26100.0
msbuild !PTRoot!\src\modules\previewpane\SvgThumbnailProvider\SvgThumbnailProvider.csproj -t:Publish -p:Configuration="Release" -p:Platform="!PlatformArg!" -p:AppxBundle=Never -p:PowerToysRoot=!PTRoot! -p:VCRTForwarders-IncludeDebugCRT=false -p:PublishProfile=InstallationPublishProfile.pubxml -p:TargetFramework=net9.0-windows10.0.26100.0

View File

@@ -81,7 +81,7 @@
if not "$(NormalizedPerUserValue)" == "true" call powershell.exe -NonInteractive -executionpolicy Unrestricted -File ..\PowerToysSetup\generateAllFileComponents.ps1 -platform $(Platform)
if "$(NormalizedPerUserValue)" == "true" call powershell.exe -NonInteractive -executionpolicy Unrestricted -File ..\PowerToysSetup\generateAllFileComponents.ps1 -platform $(Platform) -installscopeperuser $(NormalizedPerUserValue)
</Command>
<Message>Backing up original files and populating .NET and WPF Runtime dependencies </Message>
<Message>Backing up original files and populating .NET and WPF Runtime dependencies for WiX3 based installer</Message>
</PreBuildEvent>
</ItemDefinitionGroup>
<PropertyGroup Condition="'$(RunBuildEvents)'=='false'">

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,30 @@
LIBRARY "PowerToysSetupCustomActionsVNext"
EXPORTS
LaunchPowerToysCA
CheckGPOCA
CleanVideoConferenceRegistryCA
ApplyModulesRegistryChangeSetsCA
DetectPrevInstallPathCA
RemoveScheduledTasksCA
TelemetryLogInstallSuccessCA
TelemetryLogInstallCancelCA
TelemetryLogInstallFailCA
TelemetryLogUninstallSuccessCA
TelemetryLogUninstallCancelCA
TelemetryLogUninstallFailCA
TelemetryLogRepairCancelCA
TelemetryLogRepairFailCA
TerminateProcessesCA
InstallEmbeddedMSIXCA
InstallDSCModuleCA
InstallCmdPalPackageCA
UnApplyModulesRegistryChangeSetsCA
UnRegisterCmdPalPackageCA
UnRegisterContextMenuPackagesCA
UninstallEmbeddedMSIXCA
UninstallDSCModuleCA
UninstallServicesCA
UninstallCommandNotFoundModuleCA
UpgradeCommandNotFoundModuleCA
UnsetAdvancedPasteAPIKeyCA

View File

@@ -0,0 +1,183 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\packages\WixToolset.WcaUtil.5.0.2\build\WixToolset.WcaUtil.props" Condition="Exists('..\packages\WixToolset.WcaUtil.5.0.2\build\WixToolset.WcaUtil.props')" />
<Import Project="..\packages\WixToolset.DUtil.5.0.2\build\WixToolset.DUtil.props" Condition="Exists('..\packages\WixToolset.DUtil.5.0.2\build\WixToolset.DUtil.props')" />
<Import Project="..\packages\Microsoft.Windows.CppWinRT.2.0.240111.5\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('..\packages\Microsoft.Windows.CppWinRT.2.0.240111.5\build\native\Microsoft.Windows.CppWinRT.props')" />
<Import Project="..\wix.props" Condition="Exists('..\wix.props')" />
<PropertyGroup Label="Globals">
<ProjectGuid>{B3A354B0-1E54-4B55-A962-FB5AF9330C19}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>PowerToysSetupCustomActionsVNext</RootNamespace>
<ProjectName>PowerToysSetupCustomActionsVNext</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" Condition="Exists('$(VCTargetsPath)\Microsoft.Cpp.Default.props')" />
<PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<Import Project="..\..\deps\spdlog.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)'=='Debug'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)'=='Release'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<OutDir Condition=" '$(PerUser)' != 'true' ">$(Platform)\$(Configuration)\MachineSetup\</OutDir>
<OutDir Condition=" '$(PerUser)' == 'true' ">$(Platform)\$(Configuration)\UserSetup\</OutDir>
<IntDir Condition=" '$(PerUser)' != 'true' ">$(SolutionDir)$(ProjectName)\$(Platform)\$(Configuration)\MachineSetup\obj\</IntDir>
<IntDir Condition=" '$(PerUser)' == 'true' ">$(SolutionDir)$(ProjectName)\$(Platform)\$(Configuration)\UserSetup\obj\</IntDir>
<!-- The CMD script below checks this value, and it is **CASE SENSITIVE** -->
<NormalizedPerUserValue>false</NormalizedPerUserValue>
<NormalizedPerUserValue Condition=" '$(PerUser)' == 'true' ">true</NormalizedPerUserValue>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Debug'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Release'">
<LinkIncremental>false</LinkIncremental>
<IncludePath>..\..\src\common\Telemetry;$(IncludePath)</IncludePath>
</PropertyGroup>
<ItemDefinitionGroup>
<PreBuildEvent>
<Command>
call cmd /C "copy ""$(ProjectDir)DepsFilesLists.h"" ""$(ProjectDir)DepsFilesLists.h.bk"""
call cmd /C "copy ""$(ProjectDir)..\PowerToysSetupVNext\AdvancedPaste.wxs"" ""$(ProjectDir)..\PowerToysSetupVNext\AdvancedPaste.wxs.bk""""
call cmd /C "copy ""$(ProjectDir)..\PowerToysSetupVNext\Awake.wxs"" ""$(ProjectDir)..\PowerToysSetupVNext\Awake.wxs.bk""""
call cmd /C "copy ""$(ProjectDir)..\PowerToysSetupVNext\BaseApplications.wxs"" ""$(ProjectDir)..\PowerToysSetupVNext\BaseApplications.wxs.bk""""
call cmd /C "copy ""$(ProjectDir)..\PowerToysSetupVNext\CmdPal.wxs"" ""$(ProjectDir)..\PowerToysSetup\CmdPal.wxs.bk""""
call cmd /C "copy ""$(ProjectDir)..\PowerToysSetupVNext\ColorPicker.wxs"" ""$(ProjectDir)..\PowerToysSetupVNext\ColorPicker.wxs.bk""""
call cmd /C "copy ""$(ProjectDir)..\PowerToysSetupVNext\Core.wxs"" ""$(ProjectDir)..\PowerToysSetupVNext\Core.wxs.bk""""
call cmd /C "copy ""$(ProjectDir)..\PowerToysSetupVNext\EnvironmentVariables.wxs"" ""$(ProjectDir)..\PowerToysSetupVNext\EnvironmentVariables.wxs.bk""""
call cmd /C "copy ""$(ProjectDir)..\PowerToysSetupVNext\FileExplorerPreview.wxs"" ""$(ProjectDir)..\PowerToysSetupVNext\FileExplorerPreview.wxs.bk""""
call cmd /C "copy ""$(ProjectDir)..\PowerToysSetupVNext\FileLocksmith.wxs"" ""$(ProjectDir)..\PowerToysSetupVNext\FileLocksmith.wxs.bk""""
call cmd /C "copy ""$(ProjectDir)..\PowerToysSetupVNext\Hosts.wxs"" ""$(ProjectDir)..\PowerToysSetupVNext\Hosts.wxs.bk""""
call cmd /C "copy ""$(ProjectDir)..\PowerToysSetupVNext\ImageResizer.wxs"" ""$(ProjectDir)..\PowerToysSetupVNext\ImageResizer.wxs.bk""""
call cmd /C "copy ""$(ProjectDir)..\PowerToysSetupVNext\KeyboardManager.wxs"" ""$(ProjectDir)..\PowerToysSetupVNext\KeyboardManager.wxs.bk""""
call cmd /C "copy ""$(ProjectDir)..\PowerToysSetupVNext\MouseWithoutBorders.wxs"" ""$(ProjectDir)..\PowerToysSetupVNext\MouseWithoutBorders.wxs.bk""""
call cmd /C "copy ""$(ProjectDir)..\PowerToysSetupVNext\NewPlus.wxs"" ""$(ProjectDir)..\PowerToysSetupVNext\NewPlus.wxs.bk""""
call cmd /C "copy ""$(ProjectDir)..\PowerToysSetupVNext\Peek.wxs"" ""$(ProjectDir)..\PowerToysSetupVNext\Peek.wxs.bk""""
call cmd /C "copy ""$(ProjectDir)..\PowerToysSetupVNext\PowerRename.wxs"" ""$(ProjectDir)..\PowerToysSetupVNext\PowerRename.wxs.bk""""
call cmd /C "copy ""$(ProjectDir)..\PowerToysSetupVNext\Product.wxs"" ""$(ProjectDir)..\PowerToysSetupVNext\Product.wxs.bk""""
call cmd /C "copy ""$(ProjectDir)..\PowerToysSetupVNext\RegistryPreview.wxs"" ""$(ProjectDir)..\PowerToysSetupVNext\RegistryPreview.wxs.bk""""
call cmd /C "copy ""$(ProjectDir)..\PowerToysSetupVNext\Resources.wxs"" ""$(ProjectDir)..\PowerToysSetupVNext\Resources.wxs.bk""""
call cmd /C "copy ""$(ProjectDir)..\PowerToysSetupVNext\Run.wxs"" ""$(ProjectDir)..\PowerToysSetupVNext\Run.wxs.bk""""
call cmd /C "copy ""$(ProjectDir)..\PowerToysSetupVNext\Settings.wxs"" ""$(ProjectDir)..\PowerToysSetupVNext\Settings.wxs.bk""""
call cmd /C "copy ""$(ProjectDir)..\PowerToysSetupVNext\ShortcutGuide.wxs"" ""$(ProjectDir)..\PowerToysSetupVNext\ShortcutGuide.wxs.bk""""
call cmd /C "copy ""$(ProjectDir)..\PowerToysSetupVNext\Tools.wxs"" ""$(ProjectDir)..\PowerToysSetupVNext\Tools.wxs.bk""""
call cmd /C "copy ""$(ProjectDir)..\PowerToysSetupVNext\WinAppSDK.wxs"" ""$(ProjectDir)..\PowerToysSetupVNext\WinAppSDK.wxs.bk""""
call cmd /C "copy ""$(ProjectDir)..\PowerToysSetupVNext\WinUI3Applications.wxs"" ""$(ProjectDir)..\PowerToysSetupVNext\WinUI3Applications.wxs.bk""""
call cmd /C "copy ""$(ProjectDir)..\PowerToysSetupVNext\Workspaces.wxs"" ""$(ProjectDir)..\PowerToysSetupVNext\Workspaces.wxs.bk""""
if not "$(NormalizedPerUserValue)" == "true" call powershell.exe -NonInteractive -executionpolicy Unrestricted -File ..\PowerToysSetupVNext\generateAllFileComponents.ps1 -platform $(Platform)
if "$(NormalizedPerUserValue)" == "true" call powershell.exe -NonInteractive -executionpolicy Unrestricted -File ..\PowerToysSetupVNext\generateAllFileComponents.ps1 -platform $(Platform) -installscopeperuser $(NormalizedPerUserValue)
</Command>
<Message>Backing up original files and populating .NET and WPF Runtime dependencies for WiX3 based installer</Message>
</PreBuildEvent>
</ItemDefinitionGroup>
<PropertyGroup Condition="'$(RunBuildEvents)'=='false'">
<PreBuildEventUseInBuild>false</PreBuildEventUseInBuild>
<PostBuildEventUseInBuild>false</PostBuildEventUseInBuild>
</PropertyGroup>
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>inc;..\..\src\;..\..\src\common\Telemetry;telemetry;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalOptions>/await /Zc:twoPhase- /Wv:18 %(AdditionalOptions)</AdditionalOptions>
<WarningLevel>Level4</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<AdditionalDependencies>Userenv.lib;Wtsapi32.lib;WindowsApp.lib;Newdev.lib;Crypt32.lib;msi.lib;wcautil.lib;Psapi.lib;Pathcch.lib;comsupp.lib;taskschd.lib;Secur32.lib;msi.lib;dutil.lib;wcautil.lib;Version.lib;Shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<ModuleDefinitionFile>CustomAction.def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup>
<ClCompile>
<PreprocessorDefinitions>WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>$(NUGET_PACKAGES)\wixtoolset.wcautil\5.0.2\build\native\v14\$(Platform);$(NUGET_PACKAGES)\wixtoolset.dutil\5.0.2\build\native\v14\$(Platform);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)'=='Debug'">
<ClCompile>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_DEBUG;_WINDOWS;_USRDLL;CUSTOMACTIONTEST_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<UACExecutionLevel>HighestAvailable</UACExecutionLevel>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)'=='Release'">
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>NDEBUG;_WINDOWS;_USRDLL;CUSTOMACTIONTEST_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<UACExecutionLevel>HighestAvailable</UACExecutionLevel>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="CustomAction.cpp" />
<ClCompile Include="pch.cpp">
<PrecompiledHeader Condition="'$(UsePrecompiledHeaders)' != 'false'">Create</PrecompiledHeader>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="CustomAction.def" />
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="DepsFilesLists.h" />
<ClInclude Include="RcResource.h" />
<ClInclude Include="resource.h" />
<ClInclude Include="pch.h" />
<ClInclude Include="Telemetry\ProjectTelemetry.h" />
<ClInclude Include="Telemetry\TraceLoggingDefines.h" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="Resource.rc" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\common\logger\logger.vcxproj">
<Project>{d9b8fc84-322a-4f9f-bbb9-20915c47ddfd}</Project>
</ProjectReference>
<ProjectReference Include="..\..\src\common\Telemetry\EtwTrace\EtwTrace.vcxproj">
<Project>{8f021b46-362b-485c-bfba-ccf83e820cbd}</Project>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="..\packages\Microsoft.Windows.CppWinRT.2.0.240111.5\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('..\packages\Microsoft.Windows.CppWinRT.2.0.240111.5\build\native\Microsoft.Windows.CppWinRT.targets')" />
</ImportGroup>
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\Microsoft.Windows.CppWinRT.2.0.240111.5\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Windows.CppWinRT.2.0.240111.5\build\native\Microsoft.Windows.CppWinRT.props'))" />
<Error Condition="!Exists('..\packages\Microsoft.Windows.CppWinRT.2.0.240111.5\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Windows.CppWinRT.2.0.240111.5\build\native\Microsoft.Windows.CppWinRT.targets'))" />
<Error Condition="!Exists('..\packages\WixToolset.DUtil.5.0.2\build\WixToolset.DUtil.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\WixToolset.DUtil.5.0.2\build\WixToolset.DUtil.props'))" />
<Error Condition="!Exists('..\packages\WixToolset.WcaUtil.5.0.2\build\WixToolset.WcaUtil.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\WixToolset.WcaUtil.5.0.2\build\WixToolset.WcaUtil.props'))" />
</Target>
</Project>

View File

@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClCompile Include="CustomAction.cpp" />
<ClCompile Include="pch.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="pch.h" />
<ClInclude Include="Telemetry\ProjectTelemetry.h">
<Filter>Telemetry</Filter>
</ClInclude>
<ClInclude Include="Telemetry\TraceLoggingDefines.h">
<Filter>Telemetry</Filter>
</ClInclude>
<ClInclude Include="resource.h" />
<ClInclude Include="RcResource.h" />
<ClInclude Include="DepsFilesLists.h" />
</ItemGroup>
<ItemGroup>
<None Include="CustomAction.def" />
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<Filter Include="Telemetry">
<UniqueIdentifier>{6e73ce5d-e715-4e7e-b796-c5d180b07ff2}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="Resource.rc" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,63 @@
#pragma once
#include <string_view>
#include <optional>
#include <filesystem>
#include <fstream>
#include <Windows.h>
class RcResource
{
public:
const std::byte* _memory = nullptr;
size_t _size = 0;
static inline std::optional<RcResource> create(int resource_id, const std::wstring_view resource_class, const HINSTANCE handle = nullptr)
{
const HRSRC resHandle = FindResourceW(handle, MAKEINTRESOURCEW(resource_id), resource_class.data());
if (!resHandle)
{
return std::nullopt;
}
const HGLOBAL memHandle = LoadResource(handle, resHandle);
if (!memHandle)
{
return std::nullopt;
}
const size_t resSize = SizeofResource(handle, resHandle);
if (!resSize)
{
return std::nullopt;
}
auto res = static_cast<const std::byte*>(LockResource(memHandle));
if (!res)
{
return std::nullopt;
}
return RcResource{ res, resSize };
}
inline bool saveAsFile(const std::filesystem::path destination)
{
std::fstream installerFile{ destination, std::ios_base::binary | std::ios_base::out | std::ios_base::trunc };
if (!installerFile.is_open())
{
return false;
}
installerFile.write(reinterpret_cast<const char*>(_memory), _size);
return true;
}
private:
RcResource() = delete;
RcResource(const std::byte* memory, size_t size) :
_memory{ memory }, _size{ size }
{
}
};

View File

@@ -0,0 +1,96 @@
// Microsoft Visual C++ generated resource script.
//
#include <windows.h>
#include "resource.h"
#include "../../src/common/version/version.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "winres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
1 VERSIONINFO
FILEVERSION FILE_VERSION
PRODUCTVERSION PRODUCT_VERSION
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
#ifdef _DEBUG
FILEFLAGS VS_FF_DEBUG
#else
FILEFLAGS 0x0L
#endif
FILEOS VOS_NT_WINDOWS32
FILETYPE VFT_DLL
FILESUBTYPE VFT2_UNKNOWN
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0" // US English (0x0409), Unicode (0x04B0) charset
BEGIN
VALUE "CompanyName", COMPANY_NAME
VALUE "FileDescription", FILE_DESCRIPTION
VALUE "FileVersion", FILE_VERSION_STRING
VALUE "InternalName", INTERNAL_NAME
VALUE "LegalCopyright", COPYRIGHT_NOTE
VALUE "OriginalFilename", ORIGINAL_FILENAME
VALUE "ProductName", PRODUCT_NAME
VALUE "ProductVersion", PRODUCT_VERSION_STRING
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200 // US English (0x0409), Unicode (1200) charset
END
END
/////////////////////////////////////////////////////////////////////////////
// English (United States) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
LANGUAGE 25, 1
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE
BEGIN
"#include ""winres.h""\r\n"
"\0"
END
3 TEXTINCLUDE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
#endif // English (United States) resources
/////////////////////////////////////////////////////////////////////////////
// TODO: Use to activate embedded MSIX
//IDR_BIN_MSIX_HELLO_PACKAGE BIN "..\\..\..\\src\\modules\\HelloModule\\AppPackages\\HelloModule_1.0.0.0_x64_Test\\HelloModule_1.0.0.0_x64.msix"
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.Windows.CppWinRT" version="2.0.240111.5" targetFramework="native" />
<package id="WixToolset.DUtil" version="5.0.2" targetFramework="native" />
<package id="WixToolset.WcaUtil" version="5.0.2" targetFramework="native" />
</packages>

View File

@@ -0,0 +1,5 @@
// pch.cpp: source file corresponding to the pre-compiled header
#include "pch.h"
// When you are using pre-compiled headers, this source file is necessary for compilation to succeed.

View File

@@ -0,0 +1,37 @@
#pragma once
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#define DPSAPI_VERSION 1
// Windows Header Files:
#include <windows.h>
#include <newdev.h>
#include <strsafe.h>
#include <msiquery.h>
#include <Msi.h>
#include <shlobj_core.h>
// WiX Header Files:
#include <wcautil.h>
#define SECURITY_WIN32
#include <Security.h>
#include <Lmcons.h>
#include <comdef.h>
#include <taskschd.h>
#include <iostream>
#include <strutil.h>
#include <string>
#include <optional>
#include <pathcch.h>
#include <psapi.h>
#include <vector>
#include <array>
#include <mutex>
#include <winrt/Windows.Foundation.h>
#include <winrt/Windows.Foundation.Collections.h>
#include <winrt/Windows.ApplicationModel.h>
#include <winrt/Windows.Management.Deployment.h>
#include <winrt/Windows.System.h>

View File

@@ -0,0 +1,20 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by Resource.rc
#define FILE_DESCRIPTION "PowerToys Setup Custom Actions"
#define INTERNAL_NAME "PowerToysSetupCustomActionsVNext"
#define ORIGINAL_FILENAME "PowerToysSetupCustomActionsVNext.dll"
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 102
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1001
#define _APS_NEXT_SYMED_VALUE 102
#endif
#endif
#define IDR_BIN_MSIX_HELLO_PACKAGE 101

View File

@@ -0,0 +1,27 @@
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
<?include $(sys.CURRENTDIR)\Common.wxi?>
<?define AdvancedPasteAssetsFiles=?>
<?define AdvancedPasteAssetsFilesPath=$(var.BinDir)WinUI3Apps\Assets\AdvancedPaste\?>
<Fragment>
<DirectoryRef Id="WinUI3AppsAssetsFolder">
<Directory Id="AdvancedPasteAssetsFolder" Name="AdvancedPaste" />
</DirectoryRef>
<DirectoryRef Id="AdvancedPasteAssetsFolder" FileSource="$(var.AdvancedPasteAssetsFilesPath)">
<!-- Generated by generateFileComponents.ps1 -->
<!--AdvancedPasteAssetsFiles_Component_Def-->
</DirectoryRef>
<ComponentGroup Id="AdvancedPasteComponentGroup">
<Component Id="RemoveAdvancedPasteFolder" Guid="55AFE81D-F6BD-439A-A229-66AF5C360AB0" Directory="AdvancedPasteAssetsFolder">
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys\components">
<RegistryValue Type="string" Name="RemoveAdvancedPasteFolder" Value="" KeyPath="yes" />
</RegistryKey>
<RemoveFolder Id="RemoveFolderAdvancedPasteAssetsFolder" Directory="AdvancedPasteAssetsFolder" On="uninstall" />
</Component>
</ComponentGroup>
</Fragment>
</Wix>

View File

@@ -0,0 +1,30 @@
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
<?include $(sys.CURRENTDIR)\Common.wxi?>
<?define AwakeImagesFiles=?>
<?define AwakeImagesFilesPath=$(var.BinDir)\Assets\Awake\?>
<Fragment>
<!-- Awake images -->
<DirectoryRef Id="BaseApplicationsAssetsFolder">
<Directory Id="AwakeImagesFolder" Name="Awake" />
</DirectoryRef>
<DirectoryRef Id="AwakeImagesFolder" FileSource="$(var.AwakeImagesFilesPath)">
<!-- Generated by generateFileComponents.ps1 -->
<!--AwakeImagesFiles_Component_Def-->
</DirectoryRef>
<ComponentGroup Id="AwakeComponentGroup">
<Component Id="RemoveAwakeFolder" Guid="95D7774C-69A3-48A3-B417-1BD9664BE974" Directory="INSTALLFOLDER">
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys\components">
<RegistryValue Type="string" Name="RemoveAwakeFolder" Value="" KeyPath="yes" />
</RegistryKey>
<RemoveFolder Id="RemoveFolderAwakeImagesFolder" Directory="AwakeImagesFolder" On="uninstall" />
</Component>
</ComponentGroup>
</Fragment>
</Wix>

View File

@@ -0,0 +1,18 @@
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
<?include $(sys.CURRENTDIR)\Common.wxi?>
<?define BaseApplicationsFiles=?>
<?define BaseApplicationsFilesPath=$(var.BinDir)\?>
<Fragment>
<DirectoryRef Id="INSTALLFOLDER">
<!-- Generated by generateFileComponents.ps1 -->
<!--BaseApplicationsFiles_Component_Def-->
</DirectoryRef>
<ComponentGroup Id="BaseApplicationsComponentGroup">
</ComponentGroup>
</Fragment>
</Wix>

View File

@@ -0,0 +1,10 @@
using System.Windows;
[assembly: ThemeInfo(
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
//(used if a resource is not found in the page,
// or application resource dictionaries)
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
//(used if a resource is not found in the page,
// app, or any theme specific resource dictionaries)
)]

Binary file not shown.

After

Width:  |  Height:  |  Size: 287 KiB

View File

@@ -0,0 +1,38 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net9.0-windows10.0.26100.0</TargetFramework>
<Platforms>x64</Platforms>
<ImplicitUsings>disable</ImplicitUsings>
<UseWPF>true</UseWPF>
<UseWindowsForms>true</UseWindowsForms>
<SelfContained>true</SelfContained>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<ApplicationIcon>Assets\Icon.ico</ApplicationIcon>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<DebugType>none</DebugType>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<DebugType>embedded</DebugType>
</PropertyGroup>
<ItemGroup>
<Resource Include="Assets\Icon.ico" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="WixToolset.BootstrapperApplicationApi" />
</ItemGroup>
<ItemGroup>
<Page Update="Views\ShellView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,62 @@
using Bootstrapper.Models;
using Bootstrapper.Models.Util;
using System;
using WixToolset.BootstrapperApplicationApi;
namespace Bootstrapper;
internal class BootstrapperApp : BootstrapperApplication
{
private Model _model;
public int ExitCode { get; private set; }
protected override void OnCreate(CreateEventArgs args)
{
base.OnCreate(args);
try
{
var factory = new WpfBaFactory();
_model = factory.Create(this, args.Engine, args.Command);
}
catch (Exception ex)
{
ExitCode = ErrorHelper.HResultToWin32(ex.HResult);
args.Engine.Log(LogLevel.Error, ex.ToString());
throw;
}
}
protected override void Run()
{
var hResult = 0;
try
{
_model.Log.Write("Running bootstrapper application.");
try
{
_model.UiFacade.Initialize(_model);
_model.Engine.Detect();
_model.UiFacade.RunMessageLoop();
}
finally
{
hResult = _model.State.PhaseResult;
}
}
catch (Exception ex)
{
hResult = ex.HResult;
_model.Log.Write(ex);
}
finally
{
// If the HRESULT is an error, convert it to a win32 error code
ExitCode = ErrorHelper.HResultToWin32(hResult);
_model.SaveEmbeddedLog(ExitCode);
_model.Engine.Quit(ExitCode);
}
}
}

View File

@@ -0,0 +1,215 @@
using Bootstrapper.Models.State;
using Bootstrapper.Models.Util;
using System;
using System.IO;
using System.Linq;
using System.Text;
using WixToolset.BootstrapperApplicationApi;
namespace Bootstrapper.Models;
internal class Log
{
private readonly IEngine _engine;
public Log(IEngine engine)
{
_engine = engine;
}
public void Write(string message, bool indent = false, LogLevel level = LogLevel.Verbose)
{
var txt = message;
if (indent)
txt = $"{new string(' ', 10)}{txt}";
_engine.Log(level, txt);
}
public void Write(Exception ex)
{
Write(ex.ToString(), false, LogLevel.Error);
}
public void RemoveEmbeddedLog()
{
try
{
// delete any previous embedded log
var fileName = EmbeddedLogFileName();
if (!string.IsNullOrEmpty(fileName) && File.Exists(fileName))
File.Delete(fileName);
}
catch
{
// ignore
}
}
public string EmbeddedLogFileName()
{
var folder = Path.GetDirectoryName(_engine.GetVariableString(Constants.BundleLogName));
if (string.IsNullOrEmpty(folder))
return string.Empty;
return Path.Combine(folder, $"{_engine.GetVariableString(Constants.BundleNameVariable)}_embedded.txt");
}
public void WriteLogFile(AppState state, string fileName)
{
try
{
if (string.IsNullOrEmpty(fileName))
return;
var log = Read(state);
if (string.IsNullOrEmpty(log))
throw new InvalidOperationException("Reading log produced an empty string");
var logSb = new StringBuilder();
if (fileName == EmbeddedLogFileName())
{
// indent embedded log
var logArr = log.Split('\n');
foreach (var line in logArr)
{
logSb.Append(new string(' ', 8));
logSb.AppendLine(line.Trim());
}
File.WriteAllText(fileName, logSb.ToString());
}
else
File.WriteAllText(fileName, log);
}
catch (Exception ex)
{
Write($"Unable to write to {fileName}");
Write(ex);
}
}
/// <summary>
/// Formats app state, bundle log and any package logs that have been written into a single log
/// </summary>
/// <exception cref="InstallerVariableNotFoundException">
/// Thrown when the log cannot be read because a variable is missing
/// </exception>
private string Read(AppState state)
{
if (!_engine.ContainsVariable(Constants.BundleLogName))
throw new InstallerVariableNotFoundException(Constants.BundleLogName);
var tocSb = new StringBuilder();
tocSb.AppendLine("Table of Contents");
// Caches log file text. Will be appended to TOC once all logs have been read.
var logSb = new StringBuilder();
var tocIndex = 1;
// Add state to TOC
tocSb.AppendLine($"{tocIndex}. State");
// Add state to log
logSb.AppendLine();
logSb.AppendLine();
logSb.AppendLine("1. State");
logSb.AppendLine(Constants.Line);
logSb.AppendLine(state.ToString());
// Add TOC entry for bundle
tocIndex++;
var bundleLogFile = Path.GetFullPath(_engine.GetVariableString(Constants.BundleLogName));
tocSb.AppendLine($"{tocIndex}. Bundle Log (original location = \"{bundleLogFile}\")");
// Add bundle log text
logSb.Append(ReadLogFile(bundleLogFile, "Bundle Log", tocIndex));
var packageIds = state.Bundle.Packages.Values.Select(i => i.Id).ToArray();
foreach (var packageId in packageIds)
{
try
{
var packageLogFile = PackageLogFile(packageId);
if (string.IsNullOrEmpty(packageLogFile))
continue;
// Add package to TOC
var logName = state.GetPackageName(packageId);
tocIndex++;
tocSb.AppendLine($"{tocIndex}. {logName} (original location = \"{packageLogFile}\")");
// Add package log
logSb.Append(ReadLogFile(packageLogFile, logName, tocIndex));
}
catch (Exception ex)
{
logSb.AppendLine();
logSb.AppendLine();
logSb.AppendLine(ex.ToString());
}
}
if (!string.IsNullOrEmpty(state.RelatedBundleId))
{
var fileName = EmbeddedLogFileName();
if (!string.IsNullOrEmpty(fileName) && File.Exists(fileName))
{
tocIndex++;
var productName = _engine.GetVariableString(Constants.BundleNameVariable);
tocSb.AppendLine($"{tocIndex}. {productName} bundle (original location = \"{fileName}\")");
logSb.Append(ReadLogFile(fileName, productName, tocIndex));
}
}
tocSb.Append(logSb);
return tocSb.ToString();
}
private string PackageLogFile(string packageId)
{
var logLocationVar = $"{Constants.BundleLogName}_{packageId}";
// Variable won't exist until package has been run
if (!_engine.ContainsVariable(logLocationVar))
return null;
var logLocation = _engine.GetVariableString(logLocationVar);
if (string.IsNullOrWhiteSpace(logLocation))
return null;
var logFile = Path.GetFullPath(logLocation);
if (string.IsNullOrEmpty(logFile) || !File.Exists(logFile))
return null;
return logFile;
}
private string ReadLogFile(string fileName, string logName, int tocIndex)
{
string logText;
var bakFile = Path.GetFullPath($"{fileName}.view.bak");
// Copy the log file to avoid file contention.
File.Copy(fileName, bakFile);
try
{
logText = File.ReadAllText(bakFile);
}
catch (Exception ex)
{
logText = $"Unable to read file {bakFile} ({ex.Message})";
}
finally
{
File.Delete(bakFile);
}
var sb = new StringBuilder();
sb.AppendLine();
sb.AppendLine();
sb.AppendLine($"{tocIndex}. {logName}");
sb.AppendLine(Constants.Line);
sb.AppendLine(logText);
return sb.ToString();
}
}

View File

@@ -0,0 +1,112 @@
using Bootstrapper.Models.State;
using Bootstrapper.Models.Util;
using System;
using System.Diagnostics;
using System.IO;
using System.Windows;
using WixToolset.BootstrapperApplicationApi;
namespace Bootstrapper.Models;
/// <summary>
/// A model that exposes all the functionality of the BA.
/// </summary>
internal class Model
{
public Model(IEngine engine, IBootstrapperCommand commandInfo, WpfFacade uiFacade)
{
Engine = engine;
CommandInfo = commandInfo;
UiFacade = uiFacade;
Log = new Log(Engine);
State = new AppState(Engine, CommandInfo);
}
/// <summary>
/// Contains shared state used by the BA. All members are thread safe unless noted otherwise.
/// </summary>
public AppState State { get; }
/// <summary>
/// Command line parameters and other command info passed from the engine.
/// </summary>
public IBootstrapperCommand CommandInfo { get; }
/// <summary>
/// Read from and write to the bundle's log.
/// </summary>
public Log Log { get; }
/// <summary>
/// A facade exposing the limited UI functionality needed by the BA.
/// </summary>
public WpfFacade UiFacade { get; }
/// <summary>
/// WiX engine
/// </summary>
public IEngine Engine { get; }
/// <summary>
/// Starts the plan and apply phases with the given action.
/// </summary>
/// <param name="action">Action to plan</param>
public void PlanAndApply(LaunchAction action)
{
State.PlannedAction = action;
State.BaStatus = BaStatus.Planning;
State.CancelRequested = false;
Engine.Plan(action);
}
/// <summary>
/// Reads the log file and displays it in the user's default text editor.
/// </summary>
public void ShowLog()
{
try
{
var fileName = Path.GetFullPath($"{Engine.GetVariableString(Constants.BundleLogName)}.view.txt");
Log.WriteLogFile(State, fileName);
if (File.Exists(fileName))
{
Process process = null;
try
{
process = new Process();
process.StartInfo.FileName = fileName;
process.StartInfo.UseShellExecute = true;
process.StartInfo.Verb = "open";
process.Start();
}
finally
{
process?.Dispose();
}
}
}
catch (Exception ex)
{
UiFacade.ShowMessageBox($"Unable to display log: {ex.Message}", MessageBoxButton.OK, MessageBoxImage.Error, MessageBoxResult.OK);
}
}
/// <summary>
/// </summary>
public void SaveEmbeddedLog(int exitCode)
{
try
{
if (State.Display == Display.Embedded)
{
Log.Write($"Exit code: 0x{exitCode:X}");
Log.WriteLogFile(State, Log.EmbeddedLogFileName());
}
}
catch
{
// ignore
}
}
}

View File

@@ -0,0 +1,210 @@
using Bootstrapper.Models.Util;
using System;
using System.Text;
using System.Threading;
using WixToolset.BootstrapperApplicationApi;
namespace Bootstrapper.Models.State;
/// <summary>
/// Provides thread safe access to all state shared by the BA
/// </summary>
internal class AppState
{
private readonly IBootstrapperCommand _commandInfo;
private readonly object _lock = new();
private long _baStatus;
private long _plannedAction;
private long _relatedBundleStatus;
private string _relatedBundleId;
private string _relatedBundleVersion;
private long _phaseResult;
private string _errorMessage;
private long _cancelRequested;
private string _relatedBundleName;
public AppState(IEngine engine, IBootstrapperCommand commandInfo)
{
_commandInfo = commandInfo;
Bundle = new BootstrapperApplicationData().Bundle;
BundleVersion = engine.GetVariableVersion(Constants.VersionVariable);
_baStatus = (long)BaStatus.Initializing;
_relatedBundleStatus = (long)BundleStatus.Unknown;
_plannedAction = (long)LaunchAction.Unknown;
}
/// <summary>
/// Information about the packages included in the bundle.
/// </summary>
public IBundleInfo Bundle { get; }
/// <summary>
/// Version of the bundle that this BA will deploy.
/// </summary>
public string BundleVersion { get; }
/// <summary>
/// The display level of the BA.
/// </summary>
public Display Display => _commandInfo.Display;
/// <summary>
/// Whether a version of this bundle was previously installed, and if so, whether this bundle is newer or older than the
/// installed version.
/// </summary>
public BundleStatus RelatedBundleStatus
{
get => (BundleStatus)Interlocked.Read(ref _relatedBundleStatus);
set => Interlocked.Exchange(ref _relatedBundleStatus, (long)value);
}
/// <summary>
/// Package ID of the bundle that was discovered during the detection phase.
/// Will be <see langword="null" /> if not installed.
/// </summary>
public string RelatedBundleId
{
get
{
lock (_lock)
return _relatedBundleId;
}
set
{
lock (_lock)
_relatedBundleId = value;
}
}
public string RelatedBundleName
{
get
{
lock (_lock)
return _relatedBundleName;
}
set
{
lock (_lock)
_relatedBundleName = value;
}
}
/// <summary>
/// Version of the bundle that was discovered during the detection phase.
/// Will be <see langword="null" /> if not installed.
/// </summary>
public string RelatedBundleVersion
{
get
{
lock (_lock)
return _relatedBundleVersion;
}
set
{
lock (_lock)
_relatedBundleVersion = value;
}
}
/// <summary>
/// Current status of the BA.
/// </summary>
public BaStatus BaStatus
{
get => (BaStatus)Interlocked.Read(ref _baStatus);
set => Interlocked.Exchange(ref _baStatus, (long)value);
}
/// <summary>
/// Final result of the last phase that ran.
/// </summary>
public int PhaseResult
{
get => (int)Interlocked.Read(ref _phaseResult);
set => Interlocked.Exchange(ref _phaseResult, value);
}
/// <summary>
/// Action selected when beginning the plan phase.
/// </summary>
public LaunchAction PlannedAction
{
get => (LaunchAction)Interlocked.Read(ref _plannedAction);
set => Interlocked.Exchange(ref _plannedAction, (long)value);
}
/// <summary>
/// Can be set to <see langword="true" /> to cancel the plan and apply phases.
/// </summary>
public bool CancelRequested
{
get => Interlocked.Read(ref _cancelRequested) == 1L;
set => Interlocked.Exchange(ref _cancelRequested, Convert.ToInt32(value));
}
/// <summary>
/// Stores any error encountered during the apply phase.
/// </summary>
public string ErrorMessage
{
get
{
lock (_lock)
return _errorMessage;
}
set
{
lock (_lock)
_errorMessage = value;
}
}
/// <summary>
/// Gets the display name for a package if possible.
/// </summary>
/// <param name="packageId">Identity of the package.</param>
/// <returns>Display name of the package if found or the package id if not.</returns>
public string GetPackageName(string packageId)
{
var packageName = string.Empty;
if (packageId == RelatedBundleId)
packageName = RelatedBundleName;
else if (Bundle.Packages.TryGetValue(packageId, out var package) && !string.IsNullOrWhiteSpace(package.DisplayName))
packageName = package.DisplayName;
return packageName;
}
public override string ToString()
{
var tocSb = new StringBuilder();
string error;
if (string.IsNullOrWhiteSpace(ErrorMessage))
error = "None";
else
error = ErrorMessage;
string installedVersion;
if (string.IsNullOrWhiteSpace(RelatedBundleVersion))
installedVersion = "Not installed";
else
installedVersion = RelatedBundleVersion;
tocSb.AppendLine($"Bootstrapper status: {BaStatus}");
tocSb.AppendLine($"Bundle status: {RelatedBundleStatus}");
tocSb.AppendLine($"Bundle version: {BundleVersion}");
tocSb.AppendLine($"Installed version: {installedVersion}");
tocSb.AppendLine($"Planned action: {PlannedAction}");
tocSb.AppendLine($"Result of last phase: {PhaseResult}");
tocSb.AppendLine($"Bundle error message: {error}");
tocSb.AppendLine($"Display: {_commandInfo.Display}");
tocSb.AppendLine($"Command line: {_commandInfo.CommandLine}");
tocSb.AppendLine($"Command line action: {_commandInfo.Action}");
tocSb.AppendLine($"Command line resume: {_commandInfo.Resume}");
return tocSb.ToString();
}
}

View File

@@ -0,0 +1,9 @@
namespace Bootstrapper.Models.State
{
internal class ProgressReport
{
public string Message { get; set; }
public string PackageName { get; set; }
public int Progress { get; set; }
}
}

View File

@@ -0,0 +1,48 @@
namespace Bootstrapper.Models.Util
{
/// <summary>
/// The states of installation.
/// </summary>
internal enum BaStatus
{
/// <summary>
/// The BA is starting up.
/// </summary>
Initializing,
/// <summary>
/// The BA is busy running the detect phase.
/// </summary>
Detecting,
/// <summary>
/// The BA has completed the detect phase and is idle, waiting for the user to start the plan phase.
/// </summary>
Waiting,
/// <summary>
/// The BA is busy running the plan phase.
/// </summary>
Planning,
/// <summary>
/// The BA is busy running the apply phase.
/// </summary>
Applying,
/// <summary>
/// The apply phase has successfully completed and the BA is idle, waiting for the user to exit the app.
/// </summary>
Applied,
/// <summary>
/// The user cancelled a phase and the BA is idle, waiting for user input.
/// </summary>
Cancelled,
/// <summary>
/// A phase failed and the BA is idle, waiting for user input.
/// </summary>
Failed
}
}

View File

@@ -0,0 +1,30 @@
namespace Bootstrapper.Models.Util
{
/// <summary>
/// The states of bundle detection.
/// </summary>
internal enum BundleStatus
{
Unknown = 0,
/// <summary>
/// There are no upgrade related bundles installed.
/// </summary>
NotInstalled = 1,
/// <summary>
/// All upgrade related bundles that are installed are earlier versions than this bundle.
/// </summary>
OlderInstalled = 2,
/// <summary>
/// All upgrade related bundles that are installed are the same version as this bundle.
/// </summary>
Current = 3,
/// <summary>
/// At least one upgrade related bundle is installed that is a newer version than this bundle.
/// </summary>
NewerInstalled = 4
}
}

View File

@@ -0,0 +1,11 @@
namespace Bootstrapper.Models.Util
{
internal static class Constants
{
public const string BundleLogName = "WixBundleLog";
public const string VersionVariable = "WixBundleVersion";
public const string BundleNameVariable = "WixBundleName";
public const string RebootMessage = "This machine has other pending updates that require a reboot before the app can be installed. Please restart, then try installing again.";
public const string Line = "========================================================================================";
}
}

View File

@@ -0,0 +1,19 @@
using System;
using WixToolset.BootstrapperApplicationApi;
namespace Bootstrapper.Models.Util;
internal class DetectPhaseCompleteEventArgs : EventArgs
{
public DetectPhaseCompleteEventArgs(LaunchAction followupAction)
{
FollowupAction = followupAction;
}
/// <summary>
/// Indicates which action is being planned and executed after the detect phase has
/// completed. If <see cref="LaunchAction.Unknown" />, then no action is planned, and
/// the UI should prompt the user for the action (install, uninstall, updated, repair, etc.).
/// </summary>
public LaunchAction FollowupAction { get; }
}

View File

@@ -0,0 +1,12 @@
namespace Bootstrapper.Models.Util
{
/// <summary>
/// The states of detection.
/// </summary>
internal enum DetectionState
{
Unknown,
Absent,
Present
}
}

View File

@@ -0,0 +1,56 @@
using System.ComponentModel;
namespace Bootstrapper.Models.Util
{
public static class ErrorHelper
{
/// <summary>
/// WiX return code which indicates cancellation.
/// </summary>
public const int CancelCode = 1223;
/// <summary>
/// ERROR_INSTALL_USEREXIT (0x80070642)
/// </summary>
public const int CancelHResult = -2147023294;
public static bool HResultIsFailure(int hResult)
{
return hResult < 0;
}
/// <summary>
/// Converts an HRESULT to a win32 error.
/// </summary>
/// <param name="hResult"></param>
/// <returns></returns>
public static int HResultToWin32(int hResult)
{
var win32 = hResult;
if ((win32 & 0xFFFF0000) == 0x80070000)
win32 &= 0xFFFF;
return win32;
}
/// <summary>
/// Converts an HRESULT to a message.
/// </summary>
/// <param name="hResult"></param>
/// <returns></returns>
public static string HResultToMessage(int hResult)
{
if (hResult == 0)
return "OK";
if (HResultIsFailure(hResult))
{
var message = new Win32Exception(hResult).Message;
return $"0x{hResult:X} {message}";
}
return $"Result {hResult} (0x{hResult:X})";
}
}
}

View File

@@ -0,0 +1,15 @@
using System;
namespace Bootstrapper.Models.Util
{
internal class InstallerVariableNotFoundException : Exception
{
public InstallerVariableNotFoundException(string variableName)
: base($"The installer variable \"{variableName}\" could not be found.")
{ }
public InstallerVariableNotFoundException(string variableName, Exception innerException)
: base($"The installer variable \"{variableName}\" could not be found.", innerException)
{ }
}
}

View File

@@ -0,0 +1,16 @@
using System;
namespace Bootstrapper.Models.Util
{
/// <summary>
/// Exception raised when executing a phase
/// </summary>
internal class PhaseException : Exception
{
public PhaseException(Exception innerException)
: base(innerException.Message, innerException)
{
HResult = innerException.HResult;
}
}
}

View File

@@ -0,0 +1,201 @@
using Bootstrapper.Models.State;
using Bootstrapper.Models.Util;
using Bootstrapper.ViewModels;
using Bootstrapper.Views;
using System;
using System.Windows;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Threading;
using WixToolset.BootstrapperApplicationApi;
namespace Bootstrapper.Models;
internal class WpfFacade
{
private readonly Log _log;
private ShellViewModel _shellVm;
private Window _shell;
private Dispatcher _dispatcher;
public WpfFacade(Log log, Display display)
{
_log = log ?? throw new ArgumentNullException(nameof(log));
IsUiShown = display == Display.Full || display == Display.Passive;
}
/// <summary>
/// Dispatches progress reports to the UI. Will be <see langword="null" /> when there is no UI to receive these reports.
/// </summary>
public IProgress<ProgressReport> ProgressReporter { get; private set; }
/// <summary>
/// A valid window handle required for the apply phase.
/// </summary>
public IntPtr ShellWindowHandle { get; private set; }
/// <summary>
/// Returns <see langword="false" /> when the installer is running silently.
/// </summary>
public bool IsUiShown { get; }
/// <summary>
/// Builds out needed UI elements and displays the shell window if not running silently.
/// </summary>
/// <param name="model"></param>
public void Initialize(Model model)
{
_dispatcher = Dispatcher.CurrentDispatcher;
_dispatcher.UnhandledException += Dispatcher_UnhandledException;
_shell = new ShellView();
ShellWindowHandle = new WindowInteropHelper(_shell).EnsureHandle();
// Stop message loop when the window is closed.
_shell.Closed += (sender, e) => _dispatcher.InvokeShutdown();
if (!IsUiShown)
return;
_shellVm = new ShellViewModel(model);
_shell.DataContext = _shellVm;
ProgressReporter = new Progress<ProgressReport>(r => _shellVm.ProgressVm.ProcessProgressReport(r));
_log.Write("Displaying UI.");
_shell.Show();
}
/// <summary>
/// Starts the message loop for the UI framework. This is a blocking call that is exited by calling.
/// <see cref="ShutDown" />.
/// </summary>
/// <exception cref="InvalidOperationException"></exception>
public void RunMessageLoop()
{
if (_shell == null)
throw new InvalidOperationException($"{nameof(Initialize)} must be called before the message loop can be started");
Dispatcher.Run();
}
/// <summary>
/// Executes the given action on "the UI thread".
/// </summary>
/// <param name="action">Action to execute</param>
/// <param name="blockUntilComplete">
/// If <see langword="true" />, then this call will block until the action completes.
/// If <see langword="false" />, this call immediately returns after queuing the action
/// for processing by the message loop.
/// </param>
public void Dispatch(Action action, bool blockUntilComplete = true)
{
if (blockUntilComplete)
{
// No need to dispatch if already running on the UI thread
if (_dispatcher.CheckAccess())
action();
else
_dispatcher.Invoke(DispatcherPriority.Normal, action);
}
else
_dispatcher.BeginInvoke(DispatcherPriority.Normal, action);
}
/// <summary>
/// Closes any displayed windows and stops the message loop.
/// </summary>
public void ShutDown()
{
Dispatch(CloseShell);
}
/// <summary>
/// Submits a request to the UI to refresh all commands.
/// </summary>
public void Refresh()
{
if (IsUiShown)
Dispatch(CommandManager.InvalidateRequerySuggested);
}
/// <summary>
/// Displays a message box with the given criteria
/// </summary>
/// <param name="message"></param>
/// <param name="buttons"></param>
/// <param name="image"></param>
/// <param name="defaultResult"></param>
/// <returns></returns>
public MessageBoxResult ShowMessageBox(string message, MessageBoxButton buttons, MessageBoxImage image, MessageBoxResult defaultResult)
{
var result = defaultResult;
if (IsUiShown)
{
Dispatch(
() => result = MessageBox.Show(
_shell,
message,
"Installation",
buttons,
image,
defaultResult));
}
else
{
Dispatch(
() => result = MessageBox.Show(
message,
"Installation",
buttons,
image,
defaultResult));
}
return result;
}
/// <summary>
/// Informs the UI that the detect phase has completed.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public void OnDetectPhaseComplete(object sender, DetectPhaseCompleteEventArgs e)
{
if (_shellVm != null)
{
_log.Write($"{nameof(WpfFacade)}: Notified that detect is complete. Dispatching UI refresh tasks.");
Dispatch(() => _shellVm.AfterDetect(e.FollowupAction), false);
}
}
/// <summary>
/// Informs the UI that the apply phase has completed
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public void OnApplyPhaseComplete(object sender, EventArgs e)
{
if (_shellVm != null)
{
_log.Write($"{nameof(WpfFacade)}: Notified that installation has completed. Dispatching UI refresh tasks.");
Dispatch(_shellVm.AfterApply, false);
}
}
private void CloseShell()
{
if (IsUiShown)
_shell.Close();
_dispatcher.InvokeShutdown();
}
private void Dispatcher_UnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
{
e.Handled = true;
_log.Write(e.Exception);
if (IsUiShown)
ShowMessageBox($"An error occurred:\r\n{e.Exception.Message}", MessageBoxButton.OK, MessageBoxImage.Error, MessageBoxResult.OK);
}
}

View File

@@ -0,0 +1,554 @@
using Bootstrapper.Models;
using Bootstrapper.Models.Util;
using System;
using System.Linq;
using System.Windows;
using WixToolset.BootstrapperApplicationApi;
namespace Bootstrapper.Phases;
internal class ApplyPhase
{
private readonly Model _model;
public ApplyPhase(Model model)
{
_model = model;
}
public event EventHandler<EventArgs> ApplyPhaseComplete;
/// <summary>
/// Fired when the engine has begun installing the bundle.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
/// <exception cref="PhaseException"></exception>
public virtual void OnApplyBegin(object sender, ApplyBeginEventArgs e)
{
try
{
_model.State.PhaseResult = 0;
_model.State.ErrorMessage = string.Empty;
if (e.Cancel)
return;
_model.State.BaStatus = BaStatus.Applying;
}
catch (Exception ex)
{
_model.Log.Write(ex);
throw new PhaseException(ex);
}
}
/// <summary>
/// Fired when the engine has completed installing the bundle.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
/// <exception cref="PhaseException"></exception>
public virtual void OnApplyComplete(object sender, ApplyCompleteEventArgs e)
{
try
{
_model.State.PhaseResult = e.Status;
// Set the state to applied or failed unless the user cancelled.
if (_model.State.BaStatus == BaStatus.Cancelled || e.Status == ErrorHelper.CancelHResult)
{
_model.State.BaStatus = BaStatus.Cancelled;
_model.Log.Write("User cancelled");
}
else if (ErrorHelper.HResultIsFailure(e.Status))
{
_model.State.BaStatus = BaStatus.Failed;
var msg = $"Apply failed - {ErrorHelper.HResultToMessage(e.Status)}";
if (string.IsNullOrEmpty(_model.State.ErrorMessage))
_model.State.ErrorMessage = msg;
_model.Log.Write(msg);
if (e.Restart == ApplyRestart.RestartRequired && _model.UiFacade.IsUiShown)
_model.UiFacade.ShowMessageBox(Constants.RebootMessage, MessageBoxButton.OK, MessageBoxImage.Stop, MessageBoxResult.OK);
}
else
_model.State.BaStatus = BaStatus.Applied;
}
catch (Exception ex)
{
_model.Log.Write(ex);
throw new PhaseException(ex);
}
finally
{
if (_model.State.Display == Display.Full)
ApplyPhaseComplete?.Invoke(this, EventArgs.Empty);
else
_model.UiFacade.ShutDown();
}
}
/// <summary>
/// Fired when the engine has encountered an error.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
/// <exception cref="PhaseException"></exception>
public virtual void OnError(object sender, ErrorEventArgs e)
{
try
{
if (e.ErrorCode == ErrorHelper.CancelCode)
_model.State.BaStatus = BaStatus.Cancelled;
else
{
_model.State.ErrorMessage = e.ErrorMessage;
_model.Log.Write("Error encountered");
_model.Log.Write(e.ErrorMessage, true);
_model.Log.Write($"Type: {e.ErrorType}", true);
_model.Log.Write($"Code: {e.ErrorCode}", true);
if (!string.IsNullOrWhiteSpace(e.PackageId))
_model.Log.Write($"Package: {e.PackageId}", true);
var data = e.Data?.Where(d => !string.IsNullOrWhiteSpace(d)).ToArray() ?? Array.Empty<string>();
if (data.Length > 0)
{
_model.Log.Write("Data:", true);
foreach (var d in data)
_model.Log.Write($" {d}", true);
}
if (_model.UiFacade.IsUiShown)
{
// Show an error dialog.
var button = MessageBoxButton.OK;
var buttonHint = e.UIHint & 0xF;
if (buttonHint >= 0 && buttonHint <= 4)
button = (MessageBoxButton)buttonHint;
var response = _model.UiFacade.ShowMessageBox(e.ErrorMessage, button, MessageBoxImage.Error, MessageBoxResult.None);
if (buttonHint == (int)button)
{
// If WiX supplied a hint, return the result
e.Result = (Result)response;
_model.Log.Write($"User response: {response}");
}
}
}
}
catch (Exception ex)
{
_model.Log.Write(ex);
throw new PhaseException(ex);
}
}
/// <summary>
/// Fired when the plan determined that nothing should happen to prevent downgrading.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public virtual void OnApplyDowngrade(object sender, ApplyDowngradeEventArgs e)
{ }
/// <summary>
/// Fired when the engine has begun installing packages.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public virtual void OnExecuteBegin(object sender, ExecuteBeginEventArgs e)
{ }
/// <summary>
/// Fired when the engine has completed installing packages.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public virtual void OnExecuteComplete(object sender, ExecuteCompleteEventArgs e)
{ }
/// <summary>
/// Fired by the engine while executing a package.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public virtual void OnExecuteProgress(object sender, ExecuteProgressEventArgs e)
{ }
///// <summary>
///// Fired when the engine has begun to set up the update package.
///// </summary>
///// <param name="sender"></param>
///// <param name="e"></param>
//public virtual void OnSetUpdateBegin(object sender, SetUpdateBeginEventArgs e)
//{ }
///// <summary>
///// Fired when the engine has completed setting up the update package.
///// </summary>
///// <param name="sender"></param>
///// <param name="e"></param>
///// <exception cref="PhaseException"></exception>
//public virtual void OnSetUpdateComplete(object sender, SetUpdateCompleteEventArgs e)
//{ }
/// <summary>
/// Fired when the engine executes one or more patches targeting a product.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public virtual void OnExecutePatchTarget(object sender, ExecutePatchTargetEventArgs e)
{ }
/// <summary>
/// Fired when the engine is about to begin an MSI transaction.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public virtual void OnBeginMsiTransactionBegin(object sender, BeginMsiTransactionBeginEventArgs e)
{ }
/// <summary>
/// Fired when the engine has completed beginning an MSI transaction.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public virtual void OnBeginMsiTransactionComplete(object sender, BeginMsiTransactionCompleteEventArgs e)
{ }
/// <summary>
/// Fired when the engine is about to commit an MSI transaction.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public virtual void OnCommitMsiTransactionBegin(object sender, CommitMsiTransactionBeginEventArgs e)
{ }
/// <summary>
/// Fired when the engine has completed comitting an MSI transaction.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public virtual void OnCommitMsiTransactionComplete(object sender, CommitMsiTransactionCompleteEventArgs e)
{ }
/// <summary>
/// Fired when the engine is about to rollback an MSI transaction.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public virtual void OnRollbackMsiTransactionBegin(object sender, RollbackMsiTransactionBeginEventArgs e)
{ }
/// <summary>
/// Fired when the engine has completed rolling back an MSI transaction.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public virtual void OnRollbackMsiTransactionComplete(object sender, RollbackMsiTransactionCompleteEventArgs e)
{ }
/// <summary>
/// Fired when the engine has begun acquiring the payload or container.
/// The BA can change the source using
/// <see cref="M:WixToolset.Mba.Core.IEngine.SetLocalSource(System.String,System.String,System.String)" />
/// or
/// <see
/// cref="M:WixToolset.Mba.Core.IEngine.SetDownloadSource(System.String,System.String,System.String,System.String,System.String)" />
/// .
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public virtual void OnCacheAcquireBegin(object sender, CacheAcquireBeginEventArgs e)
{ }
/// <summary>
/// Fired when the engine has completed the acquisition of the payload or container.
/// The BA can change the source using
/// <see cref="M:WixToolset.Mba.Core.IEngine.SetLocalSource(System.String,System.String,System.String)" />
/// or
/// <see
/// cref="M:WixToolset.Mba.Core.IEngine.SetDownloadSource(System.String,System.String,System.String,System.String,System.String)" />
/// .
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public virtual void OnCacheAcquireComplete(object sender, CacheAcquireCompleteEventArgs e)
{ }
/// <summary>
/// Fired by the engine to allow the BA to override the acquisition action.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public virtual void OnCacheAcquireResolving(object sender, CacheAcquireResolvingEventArgs e)
{ }
/// <summary>
/// Fired when the engine has progress acquiring the payload or container.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public virtual void OnCacheAcquireProgress(object sender, CacheAcquireProgressEventArgs e)
{ }
/// <summary>
/// Fired when the engine has begun caching the installation sources.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public virtual void OnCacheBegin(object sender, CacheBeginEventArgs e)
{ }
/// <summary>
/// Fired after the engine has cached the installation sources.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public virtual void OnCacheComplete(object sender, CacheCompleteEventArgs e)
{ }
/// <summary>
/// Fired when the engine begins the verification of the payload or container that was already in the package cache.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public virtual void OnCacheContainerOrPayloadVerifyBegin(object sender, CacheContainerOrPayloadVerifyBeginEventArgs e)
{ }
/// <summary>
/// Fired when the engine has completed the verification of the payload or container that was already in the package
/// cache.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public virtual void OnCacheContainerOrPayloadVerifyComplete(object sender, CacheContainerOrPayloadVerifyCompleteEventArgs e)
{ }
/// <summary>
/// Fired when the engine has progress verifying the payload or container that was already in the package cache.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public virtual void OnCacheContainerOrPayloadVerifyProgress(object sender, CacheContainerOrPayloadVerifyProgressEventArgs e)
{ }
/// <summary>
/// Fired when the engine has begun caching a specific package.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public virtual void OnCachePackageBegin(object sender, CachePackageBeginEventArgs e)
{ }
/// <summary>
/// Fired when the engine has completed caching a specific package.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public virtual void OnCachePackageComplete(object sender, CachePackageCompleteEventArgs e)
{ }
/// <summary>
/// Fired when the engine failed validating a package in the package cache that is non-vital to execution.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public virtual void OnCachePackageNonVitalValidationFailure(object sender, CachePackageNonVitalValidationFailureEventArgs e)
{ }
/// <summary>
/// Fired when the engine begins the extraction of the payload from the container.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public virtual void OnCachePayloadExtractBegin(object sender, CachePayloadExtractBeginEventArgs e)
{ }
/// <summary>
/// Fired when the engine has completed the extraction of the payload from the container.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public virtual void OnCachePayloadExtractComplete(object sender, CachePayloadExtractCompleteEventArgs e)
{ }
/// <summary>
/// Fired when the engine has progress extracting the payload from the container.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public virtual void OnCachePayloadExtractProgress(object sender, CachePayloadExtractProgressEventArgs e)
{ }
/// <summary>
/// Fired when the engine begins the verification of the acquired payload or container.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public virtual void OnCacheVerifyBegin(object sender, CacheVerifyBeginEventArgs e)
{ }
/// <summary>
/// Fired when the engine has completed the verification of the acquired payload or container.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public virtual void OnCacheVerifyComplete(object sender, CacheVerifyCompleteEventArgs e)
{ }
/// <summary>
/// Fired when the engine has progress verifying the payload or container.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public virtual void OnCacheVerifyProgress(object sender, CacheVerifyProgressEventArgs e)
{ }
/// <summary>
/// Fired when the engine has begun installing a specific package.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public virtual void OnExecutePackageBegin(object sender, ExecutePackageBeginEventArgs e)
{ }
/// <summary>
/// Fired when the engine has completed installing a specific package.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public virtual void OnExecutePackageComplete(object sender, ExecutePackageCompleteEventArgs e)
{ }
/// <summary>
/// Fired when the engine is about to pause Windows automatic updates.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public virtual void OnPauseAutomaticUpdatesBegin(object sender, PauseAutomaticUpdatesBeginEventArgs e)
{ }
/// <summary>
/// Fired when the engine has completed pausing Windows automatic updates.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public virtual void OnPauseAutomaticUpdatesComplete(object sender, PauseAutomaticUpdatesCompleteEventArgs e)
{ }
/// <summary>
/// Fired when the engine is about to take a system restore point.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public virtual void OnSystemRestorePointBegin(object sender, SystemRestorePointBeginEventArgs e)
{ }
/// <summary>
/// Fired when the engine has completed taking a system restore point.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public virtual void OnSystemRestorePointComplete(object sender, SystemRestorePointCompleteEventArgs e)
{ }
/// <summary>
/// Fired when the engine is about to start the elevated process.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public virtual void OnElevateBegin(object sender, ElevateBeginEventArgs e)
{ }
/// <summary>
/// Fired when the engine has completed starting the elevated process.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public virtual void OnElevateComplete(object sender, ElevateCompleteEventArgs e)
{ }
/// <summary>
/// Fired when the engine is about to launch the preapproved executable.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public virtual void OnLaunchApprovedExeBegin(object sender, LaunchApprovedExeBeginEventArgs e)
{ }
/// <summary>
/// Fired when the engine has completed launching the preapproved executable.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public virtual void OnLaunchApprovedExeComplete(object sender, LaunchApprovedExeCompleteEventArgs e)
{ }
/// <summary>
/// Fired when the engine has begun registering the location and visibility of the bundle.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public virtual void OnRegisterBegin(object sender, RegisterBeginEventArgs e)
{ }
/// <summary>
/// Fired when the engine has completed registering the location and visibility of the bundle.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public virtual void OnRegisterComplete(object sender, RegisterCompleteEventArgs e)
{ }
/// <summary>
/// Fired when the engine unregisters the bundle.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public virtual void OnUnregisterBegin(object sender, UnregisterBeginEventArgs e)
{ }
/// <summary>
/// Fired when the engine unregistration is complete.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public virtual void OnUnregisterComplete(object sender, UnregisterCompleteEventArgs e)
{ }
/// <summary>
/// Fired when the engine has changed progress for the bundle installation.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public virtual void OnProgress(object sender, ProgressEventArgs e)
{ }
/// <summary>
/// Fired when Windows Installer sends an installation message.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public virtual void OnExecuteMsiMessage(object sender, ExecuteMsiMessageEventArgs e)
{ }
/// <summary>
/// Fired when a package that spawned a process is cancelled.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public virtual void OnExecuteProcessCancel(object sender, ExecuteProcessCancelEventArgs e)
{ }
/// <summary>
/// Fired when a package sends a files in use installation message.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public virtual void OnExecuteFilesInUse(object sender, ExecuteFilesInUseEventArgs e)
{ }
}

View File

@@ -0,0 +1,29 @@
using Bootstrapper.Models;
using WixToolset.BootstrapperApplicationApi;
namespace Bootstrapper.Phases;
/// <summary>
/// Manages cancellation
/// </summary>
internal class CancelHandler
{
private readonly Model _model;
public CancelHandler(Model model)
{
_model = model;
}
public void CheckForCancel(object sender, CancellableHResultEventArgs e)
{
if (!e.Cancel && _model.State.CancelRequested)
e.Cancel = true;
}
public void CheckResult(object sender, ResultEventArgs e)
{
if (e.Result != Result.Abort && e.Result != Result.Error && e.Result != Result.Cancel && _model.State.CancelRequested)
e.Result = Result.Cancel;
}
}

View File

@@ -0,0 +1,287 @@
using Bootstrapper.Models;
using Bootstrapper.Models.Util;
using System;
using WixToolset.BootstrapperApplicationApi;
namespace Bootstrapper.Phases;
internal class DetectPhase
{
private readonly Model _model;
private DetectionState _bundleDetectedState;
public DetectPhase(Model model)
{
_model = model;
_bundleDetectedState = DetectionState.Unknown;
}
public event EventHandler<DetectPhaseCompleteEventArgs> DetectPhaseComplete;
/// <summary>
/// Fired when the engine is starting up the bootstrapper application.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public virtual void OnStartup(object sender, StartupEventArgs e)
{ }
/// <summary>
/// Fired when the engine is shutting down the bootstrapper application.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public virtual void OnShutdown(object sender, ShutdownEventArgs e)
{ }
/// <summary>
/// Fired when the overall detection phase has begun.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
/// <exception cref="PhaseException"></exception>
public virtual void OnDetectBegin(object sender, DetectBeginEventArgs e)
{
try
{
_model.State.BaStatus = BaStatus.Detecting;
if (e.RegistrationType == RegistrationType.Full)
_bundleDetectedState = DetectionState.Present;
else
_bundleDetectedState = DetectionState.Absent;
_model.Log.Write($"{nameof(_bundleDetectedState)} set to {_bundleDetectedState}");
}
catch (Exception ex)
{
_model.Log.Write(ex);
throw new PhaseException(ex);
}
}
/// <summary>
/// Fired when a related bundle has been detected for a bundle.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
/// <remarks>
/// Helpful when the detected bundle has the same upgrade code that this one does.
/// </remarks>
public virtual void OnDetectRelatedBundle(object sender, DetectRelatedBundleEventArgs e)
{
try
{
// If the detected bundle's upgrade code matches this bundle, but product code and version are different...
if (e.RelationType == RelationType.Upgrade)
{
_bundleDetectedState = DetectionState.Present;
if (string.IsNullOrWhiteSpace(_model.State.RelatedBundleVersion))
_model.State.RelatedBundleVersion = e.Version;
_model.Log.Write($"Detected version = {e.Version} / Bundle version = {_model.State.BundleVersion}");
if (_model.Engine.CompareVersions(_model.State.BundleVersion, e.Version) > 0)
{
if (_model.State.RelatedBundleStatus <= BundleStatus.Current)
_model.State.RelatedBundleStatus = BundleStatus.OlderInstalled;
}
else if (_model.Engine.CompareVersions(_model.State.BundleVersion, e.Version) == 0)
{
if (_model.State.RelatedBundleStatus == BundleStatus.NotInstalled)
_model.State.RelatedBundleStatus = BundleStatus.Current;
}
else
_model.State.RelatedBundleStatus = BundleStatus.NewerInstalled;
_model.Log.Write($"{nameof(_model.State.RelatedBundleStatus)} set to {_model.State.RelatedBundleStatus}");
}
if (!_model.State.Bundle.Packages.ContainsKey(e.ProductCode))
{
var package = _model.State.Bundle.AddRelatedBundleAsPackage(e.ProductCode, e.RelationType, e.PerMachine, e.Version);
_model.State.RelatedBundleId = package.Id;
if (_model.Engine.ContainsVariable(Constants.BundleNameVariable))
{
var name = _model.Engine.GetVariableString(Constants.BundleNameVariable);
_model.State.RelatedBundleName = $"{name} v{_model.State.RelatedBundleVersion}";
}
else
_model.State.RelatedBundleName = $"v{_model.State.RelatedBundleVersion}";
}
}
catch (Exception ex)
{
_model.Log.Write(ex);
throw new PhaseException(ex);
}
}
/// <summary>
/// Fired when the detection phase has completed.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
/// <exception cref="PhaseException"></exception>
public virtual void OnDetectComplete(object sender, DetectCompleteEventArgs e)
{
var followupAction = LaunchAction.Unknown;
try
{
_model.State.PhaseResult = e.Status;
if (ErrorHelper.HResultIsFailure(e.Status))
{
var msg = $"Detect failed - {ErrorHelper.HResultToMessage(e.Status)}";
_model.Log.Write(msg);
if (string.IsNullOrEmpty(_model.State.ErrorMessage))
_model.State.ErrorMessage = msg;
if (!_model.UiFacade.IsUiShown)
_model.UiFacade.ShutDown();
return;
}
if (_model.State.RelatedBundleStatus == BundleStatus.Unknown)
{
if (_bundleDetectedState == DetectionState.Present)
{
_model.State.RelatedBundleStatus = BundleStatus.Current;
if (string.IsNullOrWhiteSpace(_model.State.RelatedBundleVersion))
_model.State.RelatedBundleVersion = _model.State.BundleVersion;
}
else
_model.State.RelatedBundleStatus = BundleStatus.NotInstalled;
}
_model.State.BaStatus = BaStatus.Waiting;
if (_model.CommandInfo.Action == LaunchAction.Uninstall && _model.CommandInfo.Resume == ResumeType.Arp)
{
_model.Log.Write("Starting plan for automatic uninstall");
followupAction = _model.CommandInfo.Action;
}
else if (_model.State.Display != Display.Full)
{
_model.Log.Write("Starting plan for silent mode.");
followupAction = _model.CommandInfo.Action;
}
}
catch (Exception ex)
{
_model.Log.Write(ex);
throw new PhaseException(ex);
}
finally
{
// Can't start plan until UI is notified
NotifyDetectComplete(followupAction);
}
try
{
if (followupAction != LaunchAction.Unknown)
_model.PlanAndApply(followupAction);
}
catch (Exception ex)
{
_model.Log.Write(ex);
throw new PhaseException(ex);
}
}
/// <summary>
/// Fired when a related bundle has been detected for a bundle package.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public virtual void OnDetectRelatedBundlePackage(object sender, DetectRelatedBundlePackageEventArgs e)
{ }
/// <summary>
/// Fired when a related MSI package has been detected for a package.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public virtual void OnDetectRelatedMsiPackage(object sender, DetectRelatedMsiPackageEventArgs e)
{ }
/// <summary>
/// Fired when the update detection has found a potential update candidate.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public virtual void OnDetectUpdate(object sender, DetectUpdateEventArgs e)
{ }
/// <summary>
/// Fired when the update detection phase has begun.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public virtual void OnDetectUpdateBegin(object sender, DetectUpdateBeginEventArgs e)
{ }
/// <summary>
/// Fired when the update detection phase has completed.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public virtual void OnDetectUpdateComplete(object sender, DetectUpdateCompleteEventArgs e)
{ }
/// <summary>
/// Fired when a forward compatible bundle is detected.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public virtual void OnDetectForwardCompatibleBundle(object sender, DetectForwardCompatibleBundleEventArgs e)
{ }
/// <summary>
/// Fired when the detection for a specific package has begun.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public virtual void OnDetectPackageBegin(object sender, DetectPackageBeginEventArgs e)
{ }
/// <summary>
/// Fired when the detection for a specific package has completed.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public virtual void OnDetectPackageComplete(object sender, DetectPackageCompleteEventArgs e)
{ }
/// <summary>
/// Fired when the engine detects a target product for an MSP package.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public virtual void OnDetectPatchTarget(object sender, DetectPatchTargetEventArgs e)
{ }
/// <summary>
/// Fired when a package was not detected but a package using the same provider key was.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public virtual void OnDetectCompatibleMsiPackage(object sender, DetectCompatibleMsiPackageEventArgs e)
{ }
/// <summary>
/// Fired when a feature in an MSI package has been detected.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public virtual void OnDetectMsiFeature(object sender, DetectMsiFeatureEventArgs e)
{ }
private void NotifyDetectComplete(LaunchAction followupAction)
{
if (_model.UiFacade.IsUiShown)
DetectPhaseComplete?.Invoke(this, new DetectPhaseCompleteEventArgs(followupAction));
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,435 @@
using Bootstrapper.Models;
using Bootstrapper.Models.Util;
using System;
using WixToolset.BootstrapperApplicationApi;
namespace Bootstrapper.Phases;
internal class LoggingDetectPhase : DetectPhase
{
private readonly Log _logger;
public LoggingDetectPhase(Model model)
: base(model)
{
_logger = model.Log;
}
/// <inheritdoc />
public override void OnStartup(object sender, StartupEventArgs e)
{
try
{
_logger.Write($"{nameof(DetectPhase)}: {nameof(OnStartup)} -------v");
base.OnStartup(sender, e);
_logger.Write($"{nameof(e.HResult)} = {ErrorHelper.HResultToMessage(e.HResult)}", true);
_logger.Write($"{nameof(DetectPhase)}: {nameof(OnStartup)} -------^");
}
catch (PhaseException)
{
throw;
}
catch (Exception ex)
{
_logger.Write(ex);
throw new PhaseException(ex);
}
}
/// <inheritdoc />
public override void OnShutdown(object sender, ShutdownEventArgs e)
{
try
{
_logger.Write($"{nameof(DetectPhase)}: {nameof(OnShutdown)} -------v");
base.OnShutdown(sender, e);
_logger.Write($"{nameof(e.Action)} = {e.Action}", true);
_logger.Write($"{nameof(e.HResult)} = {ErrorHelper.HResultToMessage(e.HResult)}", true);
_logger.Write($"{nameof(DetectPhase)}: {nameof(OnShutdown)} -------^");
}
catch (PhaseException)
{
throw;
}
catch (Exception ex)
{
_logger.Write(ex);
throw new PhaseException(ex);
}
}
/// <inheritdoc />
public override void OnDetectBegin(object sender, DetectBeginEventArgs e)
{
try
{
_logger.Write($"{nameof(DetectPhase)}: {nameof(OnDetectBegin)} -------v");
_logger.Write($"{nameof(e.PackageCount)} = {e.PackageCount}", true);
_logger.Write($"{nameof(e.Cached)} = {e.Cached}", true);
_logger.Write($"{nameof(e.RegistrationType)} = {e.RegistrationType}", true);
base.OnDetectBegin(sender, e);
_logger.Write($"{nameof(e.HResult)} = {ErrorHelper.HResultToMessage(e.HResult)}", true);
_logger.Write($"{nameof(DetectPhase)}: {nameof(OnDetectBegin)} -------^");
}
catch (PhaseException)
{ }
catch (Exception ex)
{
_logger.Write(ex);
e.HResult = ex.HResult;
}
}
/// <inheritdoc />
public override void OnDetectComplete(object sender, DetectCompleteEventArgs e)
{
try
{
_logger.Write($"{nameof(DetectPhase)}: {nameof(OnDetectComplete)} -------v");
_logger.Write($"{nameof(e.Status)} = {ErrorHelper.HResultToMessage(e.Status)}", true);
_logger.Write($"{nameof(e.EligibleForCleanup)} = {e.EligibleForCleanup}", true);
base.OnDetectComplete(sender, e);
_logger.Write($"{nameof(e.HResult)} = {ErrorHelper.HResultToMessage(e.HResult)}", true);
_logger.Write($"{nameof(DetectPhase)}: {nameof(OnDetectComplete)} -------^");
}
catch (PhaseException)
{
throw;
}
catch (Exception ex)
{
_logger.Write(ex);
throw new PhaseException(ex);
}
}
/// <inheritdoc />
public override void OnDetectRelatedBundle(object sender, DetectRelatedBundleEventArgs e)
{
try
{
_logger.Write($"{nameof(DetectPhase)}: {nameof(OnDetectRelatedBundle)} -------v");
_logger.Write($"{nameof(e.ProductCode)} = {e.ProductCode}", true);
_logger.Write($"{nameof(e.Version)} = {e.Version}", true);
_logger.Write($"{nameof(e.BundleTag)} = {e.BundleTag}", true);
_logger.Write($"{nameof(e.PerMachine)} = {e.PerMachine}", true);
_logger.Write($"{nameof(e.RelationType)} = {e.RelationType}", true);
_logger.Write($"{nameof(e.MissingFromCache)} = {e.MissingFromCache}", true);
base.OnDetectRelatedBundle(sender, e);
_logger.Write($"{nameof(e.HResult)} = {ErrorHelper.HResultToMessage(e.HResult)}", true);
_logger.Write($"{nameof(DetectPhase)}: {nameof(OnDetectRelatedBundle)} -------^");
}
catch (PhaseException)
{
throw;
}
catch (Exception ex)
{
_logger.Write(ex);
throw new PhaseException(ex);
}
}
/// <inheritdoc />
public override void OnDetectRelatedBundlePackage(object sender, DetectRelatedBundlePackageEventArgs e)
{
try
{
_logger.Write($"{nameof(DetectPhase)}: {nameof(OnDetectRelatedBundlePackage)} -------v");
_logger.Write($"{nameof(e.PackageId)} = {e.PackageId}", true);
_logger.Write($"{nameof(e.ProductCode)} = {e.ProductCode}", true);
_logger.Write($"{nameof(e.Version)} = {e.Version}", true);
_logger.Write($"{nameof(e.RelationType)} = {e.RelationType}", true);
_logger.Write($"{nameof(e.PerMachine)} = {e.PerMachine}", true);
base.OnDetectRelatedBundlePackage(sender, e);
_logger.Write($"{nameof(e.HResult)} = {ErrorHelper.HResultToMessage(e.HResult)}", true);
_logger.Write($"{nameof(DetectPhase)}: {nameof(OnDetectRelatedBundlePackage)} -------^");
}
catch (PhaseException)
{
throw;
}
catch (Exception ex)
{
_logger.Write(ex);
throw new PhaseException(ex);
}
}
/// <inheritdoc />
public override void OnDetectRelatedMsiPackage(object sender, DetectRelatedMsiPackageEventArgs e)
{
try
{
_logger.Write($"{nameof(DetectPhase)}: {nameof(OnDetectRelatedMsiPackage)} -------v");
_logger.Write($"{nameof(e.PackageId)} = {e.PackageId}", true);
_logger.Write($"{nameof(e.UpgradeCode)} = {e.UpgradeCode}", true);
_logger.Write($"{nameof(e.ProductCode)} = {e.ProductCode}", true);
_logger.Write($"{nameof(e.Version)} = {e.Version}", true);
_logger.Write($"{nameof(e.PerMachine)} = {e.PerMachine}", true);
_logger.Write($"{nameof(e.Operation)} = {e.Operation}", true);
base.OnDetectRelatedMsiPackage(sender, e);
_logger.Write($"{nameof(e.HResult)} = {ErrorHelper.HResultToMessage(e.HResult)}", true);
_logger.Write($"{nameof(DetectPhase)}: {nameof(OnDetectRelatedMsiPackage)} -------^");
}
catch (PhaseException)
{
throw;
}
catch (Exception ex)
{
_logger.Write(ex);
throw new PhaseException(ex);
}
}
/// <inheritdoc />
public override void OnDetectUpdate(object sender, DetectUpdateEventArgs e)
{
try
{
_logger.Write($"{nameof(DetectPhase)}: {nameof(OnDetectUpdate)} -------v");
_logger.Write($"{nameof(e.Title)} = {e.Title}", true);
_logger.Write($"{nameof(e.Summary)} = {e.Summary}", true);
_logger.Write($"{nameof(e.Version)} = {e.Version}", true);
_logger.Write($"{nameof(e.UpdateLocation)} = {e.UpdateLocation}", true);
base.OnDetectUpdate(sender, e);
_logger.Write($"{nameof(e.StopProcessingUpdates)} = {e.StopProcessingUpdates}");
_logger.Write($"{nameof(e.HResult)} = {ErrorHelper.HResultToMessage(e.HResult)}", true);
_logger.Write($"{nameof(DetectPhase)}: {nameof(OnDetectUpdate)} -------^");
}
catch (PhaseException)
{
throw;
}
catch (Exception ex)
{
_logger.Write(ex);
throw new PhaseException(ex);
}
}
/// <inheritdoc />
public override void OnDetectUpdateBegin(object sender, DetectUpdateBeginEventArgs e)
{
try
{
_logger.Write($"{nameof(DetectPhase)}: {nameof(OnDetectUpdateBegin)} -------v");
_logger.Write($"{nameof(e.UpdateLocation)} = {e.UpdateLocation}", true);
base.OnDetectUpdateBegin(sender, e);
_logger.Write($"{nameof(e.Skip)} = {e.Skip}", true);
_logger.Write($"{nameof(e.HResult)} = {ErrorHelper.HResultToMessage(e.HResult)}", true);
_logger.Write($"{nameof(DetectPhase)}: {nameof(OnDetectUpdateBegin)} -------^");
}
catch (PhaseException)
{
throw;
}
catch (Exception ex)
{
_logger.Write(ex);
throw new PhaseException(ex);
}
}
/// <inheritdoc />
public override void OnDetectUpdateComplete(object sender, DetectUpdateCompleteEventArgs e)
{
try
{
_logger.Write($"{nameof(DetectPhase)}: {nameof(OnDetectUpdateComplete)} -------v");
_logger.Write($"{nameof(e.Status)} = {ErrorHelper.HResultToMessage(e.Status)}", true);
base.OnDetectUpdateComplete(sender, e);
_logger.Write($"{nameof(e.IgnoreError)} = {e.IgnoreError}", true);
_logger.Write($"{nameof(e.HResult)} = {ErrorHelper.HResultToMessage(e.HResult)}", true);
_logger.Write($"{nameof(DetectPhase)}: {nameof(OnDetectUpdateComplete)} -------^");
}
catch (PhaseException)
{
throw;
}
catch (Exception ex)
{
_logger.Write(ex);
throw new PhaseException(ex);
}
}
/// <inheritdoc />
public override void OnDetectForwardCompatibleBundle(object sender, DetectForwardCompatibleBundleEventArgs e)
{
try
{
_logger.Write($"{nameof(DetectPhase)}: {nameof(OnDetectForwardCompatibleBundle)} -------v");
_logger.Write($"{nameof(e.BundleId)} = {e.BundleId}", true);
_logger.Write($"{nameof(e.Version)} = {e.Version}", true);
_logger.Write($"{nameof(e.BundleTag)} = {e.BundleTag}", true);
_logger.Write($"{nameof(e.PerMachine)} = {e.PerMachine}", true);
_logger.Write($"{nameof(e.RelationType)} = {e.RelationType}", true);
base.OnDetectForwardCompatibleBundle(sender, e);
_logger.Write($"{nameof(e.MissingFromCache)} = {e.MissingFromCache}", true);
_logger.Write($"{nameof(e.HResult)} = {ErrorHelper.HResultToMessage(e.HResult)}", true);
_logger.Write($"{nameof(DetectPhase)}: {nameof(OnDetectForwardCompatibleBundle)} -------^");
}
catch (PhaseException)
{
throw;
}
catch (Exception ex)
{
_logger.Write(ex);
throw new PhaseException(ex);
}
}
/// <inheritdoc />
public override void OnDetectPackageBegin(object sender, DetectPackageBeginEventArgs e)
{
try
{
_logger.Write($"{nameof(DetectPhase)}: {nameof(OnDetectPackageBegin)} -------v");
_logger.Write($"{nameof(e.PackageId)} = {e.PackageId}", true);
base.OnDetectPackageBegin(sender, e);
_logger.Write($"{nameof(e.HResult)} = {ErrorHelper.HResultToMessage(e.HResult)}", true);
_logger.Write($"{nameof(DetectPhase)}: {nameof(OnDetectPackageBegin)} -------^");
}
catch (PhaseException)
{
throw;
}
catch (Exception ex)
{
_logger.Write(ex);
throw new PhaseException(ex);
}
}
/// <inheritdoc />
public override void OnDetectPackageComplete(object sender, DetectPackageCompleteEventArgs e)
{
try
{
_logger.Write($"{nameof(DetectPhase)}: {nameof(OnDetectPackageComplete)} -------v");
_logger.Write($"{nameof(e.Status)} = {ErrorHelper.HResultToMessage(e.Status)}", true);
_logger.Write($"{nameof(e.PackageId)} = {e.PackageId}", true);
_logger.Write($"{nameof(e.State)} = {e.State}", true);
_logger.Write($"{nameof(e.Cached)} = {e.Cached}", true);
base.OnDetectPackageComplete(sender, e);
_logger.Write($"{nameof(e.HResult)} = {ErrorHelper.HResultToMessage(e.HResult)}", true);
_logger.Write($"{nameof(DetectPhase)}: {nameof(OnDetectPackageComplete)} -------^");
}
catch (PhaseException)
{
throw;
}
catch (Exception ex)
{
_logger.Write(ex);
throw new PhaseException(ex);
}
}
/// <inheritdoc />
public override void OnDetectPatchTarget(object sender, DetectPatchTargetEventArgs e)
{
try
{
_logger.Write($"{nameof(DetectPhase)}: {nameof(OnDetectPatchTarget)} -------v");
_logger.Write($"{nameof(e.PackageId)} = {e.PackageId}", true);
_logger.Write($"{nameof(e.ProductCode)} = {e.ProductCode}", true);
_logger.Write($"{nameof(e.State)} = {e.State}", true);
base.OnDetectPatchTarget(sender, e);
_logger.Write($"{nameof(e.HResult)} = {ErrorHelper.HResultToMessage(e.HResult)}", true);
_logger.Write($"{nameof(DetectPhase)}: {nameof(OnDetectPatchTarget)} -------^");
}
catch (PhaseException)
{
throw;
}
catch (Exception ex)
{
_logger.Write(ex);
throw new PhaseException(ex);
}
}
/// <inheritdoc />
public override void OnDetectCompatibleMsiPackage(object sender, DetectCompatibleMsiPackageEventArgs e)
{
try
{
_logger.Write($"{nameof(DetectPhase)}: {nameof(OnDetectCompatibleMsiPackage)} -------v");
_logger.Write($"{nameof(e.PackageId)} = {e.PackageId}", true);
_logger.Write($"{nameof(e.CompatiblePackageId)} = {e.CompatiblePackageId}", true);
_logger.Write($"{nameof(e.CompatiblePackageVersion)} = {e.CompatiblePackageVersion}", true);
base.OnDetectCompatibleMsiPackage(sender, e);
_logger.Write($"{nameof(e.HResult)} = {ErrorHelper.HResultToMessage(e.HResult)}", true);
_logger.Write($"{nameof(DetectPhase)}: {nameof(OnDetectCompatibleMsiPackage)} -------^");
}
catch (PhaseException)
{
throw;
}
catch (Exception ex)
{
_logger.Write(ex);
throw new PhaseException(ex);
}
}
/// <inheritdoc />
public override void OnDetectMsiFeature(object sender, DetectMsiFeatureEventArgs e)
{
try
{
_logger.Write($"{nameof(DetectPhase)}: {nameof(OnDetectMsiFeature)} -------v");
_logger.Write($"{nameof(e.PackageId)} = {e.PackageId}", true);
_logger.Write($"{nameof(e.FeatureId)} = {e.FeatureId}", true);
_logger.Write($"{nameof(e.State)} = {e.State}", true);
base.OnDetectMsiFeature(sender, e);
_logger.Write($"{nameof(e.HResult)} = {ErrorHelper.HResultToMessage(e.HResult)}", true);
_logger.Write($"{nameof(DetectPhase)}: {nameof(OnDetectMsiFeature)} -------^");
}
catch (PhaseException)
{
throw;
}
catch (Exception ex)
{
_logger.Write(ex);
throw new PhaseException(ex);
}
}
}

View File

@@ -0,0 +1,451 @@
using Bootstrapper.Models;
using Bootstrapper.Models.Util;
using System;
using WixToolset.BootstrapperApplicationApi;
namespace Bootstrapper.Phases;
internal class LoggingPlanPhase : PlanPhase
{
private readonly Log _logger;
public LoggingPlanPhase(Model model)
: base(model)
{
_logger = model.Log;
}
/// <inheritdoc />
public override void OnPlanBegin(object sender, PlanBeginEventArgs e)
{
try
{
_logger.Write($"{nameof(PlanPhase)}: {nameof(OnPlanBegin)} -------v");
_logger.Write($"{nameof(e.PackageCount)} = {e.PackageCount}", true);
base.OnPlanBegin(sender, e);
_logger.Write($"{nameof(e.HResult)} = {ErrorHelper.HResultToMessage(e.HResult)}", true);
_logger.Write($"{nameof(PlanPhase)}: {nameof(OnPlanBegin)} -------^");
}
catch (PhaseException)
{
throw;
}
catch (Exception ex)
{
_logger.Write(ex);
throw new PhaseException(ex);
}
}
/// <inheritdoc />
public override void OnPlanComplete(object sender, PlanCompleteEventArgs e)
{
try
{
_logger.Write($"{nameof(PlanPhase)}: {nameof(OnPlanComplete)} -------v");
_logger.Write($"{nameof(e.Status)} = {ErrorHelper.HResultToMessage(e.Status)}", true);
base.OnPlanComplete(sender, e);
_logger.Write($"{nameof(e.HResult)} = {ErrorHelper.HResultToMessage(e.HResult)}", true);
_logger.Write($"{nameof(PlanPhase)}: {nameof(OnPlanComplete)} -------^");
}
catch (PhaseException)
{
throw;
}
catch (Exception ex)
{
_logger.Write(ex);
throw new PhaseException(ex);
}
}
/// <inheritdoc />
public override void OnPlanPackageBegin(object sender, PlanPackageBeginEventArgs e)
{
try
{
_logger.Write($"{nameof(PlanPhase)}: {nameof(OnPlanPackageBegin)} -------v");
_logger.Write($"{nameof(e.PackageId)} = {e.PackageId}", true);
_logger.Write($"{nameof(e.CurrentState)} = {e.CurrentState}", true);
_logger.Write($"{nameof(e.RecommendedState)} = {e.RecommendedState}", true);
_logger.Write($"{nameof(e.RepairCondition)} = {e.RepairCondition}", true);
_logger.Write($"{nameof(e.Cached)} = {e.Cached}", true);
_logger.Write($"{nameof(e.RecommendedCacheType)} = {e.RecommendedCacheType}", true);
_logger.Write($"{nameof(e.InstallCondition)} = {e.InstallCondition}", true);
base.OnPlanPackageBegin(sender, e);
_logger.Write($"{nameof(e.State)} = {e.State}", true);
_logger.Write($"{nameof(e.CacheType)} = {e.CacheType}", true);
_logger.Write($"{nameof(e.HResult)} = {ErrorHelper.HResultToMessage(e.HResult)}", true);
_logger.Write($"{nameof(PlanPhase)}: {nameof(OnPlanPackageBegin)} -------^");
}
catch (PhaseException)
{
throw;
}
catch (Exception ex)
{
_logger.Write(ex);
throw new PhaseException(ex);
}
}
/// <inheritdoc />
public override void OnPlanPackageComplete(object sender, PlanPackageCompleteEventArgs e)
{
try
{
_logger.Write($"{nameof(PlanPhase)}: {nameof(OnPlanPackageComplete)} -------v");
_logger.Write($"{nameof(e.Status)} = {ErrorHelper.HResultToMessage(e.Status)}", true);
_logger.Write($"{nameof(e.PackageId)} = {e.PackageId}", true);
_logger.Write($"{nameof(e.Requested)} = {e.Requested}", true);
base.OnPlanPackageComplete(sender, e);
_logger.Write($"{nameof(e.HResult)} = {ErrorHelper.HResultToMessage(e.HResult)}", true);
_logger.Write($"{nameof(PlanPhase)}: {nameof(OnPlanPackageComplete)} -------^");
}
catch (PhaseException)
{
throw;
}
catch (Exception ex)
{
_logger.Write(ex);
throw new PhaseException(ex);
}
}
/// <inheritdoc />
public override void OnPlanCompatibleMsiPackageBegin(object sender, PlanCompatibleMsiPackageBeginEventArgs e)
{
try
{
_logger.Write($"{nameof(PlanPhase)}: {nameof(OnPlanCompatibleMsiPackageBegin)} -------v");
_logger.Write($"{nameof(e.PackageId)} = {e.PackageId}", true);
_logger.Write($"{nameof(e.CompatiblePackageId)} = {e.CompatiblePackageId}", true);
_logger.Write($"{nameof(e.CompatiblePackageVersion)} = {e.CompatiblePackageVersion}", true);
_logger.Write($"{nameof(e.RecommendedRemove)} = {e.RecommendedRemove}", true);
base.OnPlanCompatibleMsiPackageBegin(sender, e);
_logger.Write($"{nameof(e.RequestRemove)} = {e.RequestRemove}", true);
_logger.Write($"{nameof(e.HResult)} = {ErrorHelper.HResultToMessage(e.HResult)}", true);
_logger.Write($"{nameof(PlanPhase)}: {nameof(OnPlanCompatibleMsiPackageBegin)} -------^");
}
catch (PhaseException)
{
throw;
}
catch (Exception ex)
{
_logger.Write(ex);
throw new PhaseException(ex);
}
}
/// <inheritdoc />
public override void OnPlanCompatibleMsiPackageComplete(object sender, PlanCompatibleMsiPackageCompleteEventArgs e)
{
try
{
_logger.Write($"{nameof(PlanPhase)}: {nameof(OnPlanCompatibleMsiPackageComplete)} -------v");
_logger.Write($"{nameof(e.Status)} = {ErrorHelper.HResultToMessage(e.Status)}", true);
_logger.Write($"{nameof(e.PackageId)} = {e.PackageId}", true);
_logger.Write($"{nameof(e.CompatiblePackageId)} = {e.CompatiblePackageId}", true);
_logger.Write($"{nameof(e.RequestedRemove)} = {e.RequestedRemove}", true);
base.OnPlanCompatibleMsiPackageComplete(sender, e);
_logger.Write($"{nameof(e.HResult)} = {ErrorHelper.HResultToMessage(e.HResult)}", true);
_logger.Write($"{nameof(PlanPhase)}: {nameof(OnPlanCompatibleMsiPackageComplete)} -------^");
}
catch (PhaseException)
{
throw;
}
catch (Exception ex)
{
_logger.Write(ex);
throw new PhaseException(ex);
}
}
/// <inheritdoc />
public override void OnPlanRollbackBoundary(object sender, PlanRollbackBoundaryEventArgs e)
{
try
{
_logger.Write($"{nameof(PlanPhase)}: {nameof(OnPlanRollbackBoundary)} -------v");
_logger.Write($"{nameof(e.RollbackBoundaryId)} = {e.RollbackBoundaryId}", true);
_logger.Write($"{nameof(e.RecommendedTransaction)} = {e.RecommendedTransaction}", true);
base.OnPlanRollbackBoundary(sender, e);
_logger.Write($"{nameof(e.Transaction)} = {e.Transaction}", true);
_logger.Write($"{nameof(e.HResult)} = {ErrorHelper.HResultToMessage(e.HResult)}", true);
_logger.Write($"{nameof(PlanPhase)}: {nameof(OnPlanRollbackBoundary)} -------^");
}
catch (PhaseException)
{
throw;
}
catch (Exception ex)
{
_logger.Write(ex);
throw new PhaseException(ex);
}
}
/// <inheritdoc />
public override void OnPlanRelatedBundle(object sender, PlanRelatedBundleEventArgs e)
{
try
{
_logger.Write($"{nameof(PlanPhase)}: {nameof(OnPlanRelatedBundle)} -------v");
_logger.Write($"{nameof(e.BundleId)} = {e.BundleId}", true);
_logger.Write($"{nameof(e.RecommendedState)} = {e.RecommendedState}", true);
base.OnPlanRelatedBundle(sender, e);
_logger.Write($"{nameof(e.State)} = {e.State}", true);
_logger.Write($"{nameof(e.HResult)} = {ErrorHelper.HResultToMessage(e.HResult)}", true);
_logger.Write($"{nameof(PlanPhase)}: {nameof(OnPlanRelatedBundle)} -------^");
}
catch (PhaseException)
{
throw;
}
catch (Exception ex)
{
_logger.Write(ex);
throw new PhaseException(ex);
}
}
/// <inheritdoc />
public override void OnPlanRelatedBundleType(object sender, PlanRelatedBundleTypeEventArgs e)
{
try
{
_logger.Write($"{nameof(PlanPhase)}: {nameof(OnPlanRelatedBundleType)} -------v");
_logger.Write($"{nameof(e.BundleId)} = {e.BundleId}", true);
_logger.Write($"{nameof(e.RecommendedType)} = {e.RecommendedType}", true);
base.OnPlanRelatedBundleType(sender, e);
_logger.Write($"{nameof(e.Type)} = {e.Type}", true);
_logger.Write($"{nameof(e.HResult)} = {ErrorHelper.HResultToMessage(e.HResult)}", true);
_logger.Write($"{nameof(PlanPhase)}: {nameof(OnPlanRelatedBundleType)} -------^");
}
catch (PhaseException)
{
throw;
}
catch (Exception ex)
{
_logger.Write(ex);
throw new PhaseException(ex);
}
}
/// <inheritdoc />
public override void OnPlanRestoreRelatedBundle(object sender, PlanRestoreRelatedBundleEventArgs e)
{
try
{
_logger.Write($"{nameof(PlanPhase)}: {nameof(OnPlanRestoreRelatedBundle)} -------v");
_logger.Write($"{nameof(e.BundleId)} = {e.BundleId}", true);
_logger.Write($"{nameof(e.RecommendedState)} = {e.RecommendedState}", true);
base.OnPlanRestoreRelatedBundle(sender, e);
_logger.Write($"{nameof(e.State)} = {e.State}", true);
_logger.Write($"{nameof(e.HResult)} = {ErrorHelper.HResultToMessage(e.HResult)}", true);
_logger.Write($"{nameof(PlanPhase)}: {nameof(OnPlanRestoreRelatedBundle)} -------^");
}
catch (PhaseException)
{
throw;
}
catch (Exception ex)
{
_logger.Write(ex);
throw new PhaseException(ex);
}
}
/// <inheritdoc />
public override void OnPlanForwardCompatibleBundle(object sender, PlanForwardCompatibleBundleEventArgs e)
{
try
{
_logger.Write($"{nameof(PlanPhase)}: {nameof(OnPlanForwardCompatibleBundle)} -------v");
_logger.Write($"{nameof(e.BundleId)} = {e.BundleId}", true);
_logger.Write($"{nameof(e.Version)} = {e.Version}", true);
_logger.Write($"{nameof(e.PerMachine)} = {e.PerMachine}", true);
_logger.Write($"{nameof(e.RelationType)} = {e.RelationType}", true);
_logger.Write($"{nameof(e.BundleTag)} = {e.BundleTag}", true);
_logger.Write($"{nameof(e.RecommendedIgnoreBundle)} = {e.RecommendedIgnoreBundle}", true);
base.OnPlanForwardCompatibleBundle(sender, e);
_logger.Write($"{nameof(e.IgnoreBundle)} = {e.IgnoreBundle}", true);
_logger.Write($"{nameof(e.HResult)} = {ErrorHelper.HResultToMessage(e.HResult)}", true);
_logger.Write($"{nameof(PlanPhase)}: {nameof(OnPlanForwardCompatibleBundle)} -------^");
}
catch (PhaseException)
{
throw;
}
catch (Exception ex)
{
_logger.Write(ex);
throw new PhaseException(ex);
}
}
/// <inheritdoc />
public override void OnPlanMsiPackage(object sender, PlanMsiPackageEventArgs e)
{
try
{
_logger.Write($"{nameof(PlanPhase)}: {nameof(OnPlanMsiPackage)} -------v");
_logger.Write($"{nameof(e.Action)} = {e.Action}", true);
_logger.Write($"{nameof(e.PackageId)} = {e.PackageId}", true);
_logger.Write($"{nameof(e.RecommendedFileVersioning)} = {e.RecommendedFileVersioning}", true);
_logger.Write($"{nameof(e.ShouldExecute)} = {e.ShouldExecute}", true);
base.OnPlanMsiPackage(sender, e);
_logger.Write($"{nameof(e.ActionMsiProperty)} = {e.ActionMsiProperty}", true);
_logger.Write($"{nameof(e.FileVersioning)} = {e.FileVersioning}", true);
_logger.Write($"{nameof(e.DisableExternalUiHandler)} = {e.DisableExternalUiHandler}", true);
_logger.Write($"{nameof(e.UiLevel)} = {e.UiLevel}", true);
_logger.Write($"{nameof(e.HResult)} = {ErrorHelper.HResultToMessage(e.HResult)}", true);
_logger.Write($"{nameof(PlanPhase)}: {nameof(OnPlanMsiPackage)} -------^");
}
catch (PhaseException)
{
throw;
}
catch (Exception ex)
{
_logger.Write(ex);
throw new PhaseException(ex);
}
}
/// <inheritdoc />
public override void OnPlanMsiFeature(object sender, PlanMsiFeatureEventArgs e)
{
try
{
_logger.Write($"{nameof(PlanPhase)}: {nameof(OnPlanMsiFeature)} -------v");
_logger.Write($"{nameof(e.PackageId)} = {e.PackageId}", true);
_logger.Write($"{nameof(e.FeatureId)} = {e.FeatureId}", true);
_logger.Write($"{nameof(e.RecommendedState)} = {e.RecommendedState}", true);
base.OnPlanMsiFeature(sender, e);
_logger.Write($"{nameof(e.State)} = {e.State}", true);
_logger.Write($"{nameof(e.HResult)} = {ErrorHelper.HResultToMessage(e.HResult)}", true);
_logger.Write($"{nameof(PlanPhase)}: {nameof(OnPlanMsiFeature)} -------^");
}
catch (PhaseException)
{
throw;
}
catch (Exception ex)
{
_logger.Write(ex);
throw new PhaseException(ex);
}
}
/// <inheritdoc />
public override void OnPlanPatchTarget(object sender, PlanPatchTargetEventArgs e)
{
try
{
_logger.Write($"{nameof(PlanPhase)}: {nameof(OnPlanPatchTarget)} -------v");
_logger.Write($"{nameof(e.PackageId)} = {e.PackageId}", true);
_logger.Write($"{nameof(e.ProductCode)} = {e.ProductCode}", true);
_logger.Write($"{nameof(e.RecommendedState)} = {e.RecommendedState}", true);
base.OnPlanPatchTarget(sender, e);
_logger.Write($"{nameof(e.State)} = {e.State}", true);
_logger.Write($"{nameof(e.HResult)} = {ErrorHelper.HResultToMessage(e.HResult)}", true);
_logger.Write($"{nameof(PlanPhase)}: {nameof(OnPlanPatchTarget)} -------^");
}
catch (PhaseException)
{
throw;
}
catch (Exception ex)
{
_logger.Write(ex);
throw new PhaseException(ex);
}
}
/// <inheritdoc />
public override void OnPlannedPackage(object sender, PlannedPackageEventArgs e)
{
try
{
_logger.Write($"{nameof(PlanPhase)}: {nameof(OnPlannedPackage)} -------v");
_logger.Write($"{nameof(e.PackageId)} = {e.PackageId}", true);
_logger.Write($"{nameof(e.Execute)} = {e.Execute}", true);
_logger.Write($"{nameof(e.Rollback)} = {e.Rollback}", true);
_logger.Write($"{nameof(e.Cache)} = {e.Cache}", true);
_logger.Write($"{nameof(e.Uncache)} = {e.Uncache}", true);
base.OnPlannedPackage(sender, e);
_logger.Write($"{nameof(e.HResult)} = {ErrorHelper.HResultToMessage(e.HResult)}", true);
_logger.Write($"{nameof(PlanPhase)}: {nameof(OnPlannedPackage)} -------^");
}
catch (PhaseException)
{
throw;
}
catch (Exception ex)
{
_logger.Write(ex);
throw new PhaseException(ex);
}
}
/// <inheritdoc />
public override void OnPlannedCompatiblePackage(object sender, PlannedCompatiblePackageEventArgs e)
{
try
{
_logger.Write($"{nameof(PlanPhase)}: {nameof(OnPlannedCompatiblePackage)} -------v");
_logger.Write($"{nameof(e.PackageId)} = {e.PackageId}", true);
_logger.Write($"{nameof(e.CompatiblePackageId)} = {e.CompatiblePackageId}", true);
_logger.Write($"{nameof(e.Remove)} = {e.Remove}", true);
base.OnPlannedCompatiblePackage(sender, e);
_logger.Write($"{nameof(e.HResult)} = {ErrorHelper.HResultToMessage(e.HResult)}", true);
_logger.Write($"{nameof(PlanPhase)}: {nameof(OnPlannedCompatiblePackage)} -------^");
}
catch (PhaseException)
{
throw;
}
catch (Exception ex)
{
_logger.Write(ex);
throw new PhaseException(ex);
}
}
}

View File

@@ -0,0 +1,199 @@
using Bootstrapper.Models;
using Bootstrapper.Models.Util;
using System;
using WixToolset.BootstrapperApplicationApi;
namespace Bootstrapper.Phases;
internal class PlanPhase
{
private readonly Model _model;
public PlanPhase(Model model)
{
_model = model;
}
public event EventHandler<EventArgs> PlanPhaseFailed;
/// <summary>
/// Fired when the engine has begun planning the installation.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
/// <exception cref="PhaseException"></exception>
public virtual void OnPlanBegin(object sender, PlanBeginEventArgs e)
{
try
{
_model.State.PhaseResult = 0;
_model.State.ErrorMessage = string.Empty;
if (e.Cancel)
return;
_model.State.BaStatus = BaStatus.Planning;
}
catch (Exception ex)
{
_model.Log.Write(ex);
throw new PhaseException(ex);
}
}
/// <summary>
/// Fired when the engine has completed planning the installation.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
/// <exception cref="PhaseException"></exception>
public virtual void OnPlanComplete(object sender, PlanCompleteEventArgs e)
{
try
{
_model.State.PhaseResult = e.Status;
if (_model.State.BaStatus == BaStatus.Cancelled || e.Status == ErrorHelper.CancelHResult)
{
_model.State.BaStatus = BaStatus.Cancelled;
_model.Log.Write("User cancelled");
}
else if (ErrorHelper.HResultIsFailure(e.Status))
{
_model.State.BaStatus = BaStatus.Failed;
var msg = $"Plan failed - {ErrorHelper.HResultToMessage(e.Status)}";
if (string.IsNullOrEmpty(_model.State.ErrorMessage))
_model.State.ErrorMessage = msg;
_model.Log.Write(msg);
if (_model.UiFacade.IsUiShown)
PlanPhaseFailed?.Invoke(this, EventArgs.Empty);
else
_model.UiFacade.ShutDown();
}
else
{
_model.Log.Write("Plan succeeded, starting apply phase");
_model.Engine.Apply(_model.UiFacade.ShellWindowHandle);
}
}
catch (Exception ex)
{
_model.Log.Write(ex);
throw new PhaseException(ex);
}
}
/// <summary>
/// Fired when the engine has begun getting the BA's input for planning a package.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public virtual void OnPlanPackageBegin(object sender, PlanPackageBeginEventArgs e)
{ }
/// <summary>
/// Fired when the engine has completed getting the BA's input for planning a package.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public virtual void OnPlanPackageComplete(object sender, PlanPackageCompleteEventArgs e)
{ }
/// <summary>
/// Fired when the engine plans a new, compatible package using the same provider key.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public virtual void OnPlanCompatibleMsiPackageBegin(object sender, PlanCompatibleMsiPackageBeginEventArgs e)
{ }
/// <summary>
/// Fired when the engine has completed planning the installation of a specific package.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public virtual void OnPlanCompatibleMsiPackageComplete(object sender, PlanCompatibleMsiPackageCompleteEventArgs e)
{ }
/// <summary>
/// Fired when the engine is planning a rollback boundary.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public virtual void OnPlanRollbackBoundary(object sender, PlanRollbackBoundaryEventArgs e)
{ }
/// <summary>
/// Fired when the engine has begun planning for a related bundle.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public virtual void OnPlanRelatedBundle(object sender, PlanRelatedBundleEventArgs e)
{ }
/// <summary>
/// Fired when the engine has begun planning the related bundle relation type.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public virtual void OnPlanRelatedBundleType(object sender, PlanRelatedBundleTypeEventArgs e)
{ }
/// <summary>
/// Fired when the engine has begun planning an upgrade related bundle for restoring in case of failure.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public virtual void OnPlanRestoreRelatedBundle(object sender, PlanRestoreRelatedBundleEventArgs e)
{ }
/// <summary>
/// Fired when the engine is about to plan a forward compatible bundle.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public virtual void OnPlanForwardCompatibleBundle(object sender, PlanForwardCompatibleBundleEventArgs e)
{ }
/// <summary>
/// Fired when the engine is planning an MSI or MSP package.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public virtual void OnPlanMsiPackage(object sender, PlanMsiPackageEventArgs e)
{ }
/// <summary>
/// Fired when the engine is about to plan a feature in an MSI package.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public virtual void OnPlanMsiFeature(object sender, PlanMsiFeatureEventArgs e)
{ }
/// <summary>
/// Fired when the engine is about to plan a target of an MSP package.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public virtual void OnPlanPatchTarget(object sender, PlanPatchTargetEventArgs e)
{ }
/// <summary>
/// Fired when the engine has completed planning a package.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public virtual void OnPlannedPackage(object sender, PlannedPackageEventArgs e)
{ }
/// <summary>
/// Fired when the engine has completed planning a compatible package.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public virtual void OnPlannedCompatiblePackage(object sender, PlannedCompatiblePackageEventArgs e)
{ }
}

View File

@@ -0,0 +1,194 @@
using Bootstrapper.Models;
using Bootstrapper.Models.State;
using System;
using WixToolset.BootstrapperApplicationApi;
namespace Bootstrapper.Phases;
internal class ProgressHandler
{
private readonly Model _model;
private readonly object _progressLock = new();
private int _progressStages;
private int _cacheProgress;
private int _executeProgress;
public ProgressHandler(Model model)
{
_model = model;
}
public void OnPlanBegin(object sender, PlanBeginEventArgs e)
{
try
{
var action = _model.State.PlannedAction.ToString().ToLower();
ReportProgress($"Planning {action}");
}
catch (Exception ex)
{
_model.Log.Write(ex);
throw;
}
}
public void OnApplyBegin(object sender, ApplyBeginEventArgs e)
{
try
{
lock (_progressLock)
_progressStages = e.PhaseCount;
ReportProgress("Applying changes");
}
catch (Exception ex)
{
_model.Log.Write(ex);
throw;
}
}
public void OnCacheAcquireProgress(object sender, CacheAcquireProgressEventArgs e)
{
try
{
lock (_progressLock)
_cacheProgress = e.OverallPercentage;
ReportProgress("Retrieving", e.PackageOrContainerId);
}
catch (Exception ex)
{
_model.Log.Write(ex);
throw;
}
}
public void OnCachePayloadExtractProgress(object sender, CachePayloadExtractProgressEventArgs e)
{
try
{
lock (_progressLock)
_cacheProgress = e.OverallPercentage;
ReportProgress("Extracting", e.PackageOrContainerId);
}
catch (Exception ex)
{
_model.Log.Write(ex);
throw;
}
}
public void OnCacheVerifyProgress(object sender, CacheVerifyProgressEventArgs e)
{
try
{
lock (_progressLock)
_cacheProgress = e.OverallPercentage;
ReportProgress("Verifying", e.PackageOrContainerId);
}
catch (Exception ex)
{
_model.Log.Write(ex);
throw;
}
}
public void OnCacheContainerOrPayloadVerifyProgress(object sender, CacheContainerOrPayloadVerifyProgressEventArgs e)
{
try
{
lock (_progressLock)
_cacheProgress = e.OverallPercentage;
ReportProgress("Verifying", e.PackageOrContainerId);
}
catch (Exception ex)
{
_model.Log.Write(ex);
}
}
public void OnCacheComplete(object sender, CacheCompleteEventArgs e)
{
try
{
lock (_progressLock)
_cacheProgress = 100;
ReportProgress();
}
catch (Exception ex)
{
_model.Log.Write(ex);
throw;
}
}
public void OnApplyExecuteProgress(object sender, ExecuteProgressEventArgs e)
{
try
{
int overallProgress;
lock (_progressLock)
{
_executeProgress = e.OverallPercentage;
overallProgress = CalculateProgress();
}
ReportProgress(null, e.PackageId);
if (_model.State.Display == Display.Embedded)
_model.Engine.SendEmbeddedProgress(e.ProgressPercentage, overallProgress);
}
catch (Exception ex)
{
_model.Log.Write(ex);
throw;
}
}
public void OnExecutePackageComplete(object sender, ExecutePackageCompleteEventArgs e)
{
try
{
// clear display
ReportProgress(string.Empty, string.Empty);
}
catch (Exception ex)
{
_model.Log.Write(ex);
throw;
}
}
private void ReportProgress(string message = null, string packageId = null)
{
if (_model.UiFacade.ProgressReporter != null)
{
var report = new ProgressReport
{
Message = message,
Progress = CalculateProgress()
};
if (packageId != null)
report.PackageName = _model.State.GetPackageName(packageId);
_model.UiFacade.ProgressReporter.Report(report);
}
}
private int CalculateProgress()
{
lock (_progressLock)
{
if (_progressStages > 0)
return (_cacheProgress + _executeProgress) / _progressStages;
return 0;
}
}
}

View File

@@ -0,0 +1,25 @@
using Bootstrapper.Models.Util;
using System;
using WixToolset.BootstrapperApplicationApi;
namespace Bootstrapper;
internal class Program
{
private static int Main()
{
int exitCode;
try
{
var application = new BootstrapperApp();
ManagedBootstrapperApplication.Run(application);
exitCode = application.ExitCode;
}
catch (Exception ex)
{
exitCode = ErrorHelper.HResultToWin32(ex.HResult);
}
return exitCode;
}
}

View File

@@ -0,0 +1,29 @@
using Bootstrapper.Models;
using Bootstrapper.Models.Util;
using Bootstrapper.ViewModels.Util;
namespace Bootstrapper.ViewModels
{
internal class CancelViewModel : ViewModelBase
{
private readonly Model _model;
public CancelViewModel(Model model)
{
_model = model;
CancelCommand = new DelegateCommand(Cancel, CanCancel);
}
public IDelegateCommand CancelCommand { get; }
private void Cancel()
{
_model.State.CancelRequested = true;
}
private bool CanCancel()
{
return !_model.State.CancelRequested && (_model.State.BaStatus == BaStatus.Planning || _model.State.BaStatus == BaStatus.Applying);
}
}
}

View File

@@ -0,0 +1,41 @@
using Bootstrapper.Models;
using Bootstrapper.Models.Util;
using Bootstrapper.ViewModels.Util;
namespace Bootstrapper.ViewModels
{
internal class ConfigViewModel : ViewModelBase
{
private readonly Model _model;
public ConfigViewModel(Model model)
{
_model = model;
}
/// <summary>
/// An example exposing a bundle variable to the UI.
/// </summary>
public string SampleOption
{
get
{
if (_model.Engine.ContainsVariable("SampleOption"))
return _model.Engine.GetVariableString("SampleOption");
return string.Empty;
}
set
{
_model.Engine.SetVariableString("SampleOption", value, false);
OnPropertyChanged();
}
}
public void AfterDetect()
{
if (_model.State.RelatedBundleStatus != BundleStatus.NotInstalled)
SampleOption = "Installed";
}
}
}

View File

@@ -0,0 +1,74 @@
using Bootstrapper.Models.State;
using Bootstrapper.ViewModels.Util;
using System;
namespace Bootstrapper.ViewModels
{
internal class ProgressViewModel : ViewModelBase
{
private string _message;
private string _package;
private int _progress;
public string Message
{
get => _message;
set
{
if (_message == value)
return;
_message = value;
base.OnPropertyChanged();
}
}
public string Package
{
get => _package;
set
{
if (_package == value)
return;
_package = value;
base.OnPropertyChanged();
if (string.IsNullOrWhiteSpace(_package))
Message = string.Empty;
else
Message = $"Processing: {_package}";
}
}
public int Progress
{
get => _progress;
set
{
if (Math.Abs(_progress - value) < 0.0001)
return;
_progress = value;
base.OnPropertyChanged();
}
}
public void ProcessProgressReport(ProgressReport report)
{
Progress = report.Progress;
if (report.Message != null)
Message = report.Message;
if (report.PackageName != null)
Package = report.PackageName;
}
public void Reset()
{
Message = string.Empty;
Package = string.Empty;
Progress = 0;
}
}
}

View File

@@ -0,0 +1,375 @@
using Bootstrapper.Models;
using Bootstrapper.Models.Util;
using Bootstrapper.ViewModels.Util;
using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Input;
using WixToolset.BootstrapperApplicationApi;
namespace Bootstrapper.ViewModels;
internal class ShellViewModel : ViewModelBase
{
private readonly Model _model;
private readonly CancelViewModel _cancelVm;
private readonly IDelegateCommand _installCommand;
private readonly IDelegateCommand _updateCommand;
private readonly IDelegateCommand _uninstallCommand;
private bool _isRepairAvailable;
private IDelegateCommand _executeCommand;
private string _executeDescription;
private string _message;
public ShellViewModel(Model model)
{
_model = model;
_cancelVm = new CancelViewModel(model);
_installCommand = new DelegateCommand(Install, CanInstall);
_uninstallCommand = new DelegateCommand(Uninstall, CanUninstall);
_updateCommand = new DelegateCommand(Update, CanUpdate);
RepairCommand = new DelegateCommand(Repair, CanRepair);
ExitCommand = new DelegateCommand(Exit, CanExit);
ShowLogCommand = new DelegateCommand(ShowLog, CanShowLog);
ConfigVm = new ConfigViewModel(model);
ConfigVm.PropertyChanged += ConfigVm_PropertyChanged;
ProgressVm = new ProgressViewModel();
}
public ConfigViewModel ConfigVm { get; }
public ProgressViewModel ProgressVm { get; }
public IDelegateCommand ShowLogCommand { get; }
public IDelegateCommand ExitCommand { get; }
public IDelegateCommand RepairCommand { get; }
public IDelegateCommand CancelCommand => _cancelVm.CancelCommand;
/// <summary>
/// Is installer waiting for user input?
/// </summary>
public bool IsWaiting => _model.State.BaStatus == BaStatus.Waiting;
/// <summary>
/// Is the UI running in passive mode, only displaying a progress bar?
/// </summary>
public bool IsPassive => _model.State.Display == Display.Passive;
/// <summary>
/// The command that will install or uninstall the software
/// </summary>
public IDelegateCommand ExecuteCommand
{
get => _executeCommand;
set
{
if (_executeCommand == value)
return;
_executeCommand = value;
OnPropertyChanged();
}
}
/// <summary>
/// A brief, one-word description of what will happen when the <see cref="ExecuteCommand" /> is run.
/// Should be appropriate for button text.
/// </summary>
public string ExecuteDescription
{
get => _executeDescription;
set
{
if (_executeDescription == value)
return;
_executeDescription = value;
OnPropertyChanged();
}
}
/// <summary>
/// Display the Repair button?
/// </summary>
public bool IsRepairAvailable
{
get => _isRepairAvailable;
set
{
if (_isRepairAvailable == value)
return;
_isRepairAvailable = value;
OnPropertyChanged();
}
}
/// <summary>
/// A message to display to the user.
/// </summary>
public string Message
{
get => _message;
set
{
if (_message == value)
return;
_message = value;
OnPropertyChanged();
}
}
/// <summary>
/// Call after the detect phase completes to refresh the UI.
/// </summary>
/// <param name="followupAction">
/// Indicates which action will be planned when the BA is running silently or in passive mode.
/// Pass <see cref="LaunchAction.Unknown" /> for full UI mode.
/// </param>
public void AfterDetect(LaunchAction followupAction)
{
try
{
OnPropertyChanged(nameof(IsWaiting));
if (_model.State.RelatedBundleStatus == BundleStatus.OlderInstalled || followupAction == LaunchAction.UpdateReplace || followupAction == LaunchAction.UpdateReplaceEmbedded)
{
ExecuteCommand = _updateCommand;
ExecuteDescription = "Update";
}
else if (_model.State.RelatedBundleStatus == BundleStatus.Current || followupAction == LaunchAction.Uninstall || followupAction == LaunchAction.UnsafeUninstall)
{
ExecuteCommand = _uninstallCommand;
ExecuteDescription = "Uninstall";
}
else
{
ExecuteCommand = _installCommand;
ExecuteDescription = "Install";
}
IsRepairAvailable = _model.State.RelatedBundleStatus == BundleStatus.Current;
AssignMessage();
ConfigVm.AfterDetect();
}
catch (Exception ex)
{
_model.Log.Write(ex);
Message = $"Error: {ex.Message}";
_model.UiFacade.ShowMessageBox($"Error: {ex.Message}", MessageBoxButton.OK, MessageBoxImage.Error, MessageBoxResult.OK);
}
finally
{
CommandManager.InvalidateRequerySuggested();
}
}
/// <summary>
/// Call after the apply phase completes to refresh the UI.
/// </summary>
public void AfterApply()
{
try
{
ProgressVm.Reset();
AssignMessage();
}
catch (Exception ex)
{
_model.Log.Write(ex);
Message = $"Error: {ex.Message}";
_model.UiFacade.ShowMessageBox($"Error: {ex.Message}", MessageBoxButton.OK, MessageBoxImage.Error, MessageBoxResult.OK);
}
finally
{
CommandManager.InvalidateRequerySuggested();
}
}
private void Install()
{
_model.PlanAndApply(LaunchAction.Install);
OnPropertyChanged(nameof(IsWaiting));
CommandManager.InvalidateRequerySuggested();
}
private bool CanInstall()
{
return _model.State.RelatedBundleStatus == BundleStatus.NotInstalled && CanPlanAndApply();
}
private void Update()
{
// Any older bundles that were discovered have already been scheduled for uninstall, so an "upgrade" will be a fresh installation.
_model.PlanAndApply(LaunchAction.Install);
OnPropertyChanged(nameof(IsWaiting));
CommandManager.InvalidateRequerySuggested();
}
private bool CanUpdate()
{
return _model.State.RelatedBundleStatus == BundleStatus.OlderInstalled && CanPlanAndApply();
}
private void Uninstall()
{
_model.PlanAndApply(LaunchAction.Uninstall);
OnPropertyChanged(nameof(IsWaiting));
CommandManager.InvalidateRequerySuggested();
}
private bool CanUninstall()
{
return _model.State.RelatedBundleStatus == BundleStatus.Current && CanPlanAndApply();
}
private void Repair()
{
_model.PlanAndApply(LaunchAction.Repair);
OnPropertyChanged(nameof(IsWaiting));
CommandManager.InvalidateRequerySuggested();
}
private bool CanRepair()
{
return _model.State.RelatedBundleStatus == BundleStatus.Current && CanPlanAndApply();
}
private void Exit()
{
_model.UiFacade.ShutDown();
}
private bool CanExit()
{
return _model.State.BaStatus == BaStatus.Failed || _model.State.BaStatus == BaStatus.Cancelled || _model.State.BaStatus == BaStatus.Applied || _model.State.BaStatus == BaStatus.Waiting;
;
}
private void ShowLog()
{
_model.ShowLog();
}
private bool CanShowLog()
{
return _model.State.BaStatus == BaStatus.Failed || _model.State.BaStatus == BaStatus.Cancelled || _model.State.BaStatus == BaStatus.Applied || _model.State.BaStatus == BaStatus.Waiting;
;
}
private void ConfigVm_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
RepairCommand.RaiseCanExecuteChanged();
ExecuteCommand?.RaiseCanExecuteChanged();
}
private bool CanPlanAndApply()
{
// Ensure ConfigVm is not displaying any data validation errors.
return _model.State.BaStatus == BaStatus.Waiting && string.IsNullOrEmpty(ConfigVm.Error);
}
/// <summary>
/// Will assign a value to <see cref="Message" /> based on the current state.
/// This should be called after Detect, and again after Apply.
/// </summary>
/// <exception cref="ArgumentOutOfRangeException"></exception>
private void AssignMessage()
{
switch (_model.State.BaStatus)
{
case BaStatus.Cancelled:
Message = "User cancelled";
break;
case BaStatus.Failed:
if (!string.IsNullOrWhiteSpace(_model.State.ErrorMessage))
Message = $"Failed: {_model.State.ErrorMessage}";
else if (_model.State.CancelRequested)
Message = "User cancelled";
else
Message = "An error occurred. See log for details.";
break;
case BaStatus.Planning:
case BaStatus.Applying:
case BaStatus.Waiting:
// BA will be in one of these states after successfully completing the detect phase.
if (string.IsNullOrEmpty(_model.State.RelatedBundleVersion))
Message = $"Installing v{_model.State.BundleVersion}";
else
{
switch (_model.State.RelatedBundleStatus)
{
case BundleStatus.Unknown:
case BundleStatus.NotInstalled:
Message = $"Installing v{_model.State.BundleVersion}";
break;
case BundleStatus.OlderInstalled:
Message = $"Updating v{_model.State.RelatedBundleVersion} to {_model.State.BundleVersion}";
break;
case BundleStatus.Current:
Message = $"v{_model.State.BundleVersion} is currently installed";
break;
case BundleStatus.NewerInstalled:
Message = $"There is already a newer version (v{_model.State.RelatedBundleVersion}) installed on this machine.";
break;
default:
throw new ArgumentOutOfRangeException(nameof(_model.State.RelatedBundleStatus));
}
}
break;
case BaStatus.Applied:
switch (_model.State.PlannedAction)
{
case LaunchAction.Layout:
Message = $"v{_model.State.BundleVersion} successfully laid out";
break;
case LaunchAction.UnsafeUninstall:
case LaunchAction.Uninstall:
Message = $"v{_model.State.BundleVersion} successfully removed";
break;
case LaunchAction.Modify:
Message = $"v{_model.State.BundleVersion} successfully modified";
break;
case LaunchAction.Repair:
Message = $"v{_model.State.BundleVersion} successfully repaired";
break;
case LaunchAction.UpdateReplace:
case LaunchAction.UpdateReplaceEmbedded:
Message = $"v{_model.State.RelatedBundleVersion} successfully updated to {_model.State.BundleVersion}";
break;
case LaunchAction.Unknown:
case LaunchAction.Help:
case LaunchAction.Cache:
case LaunchAction.Install:
default:
Message = $"v{_model.State.BundleVersion} successfully installed";
break;
}
break;
case BaStatus.Initializing:
case BaStatus.Detecting:
// No reason to display a message
break;
default:
throw new ArgumentOutOfRangeException(nameof(_model.State.BaStatus));
}
}
}

View File

@@ -0,0 +1,69 @@
using System;
using System.Globalization;
using System.Windows;
using System.Windows.Data;
using System.Windows.Markup;
namespace Bootstrapper.ViewModels.Util
{
/// <summary>
/// Converts a <see cref="bool" /> to a <see cref="Visibility" />. If the <see cref="Negate" /> property
/// is <see langword="false" />, then <see langword="true" /> converts to <see cref="Visibility.Visible" />
/// while <see langword="false" /> converts to <see cref="Visibility.Collapsed" />. If <see cref="Negate" />
/// is <see langword="true" />, then the negated bound value is used for the conversion.
/// </summary>
[ValueConversion(typeof(bool), typeof(Visibility))]
public class BooleanVisibilityConverter : MarkupExtension, IValueConverter
{
/// <summary>
/// If <see langword="true" />, will use the negated value of the bound property to perform the conversion. So,
/// <see langword="true" /> will convert to <see cref="Visibility.Collapsed" /> while <see langword="false" />
/// will convert to <see cref="Visibility.Visible" />.
/// </summary>
public bool Negate { get; set; }
/// <inheritdoc />
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (targetType != typeof(Visibility) && targetType != typeof(Visibility?))
return Visibility.Collapsed;
var b = value as bool?;
if (b == null)
return Visibility.Collapsed;
if (Negate)
{
if (b.Value)
return Visibility.Collapsed;
return Visibility.Visible;
}
if (b.Value)
return Visibility.Visible;
return Visibility.Collapsed;
}
/// <inheritdoc />
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
if ((targetType == typeof(bool) || targetType == typeof(bool?)) && value is Visibility vis)
{
if (Negate)
return vis != Visibility.Visible;
return vis == Visibility.Visible;
}
return false;
}
/// <inheritdoc />
public override object ProvideValue(IServiceProvider serviceProvider)
{
return this;
}
}
}

View File

@@ -0,0 +1,101 @@
using System;
using System.Collections.Generic;
using System.Windows.Input;
namespace Bootstrapper.ViewModels.Util
{
/// <summary>
/// This class contains methods for the CommandManager that help avoid memory leaks by
/// using weak references.
/// </summary>
internal static class CommandManagerHelper
{
internal static void CallWeakReferenceHandlers(List<WeakReference> handlers)
{
if (handlers == null)
return;
// Take a snapshot of the handlers before we call out to them since the handlers
// could cause the array to me modified while we are reading it.
var callees = new EventHandler[handlers.Count];
var count = 0;
for (var i = handlers.Count - 1; i >= 0; i--)
{
var reference = handlers[i];
if (!(reference.Target is EventHandler handler))
{
// Clean up old handlers that have been collected
handlers.RemoveAt(i);
}
else
{
callees[count] = handler;
count++;
}
}
// Call the handlers that we snapshot
for (var i = 0; i < count; i++)
{
var handler = callees[i];
handler(null, EventArgs.Empty);
}
}
internal static void AddHandlersToRequerySuggested(IEnumerable<WeakReference> handlers)
{
if (handlers == null)
return;
foreach (var handlerRef in handlers)
{
if (handlerRef.Target is EventHandler handler)
CommandManager.RequerySuggested += handler;
}
}
internal static void RemoveHandlersFromRequerySuggested(IEnumerable<WeakReference> handlers)
{
if (handlers == null)
return;
foreach (var handlerRef in handlers)
{
if (handlerRef.Target is EventHandler handler)
CommandManager.RequerySuggested -= handler;
}
}
internal static void AddWeakReferenceHandler(ref List<WeakReference> handlers, EventHandler handler, int defaultListSize)
{
if (handlers == null)
{
if (defaultListSize > 0)
handlers = new List<WeakReference>(defaultListSize);
else
handlers = new List<WeakReference>();
}
handlers.Add(new WeakReference(handler));
}
internal static void RemoveWeakReferenceHandler(List<WeakReference> handlers, EventHandler handler)
{
if (handlers == null)
return;
for (var i = handlers.Count - 1; i >= 0; i--)
{
var reference = handlers[i];
if (!(reference.Target is EventHandler existingHandler) || existingHandler == handler)
{
// Clean up old handlers that have been collected
// in addition to the handler that is to be removed.
handlers.RemoveAt(i);
}
}
}
}
}

View File

@@ -0,0 +1,280 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq.Expressions;
using System.Windows.Input;
namespace Bootstrapper.ViewModels.Util
{
/// <summary>
/// An implementation of <see cref="IDelegateCommand" /> which allows delegating the commanding
/// logic to methods passed as parameters, and enables a View to bind commands to objects that
/// are not part of the element tree.
/// </summary>
public sealed class DelegateCommand : BaseCommand, IDelegateCommand
{
private readonly Action _executeMethod;
private readonly Func<bool> _canExecuteMethod;
/// <summary>
/// Initializes a DelegateCommand with methods for execution, verification, and allows specifying
/// if the CommandManager's automatic re-query is disabled for this command.
/// </summary>
/// <param name="executeMethod">
/// Method which is called when the command is executed.
/// </param>
/// <param name="canExecuteMethod">
/// Method which is called to determine if the Execute method may be run.
/// </param>
/// <param name="isAutomaticRequeryDisabled">
/// If true then the framework will not automatically query <see cref="ICommand.CanExecute" />.
/// Queries can be triggered manually by calling <see cref="BaseCommand.RaiseCanExecuteChanged" />.
/// </param>
public DelegateCommand(Action executeMethod, Func<bool> canExecuteMethod = null, bool isAutomaticRequeryDisabled = false)
: base(isAutomaticRequeryDisabled)
{
_executeMethod = executeMethod ?? throw new ArgumentNullException(nameof(executeMethod));
_canExecuteMethod = canExecuteMethod;
}
/// <summary>
/// Method to determine if the command can be executed.
/// </summary>
[DebuggerStepThrough]
public bool CanExecute()
{
return _canExecuteMethod == null || _canExecuteMethod();
}
/// <summary>
/// Executes the command.
/// </summary>
public void Execute()
{
_executeMethod();
}
[DebuggerStepThrough]
bool ICommand.CanExecute(object obj)
{
return CanExecute();
}
void ICommand.Execute(object obj)
{
Execute();
}
public DelegateCommand ListenOn<TObservedType, TPropertyType>(TObservedType viewModel, Expression<Func<TObservedType, TPropertyType>> propertyExpression) where TObservedType : INotifyPropertyChanged
{
AddListenOn(viewModel, nameof(propertyExpression));
return this;
}
public DelegateCommand ListenOn<TObservedType>(TObservedType viewModel, string propertyName) where TObservedType : INotifyPropertyChanged
{
AddListenOn(viewModel, propertyName);
return this;
}
}
/// <summary>
/// A strongly typed implementation of <see cref="IDelegateCommand{T}" /> which allows delegating the commanding
/// logic to methods passed as parameters, and enables a View to bind commands to objects that
/// are not part of the element tree.
/// </summary>
/// <typeparam name="T">Type of the parameter passed to the delegates</typeparam>
public sealed class DelegateCommand<T> : BaseCommand, IDelegateCommand<T>
{
private readonly Action<T> _executeMethod;
private readonly Func<T, bool> _canExecuteMethod;
/// <summary>
/// Initializes a DelegateCommand with methods for execution, verification, and allows specifying
/// if the CommandManager's automatic re-query is disabled for this command.
/// </summary>
/// <param name="executeMethod">
/// Method which is called when the command is executed.
/// </param>
/// <param name="canExecuteMethod">
/// Method which is called to determine if the Execute method may be run.
/// </param>
/// <param name="isAutomaticRequeryDisabled">
/// If true then the framework will not automatically query <see cref="ICommand.CanExecute" />.
/// Queries can be triggered manually by calling <see cref="BaseCommand.RaiseCanExecuteChanged" />.
/// </param>
/// <typeparamref name="T">
/// The type of the data passed to the <see cref="Execute" /> and <see cref="CanExecute" /> methods.
/// </typeparamref>
public DelegateCommand(Action<T> executeMethod, Func<T, bool> canExecuteMethod = null, bool isAutomaticRequeryDisabled = false)
: base(isAutomaticRequeryDisabled)
{
_executeMethod = executeMethod ?? throw new ArgumentNullException(nameof(executeMethod));
_canExecuteMethod = canExecuteMethod;
}
/// <summary>
/// Method to determine if the command can be executed.
/// </summary>
/// <typeparamref name="T">
/// Type of the data passed.
/// </typeparamref>
[DebuggerStepThrough]
public bool CanExecute(T parameter)
{
return _canExecuteMethod == null || _canExecuteMethod(parameter);
}
/// <summary>
/// Execution of the command.
/// </summary>
/// <typeparamref name="T">
/// Type of the data passed.
/// </typeparamref>
public void Execute(T parameter)
{
_executeMethod(parameter);
}
/// <summary>
/// Defines the method that determines whether the command can execute in its current state.
/// </summary>
/// <returns>
/// true if this command can be executed; otherwise, false.
/// </returns>
/// <param name="parameter">
/// Data used by the command. If the command does not require data to be passed, this object can
/// be set to null.
/// </param>
[DebuggerStepThrough]
bool ICommand.CanExecute(object parameter)
{
// if T is of value type and the parameter is not
// set yet, then return false if CanExecute delegate
// exists, else return true
if (parameter == null && typeof(T).IsValueType)
return _canExecuteMethod == null;
return CanExecute((T)parameter);
}
/// <summary>
/// Defines the method to be called when the command is invoked.
/// </summary>
/// <param name="parameter">
/// Data used by the command. If the command does not require data to be passed, this object can
/// be set to null.
/// </param>
void ICommand.Execute(object parameter)
{
Execute((T)parameter);
}
public DelegateCommand<T> ListenOn<TObservedType, TPropertyType>(TObservedType viewModel, Expression<Func<TObservedType, TPropertyType>> propertyExpression) where TObservedType : INotifyPropertyChanged
{
AddListenOn(viewModel, nameof(propertyExpression));
return this;
}
public DelegateCommand<T> ListenOn<TObservedType>(TObservedType viewModel, string propertyName) where TObservedType : INotifyPropertyChanged
{
AddListenOn(viewModel, propertyName);
return this;
}
}
public abstract class BaseCommand
{
private bool _isAutomaticRequeryDisabled;
private List<WeakReference> _canExecuteChangedHandlers;
/// <summary>
/// Initializes a DelegateCommand with methods for execution, verification, and allows specifying
/// if the CommandManager's automatic re-query is disabled for this command.
/// </summary>
/// <param name="isAutomaticRequeryDisabled">
/// If true then the framework will not automatically query <see cref="ICommand.CanExecute" />.
/// Queries can be triggered manually by calling <see cref="RaiseCanExecuteChanged" />.
/// </param>
protected BaseCommand(bool isAutomaticRequeryDisabled = false)
{
_isAutomaticRequeryDisabled = isAutomaticRequeryDisabled;
}
/// <summary>
/// Occurs when changes occur that affect whether the command should execute.
/// </summary>
public event EventHandler CanExecuteChanged
{
add
{
if (!_isAutomaticRequeryDisabled)
CommandManager.RequerySuggested += value;
CommandManagerHelper.AddWeakReferenceHandler(ref _canExecuteChangedHandlers, value, 2);
}
remove
{
if (!_isAutomaticRequeryDisabled)
CommandManager.RequerySuggested -= value;
CommandManagerHelper.RemoveWeakReferenceHandler(_canExecuteChangedHandlers, value);
}
}
/// <summary>
/// If true then the framework will not automatically query <see cref="ICommand.CanExecute" />.
/// Queries can be triggered manually by calling <see cref="RaiseCanExecuteChanged" />.
/// </summary>
public bool IsAutomaticRequeryDisabled
{
get => _isAutomaticRequeryDisabled;
set
{
if (_isAutomaticRequeryDisabled == value)
return;
if (value)
CommandManagerHelper.RemoveHandlersFromRequerySuggested(_canExecuteChangedHandlers);
else
CommandManagerHelper.AddHandlersToRequerySuggested(_canExecuteChangedHandlers);
_isAutomaticRequeryDisabled = value;
}
}
/// <summary>
/// Raises the <see cref="ICommand.CanExecuteChanged" /> event.
/// </summary>
public void RaiseCanExecuteChanged()
{
CommandManagerHelper.CallWeakReferenceHandlers(_canExecuteChangedHandlers);
}
public void ListenForNotificationFrom<TObservedType>(TObservedType viewModel) where TObservedType : INotifyPropertyChanged
{
viewModel.PropertyChanged += OnObservedPropertyChanged;
}
protected void AddListenOn<TObservedType, TPropertyType>(TObservedType viewModel, Expression<Func<TObservedType, TPropertyType>> propertyExpression) where TObservedType : INotifyPropertyChanged
{
AddListenOn(viewModel, nameof(propertyExpression));
}
protected void AddListenOn<TObservedType>(TObservedType viewModel, string propertyName) where TObservedType : INotifyPropertyChanged
{
viewModel.PropertyChanged += (sender, e) =>
{
if (e.PropertyName == propertyName)
RaiseCanExecuteChanged();
};
}
private void OnObservedPropertyChanged(object sender, PropertyChangedEventArgs e)
{
RaiseCanExecuteChanged();
}
}
}

View File

@@ -0,0 +1,73 @@
using System.Windows.Input;
namespace Bootstrapper.ViewModels.Util
{
/// <summary>
/// An <see cref="ICommand" /> which does not require data passed to the Execute and CanExecute methods.
/// </summary>
public interface IDelegateCommand : ICommand
{
/// <summary>
/// If true then the framework will not automatically query <see cref="ICommand.CanExecute" />.
/// Queries can be triggered manually by calling <see cref="RaiseCanExecuteChanged" />.
/// </summary>
bool IsAutomaticRequeryDisabled { get; set; }
/// <summary>
/// Method to determine if the command can be executed.
/// </summary>
bool CanExecute();
/// <summary>
/// Execution of the command.
/// </summary>
void Execute();
/// <summary>
/// Raises the <see cref="ICommand.CanExecuteChanged" /> event.
/// </summary>
void RaiseCanExecuteChanged();
}
/// <summary>
/// A strongly typed <see cref="ICommand" />.
/// </summary>
/// <typeparamref name="T">
/// Type of data passed to the <see cref="ICommand.Execute" /> and <see cref="ICommand.CanExecute" /> methods.
/// </typeparamref>
public interface IDelegateCommand<T> : ICommand
{
/// <summary>
/// If true then the framework will not automatically query <see cref="ICommand.CanExecute" />.
/// Queries can be triggered manually by calling <see cref="RaiseCanExecuteChanged" />.
/// </summary>
bool IsAutomaticRequeryDisabled { get; set; }
/// <summary>
/// Method to determine if the command can be executed.
/// </summary>
/// <param name="parameter">
/// Data to help determine if the command can execute.
/// </param>
/// <typeparamref name="T">
/// Type of the data passed.
/// </typeparamref>
bool CanExecute(T parameter);
/// <summary>
/// Execution of the command.
/// </summary>
/// <param name="parameter">
/// Data required to execute the command.
/// </param>
/// <typeparamref name="T">
/// Type of the data passed.
/// </typeparamref>
void Execute(T parameter);
/// <summary>
/// Raises the <see cref="ICommand.CanExecuteChanged" /> event.
/// </summary>
void RaiseCanExecuteChanged();
}
}

View File

@@ -0,0 +1,28 @@
using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace Bootstrapper.ViewModels.Util
{
/// <summary>
/// A <see cref="INotifyPropertyChanged" /> implementation that provides strongly typed OnPropertyChanged
/// implementations.
/// </summary>
public abstract class PropertyChanger : INotifyPropertyChanged
{
/// <summary>
/// Occurs when a property value changes.
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// Triggers the <see cref="PropertyChanged" /> event when passed the name of a property.
/// </summary>
/// <param name="propertyName">
/// Name of the property whose value changed.
/// </param>
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}

View File

@@ -0,0 +1,50 @@
using System;
using System.ComponentModel;
using System.Text;
namespace Bootstrapper.ViewModels.Util
{
internal abstract class ViewModelBase : PropertyChanger, IDataErrorInfo
{
public string this[string propertyName] => GetErrors(propertyName);
public string Error => GetErrors();
protected override void OnPropertyChanged(string propertyName = null)
{
base.OnPropertyChanged(propertyName);
base.OnPropertyChanged(nameof(Error));
}
/// <summary>
/// Override in derived classes to provide data validation.
/// </summary>
/// <param name="propertyName">Property name. If not supplied, will evaluate all properties and return all VM errors.</param>
/// <returns>
/// Returns an array of all errors found. If there are no errors, returns either an empty array or
/// <see langword="null" />.
/// </returns>
protected virtual string[] Validate(string propertyName = null)
{
return null;
}
private string GetErrors(string propertyName = null)
{
var errors = Validate(propertyName);
if (errors == null || errors.Length == 0)
return string.Empty;
var sb = new StringBuilder();
foreach (var error in errors)
{
if (sb.Length > 0)
sb.Append(Environment.NewLine);
sb.Append(error);
}
return sb.ToString();
}
}
}

View File

@@ -0,0 +1,19 @@
<UserControl
x:Class="Bootstrapper.Views.ConfigView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:vm="clr-namespace:Bootstrapper.ViewModels"
mc:Ignorable="d"
d:DesignWidth="450"
d:DataContext="{d:DesignInstance {x:Type vm:ConfigViewModel}}"
Background="Transparent"
>
<StackPanel>
<Label>Sample configuration option</Label>
<TextBox Text="{Binding SampleOption, UpdateSourceTrigger=PropertyChanged}" Width="300" />
</StackPanel>
</UserControl>

View File

@@ -0,0 +1,10 @@
namespace Bootstrapper.Views
{
public partial class ConfigView
{
public ConfigView()
{
InitializeComponent();
}
}
}

View File

@@ -0,0 +1,20 @@
<UserControl
x:Class="Bootstrapper.Views.ProgressView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:vm="clr-namespace:Bootstrapper.ViewModels"
mc:Ignorable="d"
d:DesignWidth="300"
d:DataContext="{d:DesignInstance vm:ProgressViewModel}"
>
<DockPanel Margin="0,10,0,0">
<ProgressBar Orientation="Horizontal" Value="{Binding Progress}" Height="15" DockPanel.Dock="Top"/>
<DockPanel DockPanel.Dock="Bottom">
<TextBlock Text="{Binding Package}" DockPanel.Dock="Left"/>
<TextBlock Text="{Binding Message}" HorizontalAlignment="Right" DockPanel.Dock="Right"/>
</DockPanel>
</DockPanel>
</UserControl>

View File

@@ -0,0 +1,25 @@
using System.Windows;
namespace Bootstrapper.Views
{
public partial class ProgressView
{
public ProgressView()
{
InitializeComponent();
}
public bool IsProgressVisible
{
get => (bool)GetValue(IsProgressVisibleProperty);
set => SetValue(IsProgressVisibleProperty, value);
}
public static readonly DependencyProperty IsProgressVisibleProperty = DependencyProperty
.Register(
nameof(IsProgressVisible),
typeof(bool),
typeof(ProgressView),
new PropertyMetadata(default(bool)));
}
}

View File

@@ -0,0 +1,168 @@
<Window
x:Class="Bootstrapper.Views.ShellView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:view="clr-namespace:Bootstrapper.Views"
xmlns:util="clr-namespace:Bootstrapper.ViewModels.Util"
xmlns:vm="clr-namespace:Bootstrapper.ViewModels"
Title="HelloWorld Install"
WindowStyle="None"
ShowInTaskbar="True"
AllowsTransparency="True"
Background="Transparent"
WindowStartupLocation="CenterScreen"
Topmost="False"
SizeToContent="Height"
Width="600"
Icon="pack://application:,,,/Bootstrapper;component/Assets/Icon.ico"
mc:Ignorable="d"
d:DataContext="{d:DesignInstance vm:ShellViewModel}"
>
<Border MouseLeftButtonDown="OnMouseLeftButtonDown" Background="White" BorderBrush="Black" BorderThickness="1">
<DockPanel Margin="20,40,20,10">
<TextBlock Text="Hello World" FontSize="14" HorizontalAlignment="Center" DockPanel.Dock="Top"/>
<TextBlock Text="{Binding Message, Mode=OneWay}" FontSize="10" HorizontalAlignment="Center" DockPanel.Dock="Bottom" Margin="0,10,0,0"/>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" DockPanel.Dock="Bottom" Height="30" Margin="0,0,0,10" Panel.ZIndex="0">
<StackPanel Orientation="Horizontal">
<Button Command="{Binding CancelCommand}" IsCancel="True" Width="95" Margin="0,0,10,0">Cancel</Button>
<Grid Visibility="{Binding IsPassive, Converter={util:BooleanVisibilityConverter Negate=True}}">
<Button
x:Name="RepairButton"
Command="{Binding RepairCommand}"
Visibility="{Binding IsRepairAvailable, Converter={util:BooleanVisibilityConverter}}"
IsDefault="False"
Width="95"
Margin="10,0,10,0"
>
<StackPanel Orientation="Horizontal">
<Image Height="16" x:Name="RepairShieldIcon" Margin="0,0,5,0"/>
<TextBlock Foreground="{Binding Foreground, ElementName=RepairButton}" VerticalAlignment="Center">Repair</TextBlock>
</StackPanel>
</Button>
</Grid>
<Button
x:Name="ApplyButton"
Command="{Binding ExecuteCommand}"
Visibility="{Binding IsPassive, Converter={util:BooleanVisibilityConverter Negate=True}}"
IsDefault="True"
Width="95"
Margin="10,0,10,0"
>
<StackPanel Orientation="Horizontal">
<Image Height="16" x:Name="ApplyShieldIcon" Margin="0,0,5,0"/>
<TextBlock Text="{Binding ExecuteDescription}" Foreground="{Binding Foreground, ElementName=ApplyButton}" VerticalAlignment="Center"/>
</StackPanel>
</Button>
</StackPanel>
<Button
Command="{Binding ExitCommand}"
Visibility="{Binding IsPassive, Converter={util:BooleanVisibilityConverter Negate=True}}"
Width="95"
Margin="10,0,0,0"
>
Exit
</Button>
</StackPanel>
<TextBlock
Visibility="{Binding IsPassive, Converter={util:BooleanVisibilityConverter Negate=True}}"
DockPanel.Dock="Bottom"
HorizontalAlignment="Right"
Panel.ZIndex="2"
Margin="0,0,0,5"
>
<Hyperlink Command="{Binding ShowLogCommand}">Log</Hyperlink>
</TextBlock>
<view:ProgressView DataContext="{Binding ProgressVm}" DockPanel.Dock="Bottom" Margin="0,0,0,10"/>
<Grid
IsEnabled="{Binding IsWaiting}"
Visibility="{Binding IsPassive, Converter={util:BooleanVisibilityConverter Negate=True}}"
Panel.ZIndex="1"
Margin="0,20,0,10"
DockPanel.Dock="Top"
>
<view:ConfigView DataContext="{Binding ConfigVm}" HorizontalAlignment="Center"/>
</Grid>
</DockPanel>
</Border>
</Window>

View File

@@ -0,0 +1,46 @@
using System.Drawing;
using System.Windows;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media.Imaging;
namespace Bootstrapper.Views
{
public partial class ShellView
{
public ShellView()
{
InitializeComponent();
try
{
BitmapSource applyIconSource = null;
BitmapSource repairIconSource = null;
try
{
applyIconSource = Imaging.CreateBitmapSourceFromHIcon(SystemIcons.Shield.Handle, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
repairIconSource = Imaging.CreateBitmapSourceFromHIcon(SystemIcons.Shield.Handle, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
}
catch
{
// ignored
}
if (applyIconSource != null)
ApplyShieldIcon.Source = applyIconSource;
if (repairIconSource != null)
RepairShieldIcon.Source = repairIconSource;
}
catch
{
// ignore
}
}
private void OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
DragMove();
}
}
}

View File

@@ -0,0 +1,223 @@
using Bootstrapper.Models;
using Bootstrapper.Phases;
using System;
using WixToolset.BootstrapperApplicationApi;
namespace Bootstrapper;
internal class WpfBaFactory
{
public Model Create(IDefaultBootstrapperApplication ba, IEngine engine, IBootstrapperCommand commandInfo)
{
try
{
var uiFacade = new WpfFacade(new Log(engine), commandInfo.Display);
var model = new Model(engine, commandInfo, uiFacade);
SubscribeCancelEvents(ba, model);
SubscribeProgressEvents(ba, model);
SubscribeDetectEvents(ba, model);
SubscribePlanEvents(ba, model);
SubscribeApplyEvents(ba, model);
model.Log.RemoveEmbeddedLog();
return model;
}
catch (Exception ex)
{
engine.Log(LogLevel.Error, ex.ToString());
throw;
}
}
private void SubscribeDetectEvents(IDefaultBootstrapperApplication ba, Model model)
{
// Adds a lot of logging, but reviewing the output can be educational
var debug = new LoggingDetectPhase(model);
var release = new DetectPhase(model);
#if DEBUG
var detectPhase = debug;
#else
var detectPhase = release;
#endif
detectPhase.DetectPhaseComplete += model.UiFacade.OnDetectPhaseComplete;
ba.Startup += detectPhase.OnStartup;
ba.Shutdown += detectPhase.OnShutdown;
ba.DetectBegin += detectPhase.OnDetectBegin;
ba.DetectComplete += detectPhase.OnDetectComplete;
ba.DetectRelatedBundle += detectPhase.OnDetectRelatedBundle;
ba.DetectRelatedBundlePackage += detectPhase.OnDetectRelatedBundlePackage;
ba.DetectRelatedMsiPackage += detectPhase.OnDetectRelatedMsiPackage;
ba.DetectUpdate += detectPhase.OnDetectUpdate;
ba.DetectUpdateBegin += detectPhase.OnDetectUpdateBegin;
ba.DetectUpdateComplete += detectPhase.OnDetectUpdateComplete;
ba.DetectForwardCompatibleBundle += detectPhase.OnDetectForwardCompatibleBundle;
ba.DetectPackageBegin += detectPhase.OnDetectPackageBegin;
ba.DetectPackageComplete += detectPhase.OnDetectPackageComplete;
ba.DetectPatchTarget += detectPhase.OnDetectPatchTarget;
ba.DetectCompatibleMsiPackage += detectPhase.OnDetectCompatibleMsiPackage;
ba.DetectMsiFeature += detectPhase.OnDetectMsiFeature;
}
private void SubscribePlanEvents(IDefaultBootstrapperApplication ba, Model model)
{
// Adds a lot of logging, but reviewing the output can be educational
var debug = new LoggingPlanPhase(model);
var release = new PlanPhase(model);
#if DEBUG
var planPhase = debug;
#else
var planPhase = release;
#endif
planPhase.PlanPhaseFailed += model.UiFacade.OnApplyPhaseComplete;
ba.PlanBegin += planPhase.OnPlanBegin;
ba.PlanComplete += planPhase.OnPlanComplete;
ba.PlanPackageBegin += planPhase.OnPlanPackageBegin;
ba.PlanPackageComplete += planPhase.OnPlanPackageComplete;
ba.PlanRollbackBoundary += planPhase.OnPlanRollbackBoundary;
ba.PlanRelatedBundle += planPhase.OnPlanRelatedBundle;
ba.PlanRelatedBundleType += planPhase.OnPlanRelatedBundleType;
ba.PlanRestoreRelatedBundle += planPhase.OnPlanRestoreRelatedBundle;
ba.PlanForwardCompatibleBundle += planPhase.OnPlanForwardCompatibleBundle;
ba.PlanCompatibleMsiPackageBegin += planPhase.OnPlanCompatibleMsiPackageBegin;
ba.PlanCompatibleMsiPackageComplete += planPhase.OnPlanCompatibleMsiPackageComplete;
ba.PlanMsiPackage += planPhase.OnPlanMsiPackage;
ba.PlanPatchTarget += planPhase.OnPlanPatchTarget;
ba.PlanMsiFeature += planPhase.OnPlanMsiFeature;
ba.PlannedPackage += planPhase.OnPlannedPackage;
ba.PlannedCompatiblePackage += planPhase.OnPlannedCompatiblePackage;
}
private void SubscribeApplyEvents(IDefaultBootstrapperApplication ba, Model model)
{
// Adds a lot of logging, but reviewing the output can be educational
var debug = new LoggingApplyPhase(model);
var release = new ApplyPhase(model);
#if DEBUG
var applyPhase = debug;
#else
var applyPhase = release;
#endif
applyPhase.ApplyPhaseComplete += model.UiFacade.OnApplyPhaseComplete;
ba.ApplyBegin += applyPhase.OnApplyBegin;
ba.ApplyComplete += applyPhase.OnApplyComplete;
ba.ApplyDowngrade += applyPhase.OnApplyDowngrade;
ba.ExecuteBegin += applyPhase.OnExecuteBegin;
ba.ExecuteComplete += applyPhase.OnExecuteComplete;
//ba.SetUpdateBegin += applyPhase.OnSetUpdateBegin;
//ba.SetUpdateComplete += applyPhase.OnSetUpdateComplete;
ba.ElevateBegin += applyPhase.OnElevateBegin;
ba.ElevateComplete += applyPhase.OnElevateComplete;
ba.ExecutePatchTarget += applyPhase.OnExecutePatchTarget;
ba.BeginMsiTransactionBegin += applyPhase.OnBeginMsiTransactionBegin;
ba.BeginMsiTransactionComplete += applyPhase.OnBeginMsiTransactionComplete;
ba.CommitMsiTransactionBegin += applyPhase.OnCommitMsiTransactionBegin;
ba.CommitMsiTransactionComplete += applyPhase.OnCommitMsiTransactionComplete;
ba.RollbackMsiTransactionBegin += applyPhase.OnRollbackMsiTransactionBegin;
ba.RollbackMsiTransactionComplete += applyPhase.OnRollbackMsiTransactionComplete;
ba.CacheBegin += applyPhase.OnCacheBegin;
ba.CacheComplete += applyPhase.OnCacheComplete;
ba.CacheAcquireBegin += applyPhase.OnCacheAcquireBegin;
ba.CacheAcquireComplete += applyPhase.OnCacheAcquireComplete;
ba.CacheAcquireResolving += applyPhase.OnCacheAcquireResolving;
ba.CacheAcquireProgress += applyPhase.OnCacheAcquireProgress;
ba.CacheContainerOrPayloadVerifyBegin += applyPhase.OnCacheContainerOrPayloadVerifyBegin;
ba.CacheContainerOrPayloadVerifyComplete += applyPhase.OnCacheContainerOrPayloadVerifyComplete;
ba.CacheContainerOrPayloadVerifyProgress += applyPhase.OnCacheContainerOrPayloadVerifyProgress;
ba.CachePackageBegin += applyPhase.OnCachePackageBegin;
ba.CachePackageComplete += applyPhase.OnCachePackageComplete;
ba.CachePackageNonVitalValidationFailure += applyPhase.OnCachePackageNonVitalValidationFailure;
ba.CachePayloadExtractBegin += applyPhase.OnCachePayloadExtractBegin;
ba.CachePayloadExtractComplete += applyPhase.OnCachePayloadExtractComplete;
ba.CachePayloadExtractProgress += applyPhase.OnCachePayloadExtractProgress;
ba.CacheVerifyBegin += applyPhase.OnCacheVerifyBegin;
ba.CacheVerifyComplete += applyPhase.OnCacheVerifyComplete;
ba.CacheVerifyProgress += applyPhase.OnCacheVerifyProgress;
ba.ExecutePackageBegin += applyPhase.OnExecutePackageBegin;
ba.ExecutePackageComplete += applyPhase.OnExecutePackageComplete;
ba.ExecuteProgress += applyPhase.OnExecuteProgress;
ba.PauseAutomaticUpdatesBegin += applyPhase.OnPauseAutomaticUpdatesBegin;
ba.PauseAutomaticUpdatesComplete += applyPhase.OnPauseAutomaticUpdatesComplete;
ba.SystemRestorePointBegin += applyPhase.OnSystemRestorePointBegin;
ba.SystemRestorePointComplete += applyPhase.OnSystemRestorePointComplete;
ba.LaunchApprovedExeBegin += applyPhase.OnLaunchApprovedExeBegin;
ba.LaunchApprovedExeComplete += applyPhase.OnLaunchApprovedExeComplete;
ba.RegisterBegin += applyPhase.OnRegisterBegin;
ba.RegisterComplete += applyPhase.OnRegisterComplete;
ba.UnregisterBegin += applyPhase.OnUnregisterBegin;
ba.UnregisterComplete += applyPhase.OnUnregisterComplete;
ba.Progress += applyPhase.OnProgress;
ba.ExecuteMsiMessage += applyPhase.OnExecuteMsiMessage;
ba.ExecuteProcessCancel += applyPhase.OnExecuteProcessCancel;
ba.ExecuteFilesInUse += applyPhase.OnExecuteFilesInUse;
ba.Error += applyPhase.OnError;
}
private void SubscribeCancelEvents(IDefaultBootstrapperApplication ba, Model model)
{
var cancelHandler = new CancelHandler(model);
ba.ElevateBegin += cancelHandler.CheckForCancel;
ba.PlanBegin += cancelHandler.CheckForCancel;
ba.PlanPackageBegin += cancelHandler.CheckForCancel;
ba.PlanPatchTarget += cancelHandler.CheckForCancel;
ba.PlanMsiFeature += cancelHandler.CheckForCancel;
ba.PlanMsiPackage += cancelHandler.CheckForCancel;
ba.PlanCompatibleMsiPackageBegin += cancelHandler.CheckForCancel;
ba.PlanForwardCompatibleBundle += cancelHandler.CheckForCancel;
ba.PlanRollbackBoundary += cancelHandler.CheckForCancel;
ba.PlanRelatedBundle += cancelHandler.CheckForCancel;
ba.PlanRelatedBundleType += cancelHandler.CheckForCancel;
ba.PlanRestoreRelatedBundle += cancelHandler.CheckForCancel;
ba.ApplyBegin += cancelHandler.CheckForCancel;
ba.LaunchApprovedExeBegin += cancelHandler.CheckForCancel;
ba.ExecuteBegin += cancelHandler.CheckForCancel;
ba.ExecutePackageBegin += cancelHandler.CheckForCancel;
ba.ExecutePatchTarget += cancelHandler.CheckForCancel;
ba.ExecuteProgress += cancelHandler.CheckForCancel;
ba.BeginMsiTransactionBegin += cancelHandler.CheckForCancel;
ba.CommitMsiTransactionBegin += cancelHandler.CheckForCancel;
ba.CacheBegin += cancelHandler.CheckForCancel;
ba.CacheAcquireBegin += cancelHandler.CheckForCancel;
ba.CacheAcquireProgress += cancelHandler.CheckForCancel;
ba.CacheAcquireResolving += cancelHandler.CheckForCancel;
ba.CachePackageBegin += cancelHandler.CheckForCancel;
ba.CacheContainerOrPayloadVerifyBegin += cancelHandler.CheckForCancel;
ba.CacheContainerOrPayloadVerifyProgress += cancelHandler.CheckForCancel;
ba.CachePayloadExtractBegin += cancelHandler.CheckForCancel;
ba.CachePayloadExtractProgress += cancelHandler.CheckForCancel;
ba.CacheVerifyBegin += cancelHandler.CheckForCancel;
ba.CacheVerifyProgress += cancelHandler.CheckForCancel;
ba.RegisterBegin += cancelHandler.CheckForCancel;
ba.Progress += cancelHandler.CheckForCancel;
ba.ExecuteMsiMessage += cancelHandler.CheckResult;
ba.ExecuteFilesInUse += cancelHandler.CheckResult;
}
private void SubscribeProgressEvents(IDefaultBootstrapperApplication ba, Model model)
{
var progressHandler = new ProgressHandler(model);
ba.PlanBegin += progressHandler.OnPlanBegin;
ba.ApplyBegin += progressHandler.OnApplyBegin;
ba.CacheAcquireProgress += progressHandler.OnCacheAcquireProgress;
ba.CachePayloadExtractProgress += progressHandler.OnCachePayloadExtractProgress;
ba.CacheVerifyProgress += progressHandler.OnCacheVerifyProgress;
ba.CacheContainerOrPayloadVerifyProgress += progressHandler.OnCacheContainerOrPayloadVerifyProgress;
ba.CacheComplete += progressHandler.OnCacheComplete;
ba.ExecutePackageComplete += progressHandler.OnExecutePackageComplete;
ba.ExecuteProgress += progressHandler.OnApplyExecuteProgress;
}
}

View File

@@ -0,0 +1,64 @@
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
<?include $(sys.CURRENTDIR)\Common.wxi?>
<?define CmdPalBuildDir="$(var.BinDir)\WinUI3Apps\CmdPal\"?>
<Fragment>
<DirectoryRef Id="WinUI3AppsInstallFolder">
<Directory Id="CmdPalInstallFolder" Name="CmdPal">
<Directory Id="CmdPalDepsInstallFolder" Name="Dependencies">
<?if $(sys.BUILDARCH) = x64 ?>
<Directory Id="CmdPalDepsX64InstallFolder" Name="x64" />
<?else?>
<Directory Id="CmdPalDepsArm64InstallFolder" Name="arm64" />
<?endif?>
</Directory>
</Directory>
</DirectoryRef>
<DirectoryRef Id="CmdPalInstallFolder" FileSource="$(var.CmdPalBuildDir)AppPackages\Microsoft.CmdPal.UI_$(var.CmdPalVersion)_Test">
<Component Id="Module_CmdPal" Guid="3A4942B2-1A86-4182-B3B4-65157365A980" Bitness="always64">
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys\components">
<RegistryValue Type="string" Name="Module_CmdPal" Value="" KeyPath="yes" />
</RegistryKey>
<?if $(sys.BUILDARCH) = x64 ?>
<File Id="Microsoft.CmdPal.UI___var.CmdPalVersion_._x64.msix" Source="$(var.CmdPalBuildDir)AppPackages\Microsoft.CmdPal.UI_$(var.CmdPalVersion)_Test\Microsoft.CmdPal.UI_$(var.CmdPalVersion)_x64.msix" />
<?else?>
<File Id="Microsoft.CmdPal.UI___var.CmdPalVersion_._arm64.msix" Source="$(var.CmdPalBuildDir)AppPackages\Microsoft.CmdPal.UI_$(var.CmdPalVersion)_Test\Microsoft.CmdPal.UI_$(var.CmdPalVersion)_arm64.msix" />
<?endif?>
</Component>
</DirectoryRef>
<?if $(sys.BUILDARCH) = x64 ?>
<DirectoryRef Id="CmdPalDepsX64InstallFolder" FileSource="$(var.CmdPalBuildDir)AppPackages\Microsoft.CmdPal.UI_$(var.CmdPalVersion)_Test\Dependencies\x64">
<Component Id="Module_CmdPal_Deps" Guid="C2790FC4-0665-4462-947A-D942A2AABFF0" Bitness="always64">
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys\components">
<RegistryValue Type="string" Name="Module_CmdPal_Deps" Value="" KeyPath="yes" />
</RegistryKey>
<File Id="Microsoft.VCLibs.x64.14.00.Desktop.appx" Source="$(var.CmdPalBuildDir)AppPackages\Microsoft.CmdPal.UI_$(var.CmdPalVersion)_Test\Dependencies\x64\Microsoft.VCLibs.x64.14.00.Desktop.appx" />
</Component>
</DirectoryRef>
<?else?>
<DirectoryRef Id="CmdPalDepsArm64InstallFolder" FileSource="$(var.CmdPalBuildDir)AppPackages\Microsoft.CmdPal.UI_$(var.CmdPalVersion)_Test\Dependencies\arm64">
<Component Id="Module_CmdPal_Deps" Guid="C2790FC4-0665-4462-947A-D942A2AABFF0" Bitness="always64">
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys\components">
<RegistryValue Type="string" Name="Module_CmdPal_Deps" Value="" KeyPath="yes" />
</RegistryKey>
<File Id="Microsoft.VCLibs.ARM64.14.00.Desktop.appx" Source="$(var.CmdPalBuildDir)AppPackages\Microsoft.CmdPal.UI_$(var.CmdPalVersion)_Test\Dependencies\arm64\Microsoft.VCLibs.ARM64.14.00.Desktop.appx" />
</Component>
</DirectoryRef>
<?endif?>
<ComponentGroup Id="CmdPalComponentGroup">
<Component Id="RemoveCmdPalFolder" Guid="2DF90C08-CC75-4245-A14E-B82904636C53" Directory="INSTALLFOLDER">
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys\components">
<RegistryValue Type="string" Name="RemoveCmdPalFolder" Value="" KeyPath="yes" />
</RegistryKey>
<RemoveFolder Id="RemoveCmdPalInstallDirFolder" Directory="CmdPalInstallFolder" On="uninstall" />
<RemoveFolder Id="RemoveCmdPalDepsInstallDirFolder" Directory="CmdPalDepsInstallFolder" On="uninstall" />
<?if $(sys.BUILDARCH) = x64 ?>
<RemoveFolder Id="RemoveCmdPalDepsX64InstallDirFolder" Directory="CmdPalDepsX64InstallFolder" On="uninstall" />
<?else?>
<RemoveFolder Id="RemoveCmdPalDepsArm64InstallDirFolder" Directory="CmdPalDepsArm64InstallFolder" On="uninstall" />
<?endif?>
</Component>
<ComponentRef Id="Module_CmdPal" />
<ComponentRef Id="Module_CmdPal_Deps" />
</ComponentGroup>
</Fragment>
</Wix>

View File

@@ -0,0 +1,29 @@
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
<?include $(sys.CURRENTDIR)\Common.wxi?>
<?define ColorPickerAssetsFiles=?>
<?define ColorPickerAssetsFilesPath=$(var.BinDir)Assets\ColorPicker\?>
<Fragment>
<!-- Color Picker -->
<DirectoryRef Id="BaseApplicationsAssetsFolder">
<Directory Id="ColorPickerAssetsFolder" Name="ColorPicker" />
</DirectoryRef>
<!-- Color Picker Resources -->
<DirectoryRef Id="ColorPickerAssetsFolder" FileSource="$(var.ColorPickerAssetsFilesPath)">
<!-- Generated by generateFileComponents.ps1 -->
<!--ColorPickerAssetsFiles_Component_Def-->
</DirectoryRef>
<ComponentGroup Id="ColorPickerComponentGroup">
<Component Id="RemoveColorPickerFolder" Guid="18C0C18C-F38A-4C88-B22C-9222F3A5B2EB" Directory="INSTALLFOLDER">
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys\components">
<RegistryValue Type="string" Name="RemoveColorPickerFolder" Value="" KeyPath="yes" />
</RegistryKey>
<RemoveFolder Id="RemoveFolderColorPickerAssetsFolder" Directory="ColorPickerAssetsFolder" On="uninstall" />
</Component>
</ComponentGroup>
</Fragment>
</Wix>

View File

@@ -0,0 +1,58 @@
<Include>
<!-- Names of folders and projects -->
<?define FancyZonesProjectName="FancyZones"?>
<?define ImageResizerProjectName="ImageResizer"?>
<?define KeyboardManagerProjectName="KeyboardManager"?>
<?define PowerAccentProjectName="PowerAccent"?>
<?define PowerRenameProjectName="PowerRename"?>
<?define FileLocksmithProjectName="FileLocksmith"?>
<?define ColorPickerProjectName="ColorPicker"?>
<?define PowerOCRProjectName="PowerOCR"?>
<?define AwakeProjectName="Awake"?>
<?define MouseUtilsProjectName="MouseUtils"?>
<?define AlwaysOnTopProjectName="AlwaysOnTop"?>
<?define MeasureToolProjectName="MeasureTool"?>
<?define HostsProjectName="Hosts"?>
<?define MouseWithoutBordersProjectName="MouseWithoutBorders"?>
<?define AdvancedPasteProjectName="AdvancedPaste"?>
<?define RegistryPreviewProjectName="RegistryPreview"?>
<?define PeekProjectName="Peek"?>
<?define WorkspacesProjectName="Workspaces"?>
<?define RepoDir="$(var.ProjectDir)..\..\" ?>
<?if $(var.Platform) = x64?>
<?define PowerToysPlatform="x64"?>
<?define PlatformProgramFiles="[ProgramFiles64Folder]"?>
<?define PlatformLK="x64" ?>
<?define BinDir="$(var.RepoDir)x64\$(var.Configuration)\" ?>
<?else?>
<!-- stable WIX 3 doesn't support ARM64, so we build installers as x86 -->
<?define PowerToysPlatform="ARM64"?>
<!--TODO: define to ARM64 Program files once it's available-->
<?define PlatformProgramFiles="[ProgramFiles6432Folder]"?>
<?define PlatformLK="arm64" ?>
<?define BinDir="$(var.RepoDir)ARM64\$(var.Configuration)\" ?>
<?endif?>
<?if $(var.PerUser) = "true"?>
<?define PerMachineYesNo="no"?>
<?define MSIPath="UserSetup"?>
<?define MSIName="PowerToysUserSetupVNext-$(var.Version)-$(var.PowerToysPlatform).msi"?>
<?define DefaultInstallDir="LocalAppDataFolder" ?>
<?define RegistryScope="HKCU" ?>
<?define InstallScope="perUser" ?>
<?define InstallPrivileges="limited" ?>
<?define UpgradeCodeGUID="D8B559DB-4C98-487A-A33F-50A8EEE42726" ?>
<?else?>
<?define PerMachineYesNo="yes"?>
<?define MSIPath="MachineSetup"?>
<?define MSIName="PowerToysSetupVNext-$(var.Version)-$(var.PowerToysPlatform).msi"?>
<?define DefaultInstallDir="ProgramFiles64Folder" ?>
<?define RegistryScope="HKLM" ?>
<?define InstallScope="perMachine" ?>
<?define InstallPrivileges="elevated" ?>
<?define UpgradeCodeGUID="42B84BF7-5FBF-473B-9C8B-049DC16F7708" ?>
<?endif?>
<?define BinX32Dir="$(var.RepoDir)x86\$(var.Configuration)\" ?>
</Include>

View File

@@ -0,0 +1,122 @@
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
<?include $(sys.CURRENTDIR)\Common.wxi?>
<Fragment>
<DirectoryRef Id="INSTALLFOLDER" FileSource="$(var.BinDir)">
<Component Id="powertoys_per_machine_comp" Bitness="always64">
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys">
<RegistryValue Type="string" Name="InstallScope" Value="$(var.InstallScope)" />
</RegistryKey>
</Component>
<Component Id="powertoys_toast_clsid" Bitness="always64">
<RemoveFolder Id="Remove_powertoys_toast_clsid" On="uninstall" />
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\CLSID\{DD5CACDA-7C2E-4997-A62A-04A597B58F76}">
<RegistryValue Type="string" Value="PowerToys Toast Notifications Background Activator" />
<RegistryValue Type="string" Key="LocalServer32" Value="[INSTALLFOLDER]PowerToys.exe -ToastActivated" />
<RegistryValue Type="string" Key="LocalServer32" Name="ThreadingModel" Value="Apartment" />
</RegistryKey>
</Component>
<Component Id="powertoys_exe" Guid="30261594-41A6-4509-AD09-FBC4E692F441" Bitness="always64">
<File Id="PowerToys.exe" Name="PowerToys.exe" Checksum="yes" />
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys">
<RegistryValue Type="string" Name="URL Protocol" Value="" KeyPath="yes" />
<RegistryValue Type="string" Value="URL:PowerToys custom internal URI protocol" />
<RegistryKey Key="DefaultIcon">
<RegistryValue Type="string" Value="PowerToys.exe" />
</RegistryKey>
<RegistryKey Key="shell\open\command">
<RegistryValue Type="string" Value="&quot;[INSTALLFOLDER]PowerToys.exe&quot; &quot;%1&quot;" />
</RegistryKey>
</RegistryKey>
</Component>
<Component Id="License_rtf" Guid="632C60DF-0DDC-4F14-8F2B-A28136CD9E63" Bitness="always64">
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys\components">
<RegistryValue Type="string" Name="License_rtf" Value="" KeyPath="yes" />
</RegistryKey>
<File Source="$(var.RepoDir)\installer\License.rtf" Id="License.rtf" />
</Component>
<Component Id="Notice_md" Guid="1671B5F5-1260-42CF-83A8-9B3430DFF8C5" Bitness="always64">
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys\components">
<RegistryValue Type="string" Name="Notice_md" Value="" KeyPath="yes" />
</RegistryKey>
<File Source="$(var.RepoDir)\Notice.md" Id="Notice.md" />
</Component>
</DirectoryRef>
<DirectoryRef Id="DSCModulesReferenceFolder">
<Component Id="PowerToysDSCReference" Guid="40869ACB-0BEB-4911-AE41-5E73BC1586A9" Bitness="always64">
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys\components">
<RegistryValue Type="string" Name="DSCModulesReference" Value="" KeyPath="yes" />
</RegistryKey>
<File Source="$(var.RepoDir)\src\dsc\Microsoft.PowerToys.Configure\Generated\Microsoft.PowerToys.Configure\$(var.Version).0\Microsoft.PowerToys.Configure.psd1" Id="PTConfReference.psd1" />
<File Source="$(var.RepoDir)\src\dsc\Microsoft.PowerToys.Configure\Generated\Microsoft.PowerToys.Configure\$(var.Version).0\Microsoft.PowerToys.Configure.psm1" Id="PTConfReference.psm1" />
</Component>
</DirectoryRef>
<?if $(var.PerUser) = "true" ?>
<!-- DSC module files for PerUser handled in InstallDSCModule custom action. -->
<?else?>
<StandardDirectory Id="ProgramFiles64Folder">
<Directory Id="WindowsPowerShellFolder" Name="WindowsPowerShell">
<Directory Id="PowerShellModulesFolder" Name="Modules">
<Directory Id="PowerToysDscFolder" Name="Microsoft.PowerToys.Configure">
<Directory Id="PowerToysDscVerFolder" Name="$(var.Version).0">
<Component Id="PowerToysDSC" Guid="C52AECA0-DA73-49B8-BB49-31EF6640FF1F" Bitness="always64">
<!-- Don't fail installation because of DSC. Files are marked as not vital. -->
<File Vital="no" Source="$(var.RepoDir)\src\dsc\Microsoft.PowerToys.Configure\Generated\Microsoft.PowerToys.Configure\$(var.Version).0\Microsoft.PowerToys.Configure.psd1" Id="PTConf.psd1" />
<File Vital="no" Source="$(var.RepoDir)\src\dsc\Microsoft.PowerToys.Configure\Generated\Microsoft.PowerToys.Configure\$(var.Version).0\Microsoft.PowerToys.Configure.psm1" Id="PTConf.psm1" />
</Component>
</Directory>
</Directory>
</Directory>
</Directory>
</StandardDirectory>
<?endif?>
<DirectoryRef Id="ApplicationProgramsFolder">
<Component Id="PowerToysStartMenuShortcut">
<Shortcut Id="ApplicationStartMenuShortcut" Name="PowerToys (Preview)" Description="PowerToys - Windows system utilities to maximize productivity" Icon="powertoys.exe" IconIndex="0" Target="[!PowerToys.exe]" WorkingDirectory="INSTALLFOLDER">
<ShortcutProperty Key="System.AppUserModel.ID" Value="Microsoft.PowerToysWin32" />
</Shortcut>
<RemoveFolder Id="CleanUpStartMenuShortCut" Directory="ApplicationProgramsFolder" On="uninstall" />
<!-- ApplicationStartMenuShortcut is implicitly installed in HKCU, so WIX won't allow changing this reg value to HKLM. -->
<RegistryValue Root="HKCU" Key="Software\Microsoft\PowerToys" Name="installed" Type="integer" Value="1" KeyPath="yes" />
</Component>
</DirectoryRef>
<StandardDirectory Id="DesktopFolder">
<Component Id="DesktopShortcut" Condition="INSTALLDESKTOPSHORTCUT">
<!-- DesktopShortcutId is implicitly installed in HKCU, so WIX won't allow changing this reg value to HKLM. -->
<RegistryValue Root="HKCU" Key="Software\[Manufacturer]\[ProductName]" Name="desktopshorcutinstalled" Type="integer" Value="1" KeyPath="yes" />
<Shortcut Id="DesktopShortcutId" Name="PowerToys (Preview)" Description="PowerToys - Windows system utilities to maximize productivity" Target="[!PowerToys.exe]" WorkingDirectory="INSTALLFOLDER" Icon="powertoys.exe" Directory="DesktopFolder" />
</Component>
</StandardDirectory>
</Fragment>
<Fragment>
<ComponentGroup Id="CoreComponents">
<Component Id="RemoveCoreFolder" Guid="9330BD69-2D12-4D98-B0C7-66C99564D619" Directory="INSTALLFOLDER">
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys\components">
<RegistryValue Type="string" Name="RemoveCoreFolder" Value="" KeyPath="yes" />
</RegistryKey>
<RemoveFolder Id="RemoveBaseApplicationsAssetsFolder" Directory="BaseApplicationsAssetsFolder" On="uninstall" />
<RemoveFolder Id="RemoveDSCModulesReferenceFolder" Directory="DSCModulesReferenceFolder" On="uninstall" />
<RemoveFolder Id="RemoveWinUI3AppsInstallFolder" Directory="WinUI3AppsInstallFolder" On="uninstall" />
<RemoveFolder Id="RemoveWinUI3AppsAssetsFolder" Directory="WinUI3AppsAssetsFolder" On="uninstall" />
<RemoveFolder Id="RemoveINSTALLFOLDER" Directory="INSTALLFOLDER" On="uninstall" />
</Component>
<ComponentRef Id="powertoys_exe" />
<ComponentRef Id="PowerToysStartMenuShortcut" />
<ComponentRef Id="powertoys_per_machine_comp" />
<ComponentRef Id="powertoys_toast_clsid" />
<ComponentRef Id="License_rtf" />
<ComponentRef Id="Notice_md" />
<ComponentRef Id="DesktopShortcut" />
<ComponentRef Id="PowerToysDSCReference" />
<?if $(var.PerUser) = "false" ?>
<ComponentRef Id="PowerToysDSC" />
<?endif?>
</ComponentGroup>
</Fragment>
</Wix>

View File

@@ -0,0 +1,28 @@
<!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. -->
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
<Fragment>
<UI>
<Dialog Id="PTInstallDirDlg" Width="370" Height="270" Title="!(loc.InstallDirDlg_Title)">
<Control Id="Next" Type="PushButton" X="236" Y="243" Width="56" Height="17" Default="yes" Text="!(loc.WixUINext)" />
<Control Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17" Text="!(loc.WixUIBack)" />
<Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Cancel="yes" Text="!(loc.WixUICancel)">
<Publish Event="SpawnDialog" Value="CancelDlg" />
</Control>
<Control Id="Description" Type="Text" X="25" Y="23" Width="280" Height="15" Transparent="yes" NoPrefix="yes" Text="!(loc.InstallDirDlgDescription)" />
<Control Id="Title" Type="Text" X="15" Y="6" Width="200" Height="15" Transparent="yes" NoPrefix="yes" Text="!(loc.InstallDirDlgTitle)" />
<Control Id="BannerBitmap" Type="Bitmap" X="0" Y="0" Width="370" Height="44" TabSkip="no" Text="!(loc.InstallDirDlgBannerBitmap)" />
<Control Id="BannerLine" Type="Line" X="0" Y="44" Width="370" Height="0" />
<Control Id="BottomLine" Type="Line" X="0" Y="234" Width="370" Height="0" />
<Control Id="FolderLabel" Type="Text" X="20" Y="60" Width="290" Height="30" NoPrefix="yes" Text="!(loc.InstallDirDlgFolderLabel)" />
<Control Id="Folder" Type="PathEdit" X="20" Y="100" Width="320" Height="18" Property="WIXUI_INSTALLDIR" Indirect="yes" />
<Control Id="ChangeFolder" Type="PushButton" X="20" Y="120" Width="56" Height="17" Text="!(loc.InstallDirDlgChange)" />
<Control Id="DesktopShortcutCheckBox" Type="CheckBox" X="20" Y="160" Width="290" Height="17" Property="INSTALLDESKTOPSHORTCUT" CheckBoxValue="1" Text="Create a shortcut for [ProductName] on the desktop." />
<Control Id="ScheduledTaskCheckBox" Type="CheckBox" X="20" Y="180" Width="330" Height="17" Property="CREATESCHEDULEDTASK" CheckBoxValue="1" Text="Automatically start [ProductName] at logon." />
</Dialog>
</UI>
</Fragment>
</Wix>

View File

@@ -0,0 +1,28 @@
<!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. -->
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
<Fragment>
<UI>
<Dialog Id="PTLicenseDlg" Width="370" Height="270" Title="!(loc.LicenseAgreementDlg_Title)">
<Control Id="BannerBitmap" Type="Bitmap" X="0" Y="0" Width="370" Height="44" TabSkip="no" Text="!(loc.LicenseAgreementDlgBannerBitmap)" />
<Control Id="BannerLine" Type="Line" X="0" Y="44" Width="370" Height="0" />
<Control Id="BottomLine" Type="Line" X="0" Y="234" Width="370" Height="0" />
<Control Id="Title" Type="Text" X="15" Y="6" Width="200" Height="15" Transparent="yes" NoPrefix="yes" Text="{\WixUI_Font_Title}[ProductName] License" />
<Control Id="Print" Type="PushButton" X="112" Y="243" Width="56" Height="17" Text="!(loc.WixUIPrint)">
<Publish Event="DoAction" Value="WixUIPrintEula_$(sys.BUILDARCHSHORT)" />
</Control>
<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" Default="yes" Text="!(loc.WixUINext)">
<Publish Event="SpawnWaitDialog" Value="WaitForCostingDlg" Condition="!(wix.WixUICostingPopupOptOut) OR CostingComplete = 1" />
</Control>
<Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Cancel="yes" Text="!(loc.WixUICancel)">
<Publish Event="SpawnDialog" Value="CancelDlg" />
</Control>
<Control Id="LicenseText" Type="ScrollableText" X="20" Y="60" Width="330" Height="140" Sunken="yes" TabSkip="no">
<Text SourceFile="!(wix.WixUILicenseRtf)" />
</Control>
</Dialog>
</UI>
</Fragment>
</Wix>

View File

@@ -0,0 +1,77 @@
<!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. -->
<!--
First-time install dialog sequence:
- WixUI_WelcomeDlg
- WixUI_LicenseAgreementDlg
- WixUI_PTInstallDirDlg
- WixUI_VerifyReadyDlg
- WixUI_DiskCostDlg
Maintenance dialog sequence:
- WixUI_MaintenanceWelcomeDlg
- WixUI_MaintenanceTypeDlg
- WixUI_PTInstallDirDlg
- WixUI_VerifyReadyDlg
Patch dialog sequence:
- WixUI_WelcomeDlg
- WixUI_VerifyReadyDlg
-->
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
<Fragment>
<UI Id="WixUI_PTInstallDir">
<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" />
<Publish Dialog="BrowseDlg" Control="OK" Event="DoAction" Value="WixUIValidatePath_$(sys.BUILDARCHSHORT)" Order="3" />
<Publish Dialog="BrowseDlg" Control="OK" Event="SpawnDialog" Value="InvalidDirDlg" Order="4" Condition="NOT WIXUI_DONTVALIDATEPATH AND WIXUI_INSTALLDIR_VALID&lt;&gt;&quot;1&quot;" />
<Publish Dialog="ExitDialog" Control="Finish" Event="EndDialog" Value="Return" Order="999" />
<Publish Dialog="WelcomeDlg" Control="Next" Event="NewDialog" Value="PTLicenseDlg" Condition="NOT Installed" />
<Publish Dialog="WelcomeDlg" Control="Next" Event="NewDialog" Value="VerifyReadyDlg" Condition="Installed AND PATCH" />
<Publish Dialog="PTLicenseDlg" Control="Back" Event="NewDialog" Value="WelcomeDlg" />
<Publish Dialog="PTLicenseDlg" Control="Next" Event="NewDialog" Value="PTInstallDirDlg" />
<Publish Dialog="PTInstallDirDlg" Control="Back" Event="NewDialog" Value="PTLicenseDlg" />
<Publish Dialog="PTInstallDirDlg" Control="Next" Event="SetTargetPath" Value="[WIXUI_INSTALLDIR]" Order="1" />
<Publish Dialog="PTInstallDirDlg" Control="Next" Event="DoAction" Value="WixUIValidatePath_$(sys.BUILDARCHSHORT)" Order="2" Condition="NOT WIXUI_DONTVALIDATEPATH" />
<Publish Dialog="PTInstallDirDlg" Control="Next" Event="SpawnDialog" Value="InvalidDirDlg" Order="3" Condition="NOT WIXUI_DONTVALIDATEPATH AND WIXUI_INSTALLDIR_VALID&lt;&gt;&quot;1&quot;" />
<Publish Dialog="PTInstallDirDlg" Control="Next" Event="NewDialog" Value="VerifyReadyDlg" Order="4" Condition="WIXUI_DONTVALIDATEPATH OR WIXUI_INSTALLDIR_VALID=&quot;1&quot;" />
<Publish Dialog="PTInstallDirDlg" Control="ChangeFolder" Property="_BrowseProperty" Value="[WIXUI_INSTALLDIR]" Order="1" />
<Publish Dialog="PTInstallDirDlg" Control="ChangeFolder" Event="SpawnDialog" Value="BrowseDlg" Order="2" />
<Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="PTInstallDirDlg" Order="1" Condition="NOT Installed" />
<Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="MaintenanceTypeDlg" Order="2" Condition="Installed AND NOT PATCH" />
<Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="WelcomeDlg" Order="2" Condition="Installed AND PATCH" />
<Publish Dialog="MaintenanceWelcomeDlg" Control="Next" Event="NewDialog" Value="MaintenanceTypeDlg" />
<Publish Dialog="MaintenanceTypeDlg" Control="RepairButton" Event="NewDialog" Value="VerifyReadyDlg" />
<Publish Dialog="MaintenanceTypeDlg" Control="RemoveButton" Event="NewDialog" Value="VerifyReadyDlg" />
<Publish Dialog="MaintenanceTypeDlg" Control="Back" Event="NewDialog" Value="MaintenanceWelcomeDlg" />
</UI>
<UIRef Id="WixUI_Common" />
</Fragment>
</Wix>

View File

@@ -0,0 +1,11 @@
<Project>
<Import Project="..\..\src\Version.props" Condition="Exists('..\..\src\Version.props')" />
<PropertyGroup>
<!-- Set BaseIntermediateOutputPath for each project to avoid conflicts -->
<BaseIntermediateOutputPath Condition="'$(MSBuildProjectName)' == 'PowerToysInstallerVNext'">obj\Installer\</BaseIntermediateOutputPath>
<BaseIntermediateOutputPath Condition="'$(MSBuildProjectName)' == 'PowerToysBootstrapperVNext'">obj\Bootstrapper\</BaseIntermediateOutputPath>
<!-- Set MSBuildProjectExtensionsPath to use the BaseIntermediateOutputPath -->
<MSBuildProjectExtensionsPath Condition="'$(BaseIntermediateOutputPath)' != ''">$(BaseIntermediateOutputPath)</MSBuildProjectExtensionsPath>
</PropertyGroup>
</Project>

View File

@@ -0,0 +1,27 @@
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
<?include $(sys.CURRENTDIR)\Common.wxi?>
<?define EnvironmentVariablesAssetsFiles=?>
<?define EnvironmentVariablesAssetsFilesPath=$(var.BinDir)WinUI3Apps\Assets\EnvironmentVariables\?>
<Fragment>
<DirectoryRef Id="WinUI3AppsAssetsFolder">
<Directory Id="EnvironmentVariablesAssetsFolder" Name="EnvironmentVariables" />
</DirectoryRef>
<DirectoryRef Id="EnvironmentVariablesAssetsFolder" FileSource="$(var.EnvironmentVariablesAssetsFilesPath)">
<!-- Generated by generateFileComponents.ps1 -->
<!--EnvironmentVariablesAssetsFiles_Component_Def-->
</DirectoryRef>
<ComponentGroup Id="EnvironmentVariablesComponentGroup">
<Component Id="RemoveEnvironmentVariablesFolder" Guid="B62A779D-38BA-46B2-859D-9D242D9B0CC1" Directory="EnvironmentVariablesAssetsFolder">
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys\components">
<RegistryValue Type="string" Name="RemoveEnvironmentVariablesFolder" Value="" KeyPath="yes" />
</RegistryKey>
<RemoveFolder Id="RemoveFolderEnvironmentVariablesAssetsFolder" Directory="EnvironmentVariablesAssetsFolder" On="uninstall" />
</Component>
</ComponentGroup>
</Fragment>
</Wix>

View File

@@ -0,0 +1,39 @@
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
<?include $(sys.CURRENTDIR)\Common.wxi?>
<?define MonacoPreviewHandlerMonacoAssetsFiles=?>
<?define MonacoPreviewHandlerMonacoAssetsFilesPath=$(var.BinDir)Assets\Monaco\?>
<?define MonacoPreviewHandlerCustomLanguagesFiles=?>
<?define MonacoPreviewHandlerCustomLanguagesFilesPath=$(var.BinDir)Assets\Monaco\customLanguages\?>
<Fragment>
<DirectoryRef Id="BaseApplicationsAssetsFolder">
<Directory Id="MonacoAssetsFolder" Name="Monaco">
<Directory Id="MonacoPreviewHandlerMonacoCustomLanguagesFolder" Name="customLanguages" />
<Directory Id="MonacoPreviewHandlerMonacoSRCFolder" Name="monacoSRC" />
</Directory>
</DirectoryRef>
<DirectoryRef Id="MonacoAssetsFolder" FileSource="$(var.MonacoPreviewHandlerMonacoAssetsFilesPath)">
<!-- Generated by generateFileComponents.ps1 -->
<!--MonacoPreviewHandlerMonacoAssetsFiles_Component_Def-->
</DirectoryRef>
<DirectoryRef Id="MonacoPreviewHandlerMonacoCustomLanguagesFolder" FileSource="$(var.MonacoPreviewHandlerCustomLanguagesFilesPath)">
<!-- Generated by generateFileComponents.ps1 -->
<!--MonacoPreviewHandlerCustomLanguagesFiles_Component_Def-->
</DirectoryRef>
<ComponentGroup Id="FileExplorerPreviewComponentGroup">
<Component Id="RemoveFileExplorerPreviewFolder" Guid="4AB83E58-17F1-41AF-B67F-F6C36EFED28D" Directory="MonacoAssetsFolder">
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys\components">
<RegistryValue Type="string" Name="RemoveFileExplorerPreviewFolder" Value="" KeyPath="yes" />
</RegistryKey>
<RemoveFolder Id="RemoveMonacoAssetsFolder" Directory="MonacoAssetsFolder" On="uninstall" />
<RemoveFolder Id="RemoveFolderMonacoPreviewHandlerCustomLanguagesFolder" Directory="MonacoPreviewHandlerMonacoCustomLanguagesFolder" On="uninstall" />
<RemoveFolder Id="RemoveFolderMonacoPreviewHandlerMonacoSRCFolder" Directory="MonacoPreviewHandlerMonacoSRCFolder" On="uninstall" />
</Component>
</ComponentGroup>
</Fragment>
</Wix>

View File

@@ -0,0 +1,43 @@
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
<?include $(sys.CURRENTDIR)\Common.wxi?>
<?define FileLocksmithAssetsFiles=?>
<?define FileLocksmithAssetsFilesPath=$(var.BinDir)WinUI3Apps\Assets\FileLocksmith\?>
<Fragment>
<DirectoryRef Id="WinUI3AppsAssetsFolder">
<Directory Id="FileLocksmithAssetsInstallFolder" Name="FileLocksmith" />
</DirectoryRef>
<DirectoryRef Id="FileLocksmithAssetsInstallFolder" FileSource="$(var.FileLocksmithAssetsFilesPath)">
<!-- Generated by generateFileComponents.ps1 -->
<!--FileLocksmithAssetsFiles_Component_Def-->
<!-- !Warning! Make sure to change Component Guid if you update something here -->
<Component Id="Module_FileLocksmith" Guid="108D3EC1-E6E0-4E81-88EF-25966133CB41" Bitness="always64">
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\CLSID\{84D68575-E186-46AD-B0CB-BAEB45EE29C0}">
<RegistryValue Type="string" Value="File Locksmith Shell Extension" />
<RegistryValue Type="string" Name="ContextMenuOptIn" Value="" />
<RegistryValue Type="string" Key="InprocServer32" Value="[WinUI3AppsInstallFolder]PowerToys.FileLocksmithExt.dll" />
<RegistryValue Type="string" Key="InprocServer32" Name="ThreadingModel" Value="Apartment" />
</RegistryKey>
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\AllFileSystemObjects\ShellEx\ContextMenuHandlers\FileLocksmithExt">
<RegistryValue Type="string" Value="{84D68575-E186-46AD-B0CB-BAEB45EE29C0}" />
</RegistryKey>
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\Drive\ShellEx\ContextMenuHandlers\FileLocksmithExt">
<RegistryValue Type="string" Value="{84D68575-E186-46AD-B0CB-BAEB45EE29C0}" />
</RegistryKey>
</Component>
</DirectoryRef>
<ComponentGroup Id="FileLocksmithComponentGroup">
<Component Id="RemoveFileLocksmithFolder" Guid="1DAC9A3F-D89C-4730-BF57-1778E011709B" Directory="FileLocksmithAssetsInstallFolder">
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys\components">
<RegistryValue Type="string" Name="RemoveFileLocksmithFolder" Value="" KeyPath="yes" />
</RegistryKey>
<RemoveFolder Id="RemoveFolderFileLocksmithAssetsFolder" Directory="FileLocksmithAssetsInstallFolder" On="uninstall" />
</Component>
<ComponentRef Id="Module_FileLocksmith" />
</ComponentGroup>
</Fragment>
</Wix>

View File

@@ -0,0 +1,27 @@
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
<?include $(sys.CURRENTDIR)\Common.wxi?>
<?define HostsAssetsFiles=?>
<?define HostsAssetsFilesPath=$(var.BinDir)WinUI3Apps\Assets\Hosts\?>
<Fragment>
<DirectoryRef Id="WinUI3AppsAssetsFolder">
<Directory Id="HostsAssetsFolder" Name="Hosts" />
</DirectoryRef>
<DirectoryRef Id="HostsAssetsFolder" FileSource="$(var.HostsAssetsFilesPath)">
<!-- Generated by generateFileComponents.ps1 -->
<!--HostsAssetsFiles_Component_Def-->
</DirectoryRef>
<ComponentGroup Id="HostsComponentGroup">
<Component Id="RemoveHostsFolder" Guid="7FF19EBB-041D-4498-9826-C9AECEBE86E1" Directory="HostsAssetsFolder">
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys\components">
<RegistryValue Type="string" Name="RemoveHostsFolder" Value="" KeyPath="yes" />
</RegistryKey>
<RemoveFolder Id="RemoveFolderHostsAssetsFolder" Directory="HostsAssetsFolder" On="uninstall" />
</Component>
</ComponentGroup>
</Fragment>
</Wix>

View File

@@ -0,0 +1,52 @@
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
<?include $(sys.CURRENTDIR)\Common.wxi?>
<?define ImageResizerAssetsFiles=?>
<?define ImageResizerAssetsFilesPath=$(var.BinDir)Assets\ImageResizer\?>
<Fragment>
<DirectoryRef Id="BaseApplicationsAssetsFolder">
<Directory Id="ImageResizerAssetsFolder" Name="ImageResizer" />
</DirectoryRef>
<DirectoryRef Id="ImageResizerAssetsFolder" FileSource="$(var.ImageResizerAssetsFilesPath)">
<!-- Generated by generateFileComponents.ps1 -->
<!--ImageResizerAssetsFiles_Component_Def-->
<Component Id="Module_ImageResizer_Registry" Bitness="always64">
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\CLSID\{51B4D7E5-7568-4234-B4BB-47FB3C016A69}\InprocServer32">
<RegistryValue Value="[INSTALLFOLDER]PowerToys.ImageResizerExt.dll" Type="string" />
<RegistryValue Name="ThreadingModel" Value="Apartment" Type="string" />
</RegistryKey>
<RegistryValue Root="$(var.RegistryScope)" Key="SOFTWARE\Classes\Directory\ShellEx\DragDropHandlers\ImageResizer" Value="{51B4D7E5-7568-4234-B4BB-47FB3C016A69}" Type="string" />
<!-- Registry Keys for the context menu handler for each of the following image formats: bmp, dib, gif, jfif, jpe, jpeg, jpg, jxr, png, rle, tif, tiff, wdp -->
<RegistryValue Root="$(var.RegistryScope)" Key="SOFTWARE\Classes\SystemFileAssociations\.bmp\ShellEx\ContextMenuHandlers\ImageResizer" Value="{51B4D7E5-7568-4234-B4BB-47FB3C016A69}" Type="string" />
<RegistryValue Root="$(var.RegistryScope)" Key="SOFTWARE\Classes\SystemFileAssociations\.dib\ShellEx\ContextMenuHandlers\ImageResizer" Value="{51B4D7E5-7568-4234-B4BB-47FB3C016A69}" Type="string" />
<RegistryValue Root="$(var.RegistryScope)" Key="SOFTWARE\Classes\SystemFileAssociations\.gif\ShellEx\ContextMenuHandlers\ImageResizer" Value="{51B4D7E5-7568-4234-B4BB-47FB3C016A69}" Type="string" />
<RegistryValue Root="$(var.RegistryScope)" Key="SOFTWARE\Classes\SystemFileAssociations\.jfif\ShellEx\ContextMenuHandlers\ImageResizer" Value="{51B4D7E5-7568-4234-B4BB-47FB3C016A69}" Type="string" />
<RegistryValue Root="$(var.RegistryScope)" Key="SOFTWARE\Classes\SystemFileAssociations\.jpe\ShellEx\ContextMenuHandlers\ImageResizer" Value="{51B4D7E5-7568-4234-B4BB-47FB3C016A69}" Type="string" />
<RegistryValue Root="$(var.RegistryScope)" Key="SOFTWARE\Classes\SystemFileAssociations\.jpeg\ShellEx\ContextMenuHandlers\ImageResizer" Value="{51B4D7E5-7568-4234-B4BB-47FB3C016A69}" Type="string" />
<RegistryValue Root="$(var.RegistryScope)" Key="SOFTWARE\Classes\SystemFileAssociations\.jpg\ShellEx\ContextMenuHandlers\ImageResizer" Value="{51B4D7E5-7568-4234-B4BB-47FB3C016A69}" Type="string" />
<RegistryValue Root="$(var.RegistryScope)" Key="SOFTWARE\Classes\SystemFileAssociations\.jxr\ShellEx\ContextMenuHandlers\ImageResizer" Value="{51B4D7E5-7568-4234-B4BB-47FB3C016A69}" Type="string" />
<RegistryValue Root="$(var.RegistryScope)" Key="SOFTWARE\Classes\SystemFileAssociations\.png\ShellEx\ContextMenuHandlers\ImageResizer" Value="{51B4D7E5-7568-4234-B4BB-47FB3C016A69}" Type="string" />
<RegistryValue Root="$(var.RegistryScope)" Key="SOFTWARE\Classes\SystemFileAssociations\.rle\ShellEx\ContextMenuHandlers\ImageResizer" Value="{51B4D7E5-7568-4234-B4BB-47FB3C016A69}" Type="string" />
<RegistryValue Root="$(var.RegistryScope)" Key="SOFTWARE\Classes\SystemFileAssociations\.tif\ShellEx\ContextMenuHandlers\ImageResizer" Value="{51B4D7E5-7568-4234-B4BB-47FB3C016A69}" Type="string" />
<RegistryValue Root="$(var.RegistryScope)" Key="SOFTWARE\Classes\SystemFileAssociations\.tiff\ShellEx\ContextMenuHandlers\ImageResizer" Value="{51B4D7E5-7568-4234-B4BB-47FB3C016A69}" Type="string" />
<RegistryValue Root="$(var.RegistryScope)" Key="SOFTWARE\Classes\SystemFileAssociations\.wdp\ShellEx\ContextMenuHandlers\ImageResizer" Value="{51B4D7E5-7568-4234-B4BB-47FB3C016A69}" Type="string" />
</Component>
</DirectoryRef>
<ComponentGroup Id="ImageResizerComponentGroup">
<Component Id="RemoveImageResizerFolder" Guid="8E5DE86A-8618-4590-9584-51BCD3A14280" Directory="ImageResizerAssetsFolder">
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys\components">
<RegistryValue Type="string" Name="RemoveImageResizerFolder" Value="" KeyPath="yes" />
</RegistryKey>
<RemoveFolder Id="RemoveFolderImageResizerAssetsFolder" Directory="ImageResizerAssetsFolder" On="uninstall" />
</Component>
<ComponentRef Id="Module_ImageResizer_Registry" />
</ComponentGroup>
</Fragment>
</Wix>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@@ -0,0 +1,55 @@
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
<?include $(sys.CURRENTDIR)\Common.wxi?>
<Fragment>
<DirectoryRef Id="INSTALLFOLDER">
<Directory Id="KeyboardManagerEditorInstallFolder" Name="KeyboardManagerEditor" />
<Directory Id="KeyboardManagerEngineInstallFolder" Name="KeyboardManagerEngine" />
</DirectoryRef>
<!-- KBM Editor -->
<DirectoryRef Id="KeyboardManagerEditorInstallFolder" FileSource="$(var.BinDir)KeyboardManagerEditor">
<Component Id="Module_KeyboardManager_Editor" Guid="E9C74E78-970F-4DF5-9CC0-FFD3CCF285B4" Bitness="always64">
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys\components">
<RegistryValue Type="string" Name="Module_KeyboardManager_Editor" Value="" KeyPath="yes" />
</RegistryKey>
<File Id="PowerToys.KeyboardManagerEditor.exe" Source="$(var.BinDir)KeyboardManagerEditor\PowerToys.KeyboardManagerEditor.exe" />
<File Id="Microsoft.Toolkit.Win32.UI.XamlHost.dll" Source="$(var.BinDir)KeyboardManagerEditor\Microsoft.Toolkit.Win32.UI.XamlHost.dll" />
<File Id="Microsoft.UI.Xaml.dll" Source="$(var.BinDir)KeyboardManagerEditor\Microsoft.UI.Xaml.dll" />
<File Id="msvcp140_app.dll" Source="$(var.BinDir)KeyboardManagerEditor\msvcp140_app.dll" />
<File Id="resources.pri" Source="$(var.BinDir)KeyboardManagerEditor\resources.pri" />
<File Id="vcruntime140_app.dll" Source="$(var.BinDir)KeyboardManagerEditor\vcruntime140_app.dll" />
<?if $(sys.BUILDARCH) = x64 ?>
<File Id="vcruntime140_1_app.dll" Source="$(var.BinDir)KeyboardManagerEditor\vcruntime140_1_app.dll" />
<?endif?>
<File Id="vcruntime140.dll" Source="$(var.BinDir)KeyboardManagerEditor\vcruntime140.dll" />
<File Id="vcruntime140_1.dll" Source="$(var.BinDir)KeyboardManagerEditor\vcruntime140_1.dll" />
<File Id="msvcp140.dll" Source="$(var.BinDir)KeyboardManagerEditor\msvcp140.dll" />
</Component>
</DirectoryRef>
<!-- KBM Engine -->
<DirectoryRef Id="KeyboardManagerEngineInstallFolder" FileSource="$(var.BinDir)KeyboardManagerEngine">
<Component Id="Module_KeyboardManager_Engine" Guid="3F58FCE3-B44D-4676-94E9-C59F1FE42FFD" Bitness="always64">
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys\components">
<RegistryValue Type="string" Name="Module_KeyboardManager_Engine" Value="" KeyPath="yes" />
</RegistryKey>
<File Id="PowerToys.KeyboardManagerEngine.exe" Source="$(var.BinDir)KeyboardManagerEngine\PowerToys.KeyboardManagerEngine.exe" />
</Component>
</DirectoryRef>
<ComponentGroup Id="KeyboardManagerComponentGroup">
<Component Id="RemoveKeyboardManagerFolder" Guid="C411CB11-4617-40A4-B6DA-1823B49FB9FF" Directory="INSTALLFOLDER">
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys\components">
<RegistryValue Type="string" Name="RemoveKeyboardManagerFolder" Value="" KeyPath="yes" />
</RegistryKey>
<RemoveFolder Id="RemoveFolderKeyboardManagerEditorFolder" Directory="KeyboardManagerEditorInstallFolder" On="uninstall" />
<RemoveFolder Id="RemoveFolderKeyboardManagerEngineFolder" Directory="KeyboardManagerEngineInstallFolder" On="uninstall" />
</Component>
<ComponentRef Id="Module_KeyboardManager_Editor" />
<ComponentRef Id="Module_KeyboardManager_Engine" />
</ComponentGroup>
</Fragment>
</Wix>

View File

@@ -0,0 +1,830 @@
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
<Fragment>
<DirectoryRef Id="MonacoPreviewHandlerMonacoSRCFolder">
<Directory Id="dirF3D9892E484C03D885D33EEA40EF87C2" Name="min" />
</DirectoryRef>
</Fragment>
<Fragment>
<ComponentGroup Id="MonacoSRCHeatGenerated">
<Component Id="cmpD794187AC05B0DFB15CD6A20F14A62D1" Directory="dirB6981C7877773C58E1AF6BDA6BA6F65E" Guid="{293F297B-F77F-4FC3-B3B7-57C7971AB8EB}">
<File Id="fil5A195A746DF9F6BFC8AC7BB0FE3F57F1" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\loader.js" />
</Component>
<Component Id="cmp76F2BAE040BF5B744FC7D6635120D0AC" Directory="dir977D270DC116F38F1B9320DA90FDF824" Guid="{F66EB766-95B6-41B2-8B6B-F2C28D35254D}">
<File Id="fil230F5EB5567F7124C272D9A08FD8E06E" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\base\browser\ui\codicons\codicon\codicon.ttf" />
</Component>
<Component Id="cmpB90F6001EE652278DF1F2404C3AC82AD" Directory="dir275B90E50E8463E5A7FE8E4490177655" Guid="{DE0EEF40-5E17-45EF-9A5D-FE02CE2771C1}">
<File Id="fil5707E516B7AA4E597526C6CC85AAC6EE" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\base\common\worker\simpleWorker.nls.de.js" />
</Component>
<Component Id="cmpE89319386933CC41881199D73CE409FE" Directory="dir275B90E50E8463E5A7FE8E4490177655" Guid="{2C13AA07-C241-434E-B173-F2BD4FF4E937}">
<File Id="fil13BCC8728A5F0D6300F6B85AB00833F2" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\base\common\worker\simpleWorker.nls.es.js" />
</Component>
<Component Id="cmp65F6AA386EE2A7A90BA893F0E73A7741" Directory="dir275B90E50E8463E5A7FE8E4490177655" Guid="{7C9EC847-C05A-4116-99A1-134EDE10A48F}">
<File Id="filB4C8F9513A064E1C00F49494873E55E8" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\base\common\worker\simpleWorker.nls.fr.js" />
</Component>
<Component Id="cmp77734493650FF4AB58B99C030897C2BD" Directory="dir275B90E50E8463E5A7FE8E4490177655" Guid="{2715E4D4-6275-4520-BDC5-1B19734D2930}">
<File Id="fil8663ED2A7E79DAE319E65474E82F45B0" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\base\common\worker\simpleWorker.nls.it.js" />
</Component>
<Component Id="cmp593C7718F41A091A4A3CFB51CC707FF4" Directory="dir275B90E50E8463E5A7FE8E4490177655" Guid="{EB748ED4-A9AE-41C4-A585-DE1052F004BE}">
<File Id="fil017A687AD2CCE62C83577F1E93946058" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\base\common\worker\simpleWorker.nls.ja.js" />
</Component>
<Component Id="cmp320DF96442E69C8E1924351184F91A47" Directory="dir275B90E50E8463E5A7FE8E4490177655" Guid="{940BA005-4CC7-4896-BBED-8DFE98EF3EFD}">
<File Id="filD6C9666D67F09118BE523D8A6C46836A" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\base\common\worker\simpleWorker.nls.js" />
</Component>
<Component Id="cmp0EF426F24661ED7EBFD6B3F50FCD1D17" Directory="dir275B90E50E8463E5A7FE8E4490177655" Guid="{67005149-751E-40FB-A725-42A7CC3AEDE4}">
<File Id="filA2712B6FF0D3E1F83C685B022A9907DB" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\base\common\worker\simpleWorker.nls.ko.js" />
</Component>
<Component Id="cmp1132C8043C3F6D377477B3D486460EF7" Directory="dir275B90E50E8463E5A7FE8E4490177655" Guid="{A7F88A3A-AE97-48EB-8A4E-18AC0194D8A0}">
<File Id="fil479C62EA30789166E5A6D802579027E6" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\base\common\worker\simpleWorker.nls.ru.js" />
</Component>
<Component Id="cmp1F9372B1F8B7DC8C7CA29E8668582184" Directory="dir275B90E50E8463E5A7FE8E4490177655" Guid="{4812FAEA-9A62-40B8-9F73-FC0929610DF2}">
<File Id="filF93A3D1232655CE040B3B4DDB92E88AE" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\base\common\worker\simpleWorker.nls.zh-cn.js" />
</Component>
<Component Id="cmp4A431A741757A7B0611ECD249745D6DE" Directory="dir275B90E50E8463E5A7FE8E4490177655" Guid="{DEE2E207-E983-43E3-B7FC-1F485C6B7ADF}">
<File Id="filDEFBADDBBAF39DAA5B1636399F17726F" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\base\common\worker\simpleWorker.nls.zh-tw.js" />
</Component>
<Component Id="cmp27DA4DF6CA1A415A1B093D2AA7DCB7B8" Directory="dir1073A77D6A6F9C3BD868895BC0D2BB43" Guid="{6101D20F-FA19-406E-B877-444EA20B385B}">
<File Id="filE7A37FC22BFDE273DA141CEC965874BC" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\base\worker\workerMain.js" />
</Component>
<Component Id="cmp5DD256FF0534FA2EFD897D7096F79776" Directory="dirEEC36D6CE0850FD998425DA64003EF71" Guid="{3D4BBC83-B0A3-4F8F-8FD5-837EA55742B7}">
<File Id="fil4716FFF7F5BE94226FEEF137155B46EF" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\basic-languages\abap\abap.js" />
</Component>
<Component Id="cmpC257248FA4D690DD5F454AD45894A1D6" Directory="dirA5D6CA3E903645EA55097ED025FDC806" Guid="{7880F300-DFCE-497A-B745-8513243F2392}">
<File Id="filF7702CDF0F8A4A51E66DAA366AACB368" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\basic-languages\apex\apex.js" />
</Component>
<Component Id="cmpDF8D96BA15B92D88FFDDD65D85624A47" Directory="dir78E5143BB991015ABB2B126B33DF20F3" Guid="{38612CA7-2C7F-4653-8AF4-1037AF9DE200}">
<File Id="fil77FDE762A29B94578C6A7E50142114F3" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\basic-languages\azcli\azcli.js" />
</Component>
<Component Id="cmpF7E39F0DA6D41EC6E5ACA196CBD76A4B" Directory="dirBB7633031785DFA55795107B6D149163" Guid="{D8B3C80C-A2B1-40D8-9F96-2B945C005096}">
<File Id="fil5CC8087FCE857D501F36DC47C770C099" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\basic-languages\bat\bat.js" />
</Component>
<Component Id="cmp123E8D2669169DF370FBC1E638A88B01" Directory="dir3428A3B09088B4D43D3C5D04E265CE5B" Guid="{E8863C50-B519-45EF-BDFF-522D1A1CF6ED}">
<File Id="fil73D7298F5BC725AB1902960F384D8EE6" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\basic-languages\bicep\bicep.js" />
</Component>
<Component Id="cmp9D24E640F94C19F22CAA9D8317FCE692" Directory="dir11500149D13F58C29A933FFBCF7AE831" Guid="{DCB5A7B1-CD7E-467F-B34A-EAF20D605CF7}">
<File Id="filF79C76A71621AD4172E02CE5603CA7FE" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\basic-languages\cameligo\cameligo.js" />
</Component>
<Component Id="cmp2A2DBAA1966C85200CC39CA3BEFA0290" Directory="dir8F4676CBA9C11989C570D9760FDB6D14" Guid="{917E823D-3113-45E3-BF93-DED3A3172BD3}">
<File Id="filE68A15A72537EBCF9F123DFB8C5067E4" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\basic-languages\clojure\clojure.js" />
</Component>
<Component Id="cmp60FC028022733E6C011C5FEDF27B4841" Directory="dir1DC625A0C557A53F30B2B2778AC20EAC" Guid="{AACADB0B-35AA-43F2-9678-5297112D3418}">
<File Id="fil68CC461818DCCB3A84A1EF35D0390651" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\basic-languages\coffee\coffee.js" />
</Component>
<Component Id="cmp61D17782DC575327F8B8C6401A788846" Directory="dir2DADC716DFBEA6EC858374A8DE4A55BF" Guid="{B2E172DD-871E-4B0D-A668-122E72137361}">
<File Id="filAC903246C65CCCCDE52F6B5BF26B25E1" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\basic-languages\cpp\cpp.js" />
</Component>
<Component Id="cmp066AA35698CEA6719D4C1297E66185D0" Directory="dirE4E212383E30441F1F43B3FCB74DDD2E" Guid="{B1A8EB15-29A0-48CB-8A15-5753D810D660}">
<File Id="fil613CABD1196D2EB0D5AF231E6ACA5F48" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\basic-languages\csharp\csharp.js" />
</Component>
<Component Id="cmp41D508CED9B63C5935241337A5E65C34" Directory="dir9BDD3DD06D0AE947DFAB4ECE8AED417A" Guid="{656BF0E9-1DF0-444B-8619-D5DB76A039D5}">
<File Id="fil4D323557640C7B4D1370AE7415167ED4" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\basic-languages\csp\csp.js" />
</Component>
<Component Id="cmpCE10D34AFB174E2D480A8E5DAD51163D" Directory="dir44B4D4584FD02BDBAD15EAA2FF9C3081" Guid="{761EAF43-4700-4D97-AE55-F30F0FFECD98}">
<File Id="filC4F99435F9C80CF179A573800122002A" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\basic-languages\css\css.js" />
</Component>
<Component Id="cmp38134B04881A8198F104FDC5958A01E5" Directory="dir5FB0D3CBAA8948CFB2EA580D00694174" Guid="{6A65C724-2347-4D1D-940A-68625A5DE87E}">
<File Id="filF056125DE9BD2B480277AC2558B2BC05" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\basic-languages\cypher\cypher.js" />
</Component>
<Component Id="cmpD3DCAB67EF8E802516BF17B051F8B54A" Directory="dir98CCF277B8D261E44E72D2436AE03A17" Guid="{1D278A16-67F6-4353-8E70-DE57AD9AD2D3}">
<File Id="fil18E4885DCF08C677694AF22C2CC58D77" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\basic-languages\dart\dart.js" />
</Component>
<Component Id="cmp33A6E9486D8D91F57B7AE33501C45932" Directory="dirEEBBE2EAD2FF3D7241AB0246E0F2EE59" Guid="{1FB3E05A-5A37-47E2-A8E4-8035FD8485BA}">
<File Id="fil677130B753F696F5542909678FAFD7EC" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\basic-languages\dockerfile\dockerfile.js" />
</Component>
<Component Id="cmp8A1AC85DC4199DD7B8D6FF67A97A8C37" Directory="dirE449AC0C719DDD618B136F9380896803" Guid="{590A912E-FEB0-43A9-A373-9940D7D71B04}">
<File Id="filEF2689C0260FCCFF84FAEDDA4D63646F" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\basic-languages\ecl\ecl.js" />
</Component>
<Component Id="cmp042CDA391CBCB3EFC24858A7E3410029" Directory="dir9913F0276DC804D55443ED170B33897B" Guid="{06E3A888-E49E-401F-B441-9EDFDA90228D}">
<File Id="filB98B6E1418582A24EC9731DAA62A1E77" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\basic-languages\elixir\elixir.js" />
</Component>
<Component Id="cmp992D43898063D04A1E6394A98A36F927" Directory="dir4384234FF105D9CE96FF8F90EFD7A008" Guid="{08597831-6288-418F-B937-65775FFD3483}">
<File Id="fil4553DF98EFAC3BF7ECA12E07ED546C0C" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\basic-languages\flow9\flow9.js" />
</Component>
<Component Id="cmp5EFA49D606C8C90FB42023FD541FA9CB" Directory="dir4EDA420ECFFAE101E961F38C239F9924" Guid="{78A6D6C8-A527-4174-B249-F70E3FD7E003}">
<File Id="fil0ABCE560EBAC04418295F0C0BB894508" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\basic-languages\freemarker2\freemarker2.js" />
</Component>
<Component Id="cmp49F9485793701E195AE9B312C908C977" Directory="dirDC0D8D61976CD9114B598B3D7BC3A75E" Guid="{68089CC7-5F9D-4B44-B4D4-EE19A1958916}">
<File Id="fil9F3473182D46B20D72D60B8AD0031246" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\basic-languages\fsharp\fsharp.js" />
</Component>
<Component Id="cmpB0B29540C5D5446781C1B6FAA1E090D6" Directory="dir09029A378D1F2B1CB5245A0926BB01B5" Guid="{2E0607DE-1A14-4EA0-BCB3-5EED572BC3DE}">
<File Id="fil1B0F3EF110B1B3619872E641D06BDFB8" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\basic-languages\go\go.js" />
</Component>
<Component Id="cmp9FBC4EED7959B05C65F8B932DE801C21" Directory="dir7FC34AF4DF60585C05AF245B0976DB1A" Guid="{653C988D-EB67-436F-BD83-EB6A4F9749CB}">
<File Id="fil678F2821AF1941144AA26961A798225E" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\basic-languages\graphql\graphql.js" />
</Component>
<Component Id="cmp7B7FB30E70C4E173321B3E834AB38153" Directory="dir0D808593278731C2A8A5E3579964B030" Guid="{6F151DA2-40F0-4553-B1A2-5B76D4A7DCAE}">
<File Id="fil704686C5BE0D4A68FE121AAD02C2B2BC" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\basic-languages\handlebars\handlebars.js" />
</Component>
<Component Id="cmp3177C2D5997D023EB737804E90A8219D" Directory="dir08D93211F4F28EB69AAB12C06A0A2717" Guid="{8F07FC31-7C3E-451C-A8C8-6B94C61C6244}">
<File Id="fil41B011E3827AEE80EF78527C083141CD" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\basic-languages\hcl\hcl.js" />
</Component>
<Component Id="cmpC589E0056B907D7CF2CF0B45E8163C01" Directory="dir290B934CDF26049203FDCD68940E9A56" Guid="{AD0449B8-D539-4748-843D-ACCC252969D8}">
<File Id="fil17392B8121F4FBB6A506FABC2C2E5B4A" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\basic-languages\html\html.js" />
</Component>
<Component Id="cmp4D5DDE2D9E64DBF9C36214C22F90B6CB" Directory="dir32E14839B1A40DAE7351CDB5201D0D6B" Guid="{9883696B-2F6B-4E2D-9315-16317B79D418}">
<File Id="fil1DD0BC29C5CFEE770DCBC99543791DE5" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\basic-languages\ini\ini.js" />
</Component>
<Component Id="cmp8825BFFA58C83EE05C788E9EB696ACDB" Directory="dirD6C83E20CEBD48927A1B999FC29D10D5" Guid="{458AF123-8DBE-4100-9E46-D6E3CF2DC934}">
<File Id="filE1A38B5EDCCC63CDAC5C53F6FB704BF8" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\basic-languages\java\java.js" />
</Component>
<Component Id="cmp4932D9E07C49E2847EDB8EF1CF8F329B" Directory="dir5F323D10C8C8A75A64FA7C89D96680EC" Guid="{4AB1C5E5-2FC7-4C15-94F1-8749B0301B0D}">
<File Id="fil75D6CB9D9E4BE7CE31A77C2F73E4170B" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\basic-languages\javascript\javascript.js" />
</Component>
<Component Id="cmp230607F260EA2F70B55769327F052D04" Directory="dir06601F6D5A3F9D7D60424F5E09524DB4" Guid="{B80F841E-53ED-44D4-8AB7-CC2723C10688}">
<File Id="fil39BD2FA55AD2B1997E5B0C8E8C3FAB4F" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\basic-languages\julia\julia.js" />
</Component>
<Component Id="cmp66E703C175502EC3E2709571A70CB232" Directory="dir70381AED3CC1DDCE84DA393FA084DF30" Guid="{8CA28657-F148-422D-AE8C-1A7883AB465B}">
<File Id="filAE5313884B78191CBE09A130A8710884" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\basic-languages\kotlin\kotlin.js" />
</Component>
<Component Id="cmp84DFB427A889509D65D2B421A80B5A63" Directory="dir71C05CEF79E7873797404DB7FA624782" Guid="{8A306CFF-AEC8-48A9-90A8-84B8FDE79C40}">
<File Id="fil9C85B4CD5265DAF76CEE07C4224196A2" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\basic-languages\less\less.js" />
</Component>
<Component Id="cmp2E3FDB092C4D52C001F8F0E74C309548" Directory="dir827C0A5B3A46EFF9ED86626CA8E09FEB" Guid="{C980849D-87AC-4B55-9358-253F2F83444F}">
<File Id="filFD0890423932307FE25D4C8B53F00BD0" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\basic-languages\lexon\lexon.js" />
</Component>
<Component Id="cmp8F54BAF95378835755F3A5CD9AFADBDD" Directory="dir97DF6B0B0AC776C7AA8A3B17483E6B88" Guid="{8C9C5A55-E657-48C7-8175-912D97D7C997}">
<File Id="filEF4F2E0137CAC7A0CB164DBDFAA399B2" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\basic-languages\liquid\liquid.js" />
</Component>
<Component Id="cmp18388C9F47969C68D1E3502E7274C276" Directory="dirE518C878E428E98585AE9C7E7A5B2742" Guid="{DE3DFB30-7D7D-4B89-BB37-EBC091EC2C63}">
<File Id="fil97D5759C81D0BD8FE8C89506426A7497" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\basic-languages\lua\lua.js" />
</Component>
<Component Id="cmp3A23A2A3F0AB9CE881DB1B2E1C72C4EC" Directory="dir1FCD208725F3AED0B959B9B5B5206392" Guid="{D0EB6E8F-B7F2-44B3-8DCF-B2955D96D7AF}">
<File Id="fil1D6EF5348EF78CF6AB5296A5DB526D17" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\basic-languages\m3\m3.js" />
</Component>
<Component Id="cmp57E4B0F9116B033EFC658534BE41C3E7" Directory="dir6358A938D9D11E471FFB3DA2ADAD7BCB" Guid="{592CD39A-B856-45A1-987D-5C95E3E5A2EA}">
<File Id="fil50720EF680C0B80D0A873A006FAF36E4" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\basic-languages\markdown\markdown.js" />
</Component>
<Component Id="cmp1314326A4518FD22F710126767095CBD" Directory="dir5D94AAB564D15FAF0AD003A873C6E880" Guid="{AA650D34-EE94-4B3F-949B-38E256C42DCC}">
<File Id="fil3F07BC27D9B0043109DC8A031C4F88BA" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\basic-languages\mdx\mdx.js" />
</Component>
<Component Id="cmpCB6D69B171231CD55C8F2F006E2B6A5B" Directory="dir45D8F9637E749259F3D09F01185CB277" Guid="{6BF3B181-3A94-438F-B692-01C901860460}">
<File Id="fil9B69D50CE180BF085AAAAEF02DEE74A0" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\basic-languages\mips\mips.js" />
</Component>
<Component Id="cmpF740C950DE512A21B1090FAD9AA7F43B" Directory="dirEEBD553161A5477464565F0AA9C66A4E" Guid="{AF4FBBF1-DFB8-4C3B-8C27-0CF8B6E76402}">
<File Id="fil6EEF0E30296A7C5E9E221F559D46C564" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\basic-languages\msdax\msdax.js" />
</Component>
<Component Id="cmpA691984DF9BAE25738CA0308D59CDBF3" Directory="dirE82FE5B1199EBD2FB6D6CB51A54FDBF1" Guid="{29D7ACC1-9554-4491-818B-C7DEACE82DCA}">
<File Id="filE2E2ADB30CFFEE9947D413AC238ED703" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\basic-languages\mysql\mysql.js" />
</Component>
<Component Id="cmp1C59CF91472616F1C050D9F316A029F6" Directory="dir2757105AED061CB6E7A811A59041E70B" Guid="{632748A1-6EC2-41D9-A91D-9DDF207CF72D}">
<File Id="filA05535A421A43C37B4F1DD8ECE1A482B" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\basic-languages\objective-c\objective-c.js" />
</Component>
<Component Id="cmpFE06C4889E456B912FB3EC264017EA97" Directory="dir2DAF129901E8E61B5F28D8764B2A53EC" Guid="{3A3DDA58-392B-4312-A96B-39BCDA8A80EE}">
<File Id="fil8D8757671D2402CAB7991C706DA30383" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\basic-languages\pascal\pascal.js" />
</Component>
<Component Id="cmp24C41DC272F12153D4A032F8A7F6275D" Directory="dir88BB0F9F45F25EA2B8BD2B169E47C6C3" Guid="{317BA39A-E7B2-4D7E-8DF0-503D07C34F09}">
<File Id="fil95AE56597B69A6257AF6BCA3524181CE" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\basic-languages\pascaligo\pascaligo.js" />
</Component>
<Component Id="cmp6BEEC5E5DE43E67A9CD1C9F5C5A54EF1" Directory="dir4365498E48631EE6110E707C908F23E5" Guid="{03FC1897-56A2-4959-8D11-B3D2E6617FA0}">
<File Id="filF1CA56B4A2FD133AC73C3FC142E1DC04" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\basic-languages\perl\perl.js" />
</Component>
<Component Id="cmp5C77DCEFCB780E509972C581E7A667C6" Directory="dir7BBE99088AD794540115669A678F7B57" Guid="{9078DF58-0982-44FF-8452-FF9241273E32}">
<File Id="filB7C2C8FE9FB72313CBF6C62671819658" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\basic-languages\pgsql\pgsql.js" />
</Component>
<Component Id="cmpD96FF6E590005311C7D30C197C6A0307" Directory="dir73ABE26EA37698BE7A3BB7464BCC549A" Guid="{7090CFEE-C109-43D2-9100-3070C59F65AD}">
<File Id="fil0464BE3C58F01A6B41DF4F477DB30C02" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\basic-languages\php\php.js" />
</Component>
<Component Id="cmp213104A30886166BA0E11531FDA6DB31" Directory="dir25A1924A74C6AC9A29661F8183830092" Guid="{B0DC3938-DF2F-4B0B-8A3A-476D937436C8}">
<File Id="fil32E78E404FE7CCF7D8695DF7D6C74516" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\basic-languages\pla\pla.js" />
</Component>
<Component Id="cmp16C8627E2AFE920942D74D5BD856F05D" Directory="dirA17168CDD8EEFA01087350F05246840B" Guid="{738DD45A-7DD0-452C-A4FA-4429C570038B}">
<File Id="fil04764B685A932E9A4A48EB0310B17703" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\basic-languages\postiats\postiats.js" />
</Component>
<Component Id="cmp1B47D9C0F19BDDF7480A4CDC9AB9D569" Directory="dirBF1FE658716DC862C9477F47E3EE0E9C" Guid="{2ED00312-DCA2-40F0-BB02-A28968D848C3}">
<File Id="fil8BAF642C32F4C085B9021790BC7F1753" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\basic-languages\powerquery\powerquery.js" />
</Component>
<Component Id="cmpDB990090AB5BB210E519416AE5C78615" Directory="dirF0808D745B8F1D84EC3E766DED71F25D" Guid="{6DC50786-868F-4B4F-AF5E-29DA307EB83D}">
<File Id="filF41994C5075B95653F5E0E8CC957BB5F" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\basic-languages\powershell\powershell.js" />
</Component>
<Component Id="cmp44E47D9A54F88DB52FE8EEF3E627891B" Directory="dirB0AC1BF5C32B8286A676408C25A61765" Guid="{5B7F104C-858C-4BAB-A510-9BD733E972A5}">
<File Id="filD2EF2570C2F0A965E303338172EF31E8" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\basic-languages\protobuf\protobuf.js" />
</Component>
<Component Id="cmp5E8C3A3D73CF271F9F1E0A7C5A0F4799" Directory="dir55FBC962119473511EA55883EE255033" Guid="{B99CC010-4FC8-4C64-AA20-F809BF734B9A}">
<File Id="fil36EDC81F4162D7F6889C6FAD1EE25274" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\basic-languages\pug\pug.js" />
</Component>
<Component Id="cmpE1183B34F4303C066B405DC7F580B8B3" Directory="dir76484A3A9306229E678FD42F61E4FB4C" Guid="{9DE91FDD-9F11-4F4C-B638-4E50A11239BE}">
<File Id="filA28101ED2FB28FFEBEF91CA35ABA4181" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\basic-languages\python\python.js" />
</Component>
<Component Id="cmp510DF3AB1E33810D207A9E5214A45211" Directory="dir3A749E768458D7BDB7E8A3619C9DBF19" Guid="{A5D1EBA9-4337-416E-8649-BE0B9F82CEA1}">
<File Id="fil32F5269E874740765999CAF3A9ED0A8E" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\basic-languages\qsharp\qsharp.js" />
</Component>
<Component Id="cmp58AAD5FA6383B79AC4A2D0D62A431CB5" Directory="dirBEAA75EFDD04A1C0A9B19D70DD4732C1" Guid="{7C06275B-5A21-48E1-8318-B5991B5B0DCD}">
<File Id="filEFE8F8D1345E00064E315D54E43E8F01" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\basic-languages\r\r.js" />
</Component>
<Component Id="cmp4864DCD32017665F9BB35BEEAADF8A6A" Directory="dir00D56363696DE914F9B5833697CE6982" Guid="{83530E4A-2732-46B2-A02E-AC96F5DA2B17}">
<File Id="filBEF9DDF10A4E2C12691C819DFA6EFE1A" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\basic-languages\razor\razor.js" />
</Component>
<Component Id="cmp3C639E16956296FE1D0F105407600436" Directory="dirFC530128ACFC59ECC74A19B7BB5EA51E" Guid="{6FB32BA2-84D1-4552-B63E-BAC6A5A12FFD}">
<File Id="fil34F417302580CFB557A5A2344A27416F" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\basic-languages\redis\redis.js" />
</Component>
<Component Id="cmp8C10458E0F2A3FF3BE8726181F0C1E36" Directory="dir6731A8985A5C5FB88A9B2E2E504176AB" Guid="{126A6A6A-1D01-4D96-B413-F23EC6412E24}">
<File Id="filA4D4F68D56F445406C84AEAA71EE6CB9" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\basic-languages\redshift\redshift.js" />
</Component>
<Component Id="cmp70AE16ED3E9D61BFEB26A57D0EE6FE00" Directory="dir9251D6B5581D4133030A9129421E5255" Guid="{802A2E39-82C3-4918-9B26-5EF483C1E85C}">
<File Id="fil72400E6CF9ED96C8FED862DCB5ECAD5C" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\basic-languages\restructuredtext\restructuredtext.js" />
</Component>
<Component Id="cmpAD9EF7CD070993A40475D546EF92B3FC" Directory="dir59061104B938DAD5AB82F8269BF9A5CC" Guid="{3A0D608A-A248-4ACE-9298-A82E7812298B}">
<File Id="fil297DE4364A0AECC8CA41DF12A648FE70" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\basic-languages\ruby\ruby.js" />
</Component>
<Component Id="cmp4B7EF474E90F8CFAADB3164A01AFFE37" Directory="dir1670BA97A7F3BB1471DA99A5F0DDF616" Guid="{168429A8-C2BB-4F57-A8B6-3A1FA64E62DF}">
<File Id="fil7457730B29BFF0E111609B4B8B080866" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\basic-languages\rust\rust.js" />
</Component>
<Component Id="cmp492EFE4E0608D0FC3AC6CA57F8304272" Directory="dirE97385D326929F1063C2ECE2A2291160" Guid="{F1ACB7E4-2672-448E-8C7E-4594A943C175}">
<File Id="fil21FE4117314367DE11CB6B56542D917D" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\basic-languages\sb\sb.js" />
</Component>
<Component Id="cmpEEC5F6AE0DB2EEDA217EA399A99FAD2D" Directory="dirECE9BA50EABF810E2043B3CAB8D50EFF" Guid="{765A96CC-6C76-4537-BDBF-1EDF0C1F85A4}">
<File Id="filC547F1A9C4461E8F1C5F201F5F8BC45D" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\basic-languages\scala\scala.js" />
</Component>
<Component Id="cmp7B3A0FBF09671C886AEEB6691CFC5950" Directory="dir2D09B3341172E78CED634088E3A0F0D6" Guid="{4908731B-660A-41AB-ACD3-777072305687}">
<File Id="filB6150653139EA7511F6C62E50A7123E3" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\basic-languages\scheme\scheme.js" />
</Component>
<Component Id="cmp17AD36D554AFF8C3F803D394A951409A" Directory="dirD421FCD5A3C6885202E25032B144CBC0" Guid="{EEF585FD-900E-4931-A3EF-A8FA3EA5892D}">
<File Id="fil926165C5CB9FE7A40C40B7F7C81ECC4C" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\basic-languages\scss\scss.js" />
</Component>
<Component Id="cmp3722C5C661FFA62440A61CFB0AA27D02" Directory="dir1EEEE401A815DC23AF03E7CAB9B69E8A" Guid="{1736D61A-9BC5-4675-B866-E5F989046969}">
<File Id="fil1655B592BA6AB0437868FE0B4084182C" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\basic-languages\shell\shell.js" />
</Component>
<Component Id="cmp34F767180B1903E2CB6601CAA8CBD40B" Directory="dir5816A6FCDB97E961BF867F179E019F5C" Guid="{D5305477-4AC3-4353-B92C-B9D533D78729}">
<File Id="fil5180142482B9251C1131C06B02128123" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\basic-languages\solidity\solidity.js" />
</Component>
<Component Id="cmp129EC490BB79A4C3043B7C9DF392FAA7" Directory="dir94109FFBE73954C2E3D9560E43A94392" Guid="{0FC1CFD1-A489-4D96-B8F2-6FB55E6E6117}">
<File Id="fil1E962378D9BCCE53EDC667BCCEA7F7B7" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\basic-languages\sophia\sophia.js" />
</Component>
<Component Id="cmp6A907AFCED6CBB9ED4A7B88E9580D653" Directory="dirC315087738325C868107A7E7D0D4CAEF" Guid="{A9FEC8A0-2E0B-4215-AEDF-672F2615BD0E}">
<File Id="fil41B25CF5C0F174C49894D14A52F2DD27" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\basic-languages\sparql\sparql.js" />
</Component>
<Component Id="cmpC8C679E43528396B9B3F5081608E526D" Directory="dirB5EF435C30BEC37ACFF774928750D156" Guid="{548A95C4-CFD6-4940-ADCB-5D1190C8FA6B}">
<File Id="fil798B57A552B95E9D21CD6B3CC4A5F075" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\basic-languages\sql\sql.js" />
</Component>
<Component Id="cmp7207DBBDA0D4C1DBB41C84603BA09931" Directory="dir52852EA262AF9E52EAAFE3C91C7E5AAB" Guid="{1CB7F6CD-942D-458D-913B-874F527B4E47}">
<File Id="fil5E8B830254A3429CC3322FF5104BA8D7" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\basic-languages\st\st.js" />
</Component>
<Component Id="cmpC4652086B9880C093BD80EDFAE501B2A" Directory="dirDE2C1CBE313A17238E2151D374450794" Guid="{50EE05CC-022A-490A-B39E-A0660959B228}">
<File Id="filD7B9818DDCDD592008BC44FDEF877AA5" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\basic-languages\swift\swift.js" />
</Component>
<Component Id="cmp74D0BCC38FC3B7DBAE59BC6CEBAC893E" Directory="dir36C13CDE80473EDC55B5B2B9A4585964" Guid="{137C3BE8-357D-43D3-A592-88432D1D26A8}">
<File Id="fil0F7BC73CB34B55B7D922C41EC221E206" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\basic-languages\systemverilog\systemverilog.js" />
</Component>
<Component Id="cmp55E997BF9077CE615EC79EB887495E13" Directory="dir05BEFA701AFF555CBB0C575C4A8042DD" Guid="{DB249D47-8503-4964-A307-0DF691E64BEF}">
<File Id="fil5C156694117FB91497790ED575BAC183" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\basic-languages\tcl\tcl.js" />
</Component>
<Component Id="cmp4D4A1F0935C6DC917BA09F8E579D0FF5" Directory="dir9FBB158AFDA9A66E220286D4F2609E71" Guid="{33B8CC89-0E71-4450-939B-1ACF51A09D57}">
<File Id="filFE01063A541012A82A6F8D2045B93263" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\basic-languages\twig\twig.js" />
</Component>
<Component Id="cmpFF3FCAE616D37EAD14EF983504CC727F" Directory="dirF551ED8D7A1A57AEAD472CE945460F44" Guid="{D3F7CD57-DBE1-4989-AE2C-3EE7CFD3D89F}">
<File Id="fil122D364F60BF040622B818884CA43C98" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\basic-languages\typescript\typescript.js" />
</Component>
<Component Id="cmpD54D459A7B653EA2E3682BF144AD50E0" Directory="dir6E11C98F7CEAF38791F199EF7D6C5A9C" Guid="{08BCF6BB-B9F3-47FF-BEFA-B3DFD4627A76}">
<File Id="fil9421738766446503692A368999585409" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\basic-languages\vb\vb.js" />
</Component>
<Component Id="cmp01E1676001EF9447CCE99EF997C3854A" Directory="dir3AA5BCBFC2ED6DF8EE8F6DFED0E130D8" Guid="{7C3BEA61-1D90-4FFF-98E9-35E47877ECA7}">
<File Id="filA2810D25D0DB89452047A541E92E048A" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\basic-languages\wgsl\wgsl.js" />
</Component>
<Component Id="cmp5C3D3E69EB6D8936621F6EAF99202894" Directory="dir28FFEB82009147C6884C2EC55E931EF0" Guid="{232643C8-42D8-4F58-929D-DE0FDE5542D3}">
<File Id="fil956BD8B00CA18D1568B4C79693EB2A3D" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\basic-languages\xml\xml.js" />
</Component>
<Component Id="cmp61C476F773F767F6539045AD5ADE758F" Directory="dir23EA2EDA8657328B2431358EE85819C3" Guid="{ACFD656F-57F8-4E43-BCA8-91765BBF1E31}">
<File Id="fil98A02DF128F00309F1A943D07AB055C3" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\basic-languages\yaml\yaml.js" />
</Component>
<Component Id="cmp20A5B542971DE9DA8D644A61420785F9" Directory="dirF07B2D247178B70BDB211F65EFFEFC96" Guid="{14DF39F6-D263-45D6-8235-C8C2635E45DE}">
<File Id="fil4739DC27D1A7C65663FBDE2445A60560" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\editor\editor.main.css" />
</Component>
<Component Id="cmpF1CC644B2CA40B09F8FA699359C1771E" Directory="dirF07B2D247178B70BDB211F65EFFEFC96" Guid="{E0A66B93-1A8E-4251-B1B3-7DC973FAC818}">
<File Id="fil16DAD4259A7A7AACD322B6C0FB7B9188" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\editor\editor.main.js" />
</Component>
<Component Id="cmp8FE1FFC5A8CA470AC90BA429584868CD" Directory="dirF07B2D247178B70BDB211F65EFFEFC96" Guid="{E370B8C3-D021-480F-9DC2-6922FDE68AD5}">
<File Id="fil5EA84511D355AC43A8D6C5723FAF9A11" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\editor\editor.main.nls.de.js" />
</Component>
<Component Id="cmp8D6D24BF81A453DC275C6893913D7CAE" Directory="dirF07B2D247178B70BDB211F65EFFEFC96" Guid="{0EC15B09-ED76-4B76-91D6-237B6771A764}">
<File Id="filF4B3065C0890DB56CED7793E6A837BA1" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\editor\editor.main.nls.es.js" />
</Component>
<Component Id="cmp3E42A2ACE7311946156242474BC9E156" Directory="dirF07B2D247178B70BDB211F65EFFEFC96" Guid="{EE52EC17-6585-48FA-B7E3-17F82B85FFD9}">
<File Id="fil67314B5BC24A48D3440DD4F6CB19A037" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\editor\editor.main.nls.fr.js" />
</Component>
<Component Id="cmp0F26375C9575FA3423D86623177E0CA5" Directory="dirF07B2D247178B70BDB211F65EFFEFC96" Guid="{CF395178-63EC-4BF5-A530-0F7CBFBF85F5}">
<File Id="fil34831777C73B6FE2CFFF44AE70DF5BE8" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\editor\editor.main.nls.it.js" />
</Component>
<Component Id="cmp96CC2FC806BC069747C7CA85FB47A6DA" Directory="dirF07B2D247178B70BDB211F65EFFEFC96" Guid="{B848EBE1-B89A-4CA5-A79D-9E7956412807}">
<File Id="filC145FC2C50442F939AD2D4298A82277A" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\editor\editor.main.nls.ja.js" />
</Component>
<Component Id="cmp70B74230CB60AA5841BB5B1A1EDB5C99" Directory="dirF07B2D247178B70BDB211F65EFFEFC96" Guid="{B8002CB8-CD6D-4A5F-A748-10B445905DF9}">
<File Id="filCB8B958A25BE666A507F1E2C44B5C8CD" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\editor\editor.main.nls.js" />
</Component>
<Component Id="cmp1569D2545DA5756B7AF09D6E24571D1A" Directory="dirF07B2D247178B70BDB211F65EFFEFC96" Guid="{D79019DD-DBB9-4CE2-A885-5670633EB193}">
<File Id="fil44E03FF0B6C591FDB72B6AF9054FA050" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\editor\editor.main.nls.ko.js" />
</Component>
<Component Id="cmp4BC7AA05FBB35E2D887B52238A974E99" Directory="dirF07B2D247178B70BDB211F65EFFEFC96" Guid="{76B6398D-B72B-4EBF-B9EB-9DBE737EF78C}">
<File Id="filC86EE71A7791F90B66091FC42E34E279" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\editor\editor.main.nls.ru.js" />
</Component>
<Component Id="cmp87D284043D62B973564C789AC38E6232" Directory="dirF07B2D247178B70BDB211F65EFFEFC96" Guid="{6452D6C6-BCAA-43F3-A01E-9337C16AB7E7}">
<File Id="fil6C7FBC6268BD04DF266FB5E7AE2D3BB1" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\editor\editor.main.nls.zh-cn.js" />
</Component>
<Component Id="cmp8C7329BF067B79A18D1F270A135AFAE7" Directory="dirF07B2D247178B70BDB211F65EFFEFC96" Guid="{3BF2DF38-0264-4BF1-ACE6-E1E7376FED44}">
<File Id="fil45B4CFBBF26E182D02106C9D4AB01F60" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\editor\editor.main.nls.zh-tw.js" />
</Component>
<Component Id="cmp11EBB7AA4D55CD187B31159D117A3AA3" Directory="dir22A893114234A222604F944F124359F2" Guid="{B3F7D617-1CCF-44AE-B2D4-34FCBDFE628C}">
<File Id="filE5B71FD2217B247614C6F7E37FD58701" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\language\css\cssMode.js" />
</Component>
<Component Id="cmpD8D409B0DE3406F70BD754B0C89C9E48" Directory="dir22A893114234A222604F944F124359F2" Guid="{4045DFDD-34C4-4276-887B-6121A9E3A4C1}">
<File Id="fil7CB23C78A8B99F4CBB1E7283F9C4560C" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\language\css\cssWorker.js" />
</Component>
<Component Id="cmp20B9B5FDC82CF72BE81A885B68083A84" Directory="dir35A51C99DC1F92887D6C6744ED281FD4" Guid="{0EF8853A-D0AC-4171-B369-8D3FE4CE1C5E}">
<File Id="fil33BC2F92999250551F7CA976EEC0B6ED" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\language\html\htmlMode.js" />
</Component>
<Component Id="cmp2F3449798999F976A2DD749FB80E707B" Directory="dir35A51C99DC1F92887D6C6744ED281FD4" Guid="{8F14586D-014E-440A-AB7B-CBBED9C9CBA8}">
<File Id="fil465C7EA3B363555AD0233D4868CF4EEB" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\language\html\htmlWorker.js" />
</Component>
<Component Id="cmp722E7E41526C963DBDE2532CCC5CC536" Directory="dirB72201FCDD6F74DCCB7C3D7363F744FA" Guid="{75F16396-FE08-4C3F-BE97-A38A89C117D6}">
<File Id="fil7F0AD8712803D096A85B1164E1715A28" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\language\json\jsonMode.js" />
</Component>
<Component Id="cmp53E4833864E8220F264CF746988DAC14" Directory="dirB72201FCDD6F74DCCB7C3D7363F744FA" Guid="{4C2B0771-E155-4A3D-A035-129A480EB04B}">
<File Id="filEB1AB67CFA3EF36EF44A0FFA3F8EFE25" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\language\json\jsonWorker.js" />
</Component>
<Component Id="cmp7AF798BEB756EB97B517CDCE9CF86AE9" Directory="dir03E77505A5D8EF35AB68BDCC15BFA1E9" Guid="{E732F4FD-4EAB-41BB-9CBF-2F52A61A7EEC}">
<File Id="filCECB815DB64DFE38BB4B90B881852BFC" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\language\typescript\tsMode.js" />
</Component>
<Component Id="cmp3F09647B702F5ED8BB82F951A49BC992" Directory="dir03E77505A5D8EF35AB68BDCC15BFA1E9" Guid="{CE5750C3-472F-4209-BA06-51C1BF7D1301}">
<File Id="filEBE60190891E94F311FA7D42A3986EF0" KeyPath="yes" Source="$(var.MonacoSRCHarvestPath)\min\vs\language\typescript\tsWorker.js" />
</Component>
</ComponentGroup>
</Fragment>
<Fragment>
<DirectoryRef Id="dirEC30CB8F9559AADF029B8A794F7B3C25">
<Directory Id="dir00D56363696DE914F9B5833697CE6982" Name="razor" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dir70DCD0AEE58916DD3148EADC4C276EFB">
<Directory Id="dir03E77505A5D8EF35AB68BDCC15BFA1E9" Name="typescript" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirEC30CB8F9559AADF029B8A794F7B3C25">
<Directory Id="dir05BEFA701AFF555CBB0C575C4A8042DD" Name="tcl" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirEC30CB8F9559AADF029B8A794F7B3C25">
<Directory Id="dir06601F6D5A3F9D7D60424F5E09524DB4" Name="julia" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirEC30CB8F9559AADF029B8A794F7B3C25">
<Directory Id="dir08D93211F4F28EB69AAB12C06A0A2717" Name="hcl" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirEC30CB8F9559AADF029B8A794F7B3C25">
<Directory Id="dir09029A378D1F2B1CB5245A0926BB01B5" Name="go" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirEC30CB8F9559AADF029B8A794F7B3C25">
<Directory Id="dir0D808593278731C2A8A5E3579964B030" Name="handlebars" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirE1F2A63D54A51EDB0B3C0410B469CB2F">
<Directory Id="dir1073A77D6A6F9C3BD868895BC0D2BB43" Name="worker" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirEC30CB8F9559AADF029B8A794F7B3C25">
<Directory Id="dir11500149D13F58C29A933FFBCF7AE831" Name="cameligo" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirE1F2A63D54A51EDB0B3C0410B469CB2F">
<Directory Id="dir1528D3D2EC9AB2C3DF03F6D6FECF40E4" Name="browser" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirEC30CB8F9559AADF029B8A794F7B3C25">
<Directory Id="dir1670BA97A7F3BB1471DA99A5F0DDF616" Name="rust" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirEC30CB8F9559AADF029B8A794F7B3C25">
<Directory Id="dir1DC625A0C557A53F30B2B2778AC20EAC" Name="coffee" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirEC30CB8F9559AADF029B8A794F7B3C25">
<Directory Id="dir1EEEE401A815DC23AF03E7CAB9B69E8A" Name="shell" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirEC30CB8F9559AADF029B8A794F7B3C25">
<Directory Id="dir1FCD208725F3AED0B959B9B5B5206392" Name="m3" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dir70DCD0AEE58916DD3148EADC4C276EFB">
<Directory Id="dir22A893114234A222604F944F124359F2" Name="css" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirEC30CB8F9559AADF029B8A794F7B3C25">
<Directory Id="dir23EA2EDA8657328B2431358EE85819C3" Name="yaml" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirEC30CB8F9559AADF029B8A794F7B3C25">
<Directory Id="dir25A1924A74C6AC9A29661F8183830092" Name="pla" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirEC30CB8F9559AADF029B8A794F7B3C25">
<Directory Id="dir2757105AED061CB6E7A811A59041E70B" Name="objective-c" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dir35CBE4A6B59B8A2A1409DC9DB79DD42A">
<Directory Id="dir275B90E50E8463E5A7FE8E4490177655" Name="worker" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirEC30CB8F9559AADF029B8A794F7B3C25">
<Directory Id="dir28FFEB82009147C6884C2EC55E931EF0" Name="xml" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirEC30CB8F9559AADF029B8A794F7B3C25">
<Directory Id="dir290B934CDF26049203FDCD68940E9A56" Name="html" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirEC30CB8F9559AADF029B8A794F7B3C25">
<Directory Id="dir2D09B3341172E78CED634088E3A0F0D6" Name="scheme" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirEC30CB8F9559AADF029B8A794F7B3C25">
<Directory Id="dir2DADC716DFBEA6EC858374A8DE4A55BF" Name="cpp" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirEC30CB8F9559AADF029B8A794F7B3C25">
<Directory Id="dir2DAF129901E8E61B5F28D8764B2A53EC" Name="pascal" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirEC30CB8F9559AADF029B8A794F7B3C25">
<Directory Id="dir32E14839B1A40DAE7351CDB5201D0D6B" Name="ini" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirEC30CB8F9559AADF029B8A794F7B3C25">
<Directory Id="dir3428A3B09088B4D43D3C5D04E265CE5B" Name="bicep" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dir70DCD0AEE58916DD3148EADC4C276EFB">
<Directory Id="dir35A51C99DC1F92887D6C6744ED281FD4" Name="html" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirE1F2A63D54A51EDB0B3C0410B469CB2F">
<Directory Id="dir35CBE4A6B59B8A2A1409DC9DB79DD42A" Name="common" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirEC30CB8F9559AADF029B8A794F7B3C25">
<Directory Id="dir36C13CDE80473EDC55B5B2B9A4585964" Name="systemverilog" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirEC30CB8F9559AADF029B8A794F7B3C25">
<Directory Id="dir3A749E768458D7BDB7E8A3619C9DBF19" Name="qsharp" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirEC30CB8F9559AADF029B8A794F7B3C25">
<Directory Id="dir3AA5BCBFC2ED6DF8EE8F6DFED0E130D8" Name="wgsl" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirEC30CB8F9559AADF029B8A794F7B3C25">
<Directory Id="dir4365498E48631EE6110E707C908F23E5" Name="perl" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirEC30CB8F9559AADF029B8A794F7B3C25">
<Directory Id="dir4384234FF105D9CE96FF8F90EFD7A008" Name="flow9" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirEC30CB8F9559AADF029B8A794F7B3C25">
<Directory Id="dir44B4D4584FD02BDBAD15EAA2FF9C3081" Name="css" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirEC30CB8F9559AADF029B8A794F7B3C25">
<Directory Id="dir45D8F9637E749259F3D09F01185CB277" Name="mips" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirEC30CB8F9559AADF029B8A794F7B3C25">
<Directory Id="dir4EDA420ECFFAE101E961F38C239F9924" Name="freemarker2" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirEC30CB8F9559AADF029B8A794F7B3C25">
<Directory Id="dir52852EA262AF9E52EAAFE3C91C7E5AAB" Name="st" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirEC30CB8F9559AADF029B8A794F7B3C25">
<Directory Id="dir55FBC962119473511EA55883EE255033" Name="pug" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirEC30CB8F9559AADF029B8A794F7B3C25">
<Directory Id="dir5816A6FCDB97E961BF867F179E019F5C" Name="solidity" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirEC30CB8F9559AADF029B8A794F7B3C25">
<Directory Id="dir59061104B938DAD5AB82F8269BF9A5CC" Name="ruby" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirEC30CB8F9559AADF029B8A794F7B3C25">
<Directory Id="dir5D94AAB564D15FAF0AD003A873C6E880" Name="mdx" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirEC30CB8F9559AADF029B8A794F7B3C25">
<Directory Id="dir5F323D10C8C8A75A64FA7C89D96680EC" Name="javascript" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirEC30CB8F9559AADF029B8A794F7B3C25">
<Directory Id="dir5FB0D3CBAA8948CFB2EA580D00694174" Name="cypher" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirEC30CB8F9559AADF029B8A794F7B3C25">
<Directory Id="dir6358A938D9D11E471FFB3DA2ADAD7BCB" Name="markdown" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirEC30CB8F9559AADF029B8A794F7B3C25">
<Directory Id="dir6731A8985A5C5FB88A9B2E2E504176AB" Name="redshift" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirEC30CB8F9559AADF029B8A794F7B3C25">
<Directory Id="dir6E11C98F7CEAF38791F199EF7D6C5A9C" Name="vb" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirEC30CB8F9559AADF029B8A794F7B3C25">
<Directory Id="dir70381AED3CC1DDCE84DA393FA084DF30" Name="kotlin" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirB6981C7877773C58E1AF6BDA6BA6F65E">
<Directory Id="dir70DCD0AEE58916DD3148EADC4C276EFB" Name="language" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirEC30CB8F9559AADF029B8A794F7B3C25">
<Directory Id="dir71C05CEF79E7873797404DB7FA624782" Name="less" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirEC30CB8F9559AADF029B8A794F7B3C25">
<Directory Id="dir73ABE26EA37698BE7A3BB7464BCC549A" Name="php" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirEC30CB8F9559AADF029B8A794F7B3C25">
<Directory Id="dir76484A3A9306229E678FD42F61E4FB4C" Name="python" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirEC30CB8F9559AADF029B8A794F7B3C25">
<Directory Id="dir78E5143BB991015ABB2B126B33DF20F3" Name="azcli" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirEC30CB8F9559AADF029B8A794F7B3C25">
<Directory Id="dir7BBE99088AD794540115669A678F7B57" Name="pgsql" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirEC30CB8F9559AADF029B8A794F7B3C25">
<Directory Id="dir7FC34AF4DF60585C05AF245B0976DB1A" Name="graphql" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirEC30CB8F9559AADF029B8A794F7B3C25">
<Directory Id="dir827C0A5B3A46EFF9ED86626CA8E09FEB" Name="lexon" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirEC30CB8F9559AADF029B8A794F7B3C25">
<Directory Id="dir88BB0F9F45F25EA2B8BD2B169E47C6C3" Name="pascaligo" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirEC30CB8F9559AADF029B8A794F7B3C25">
<Directory Id="dir8F4676CBA9C11989C570D9760FDB6D14" Name="clojure" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirEC30CB8F9559AADF029B8A794F7B3C25">
<Directory Id="dir9251D6B5581D4133030A9129421E5255" Name="restructuredtext" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirEC30CB8F9559AADF029B8A794F7B3C25">
<Directory Id="dir94109FFBE73954C2E3D9560E43A94392" Name="sophia" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dir1528D3D2EC9AB2C3DF03F6D6FECF40E4">
<Directory Id="dir94C8AABAD397D84885173B63F0FDC679" Name="ui" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dir9DB9B0E8B08A1BA65AFAEFC2FA10E30A">
<Directory Id="dir977D270DC116F38F1B9320DA90FDF824" Name="codicon" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirEC30CB8F9559AADF029B8A794F7B3C25">
<Directory Id="dir97DF6B0B0AC776C7AA8A3B17483E6B88" Name="liquid" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirEC30CB8F9559AADF029B8A794F7B3C25">
<Directory Id="dir98CCF277B8D261E44E72D2436AE03A17" Name="dart" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirEC30CB8F9559AADF029B8A794F7B3C25">
<Directory Id="dir9913F0276DC804D55443ED170B33897B" Name="elixir" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirEC30CB8F9559AADF029B8A794F7B3C25">
<Directory Id="dir9BDD3DD06D0AE947DFAB4ECE8AED417A" Name="csp" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dir94C8AABAD397D84885173B63F0FDC679">
<Directory Id="dir9DB9B0E8B08A1BA65AFAEFC2FA10E30A" Name="codicons" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirEC30CB8F9559AADF029B8A794F7B3C25">
<Directory Id="dir9FBB158AFDA9A66E220286D4F2609E71" Name="twig" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirEC30CB8F9559AADF029B8A794F7B3C25">
<Directory Id="dirA17168CDD8EEFA01087350F05246840B" Name="postiats" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirEC30CB8F9559AADF029B8A794F7B3C25">
<Directory Id="dirA5D6CA3E903645EA55097ED025FDC806" Name="apex" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirEC30CB8F9559AADF029B8A794F7B3C25">
<Directory Id="dirB0AC1BF5C32B8286A676408C25A61765" Name="protobuf" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirEC30CB8F9559AADF029B8A794F7B3C25">
<Directory Id="dirB5EF435C30BEC37ACFF774928750D156" Name="sql" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirF3D9892E484C03D885D33EEA40EF87C2">
<Directory Id="dirB6981C7877773C58E1AF6BDA6BA6F65E" Name="vs" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dir70DCD0AEE58916DD3148EADC4C276EFB">
<Directory Id="dirB72201FCDD6F74DCCB7C3D7363F744FA" Name="json" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirEC30CB8F9559AADF029B8A794F7B3C25">
<Directory Id="dirBB7633031785DFA55795107B6D149163" Name="bat" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirEC30CB8F9559AADF029B8A794F7B3C25">
<Directory Id="dirBEAA75EFDD04A1C0A9B19D70DD4732C1" Name="r" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirEC30CB8F9559AADF029B8A794F7B3C25">
<Directory Id="dirBF1FE658716DC862C9477F47E3EE0E9C" Name="powerquery" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirEC30CB8F9559AADF029B8A794F7B3C25">
<Directory Id="dirC315087738325C868107A7E7D0D4CAEF" Name="sparql" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirEC30CB8F9559AADF029B8A794F7B3C25">
<Directory Id="dirD421FCD5A3C6885202E25032B144CBC0" Name="scss" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirEC30CB8F9559AADF029B8A794F7B3C25">
<Directory Id="dirD6C83E20CEBD48927A1B999FC29D10D5" Name="java" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirEC30CB8F9559AADF029B8A794F7B3C25">
<Directory Id="dirDC0D8D61976CD9114B598B3D7BC3A75E" Name="fsharp" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirEC30CB8F9559AADF029B8A794F7B3C25">
<Directory Id="dirDE2C1CBE313A17238E2151D374450794" Name="swift" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirB6981C7877773C58E1AF6BDA6BA6F65E">
<Directory Id="dirE1F2A63D54A51EDB0B3C0410B469CB2F" Name="base" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirEC30CB8F9559AADF029B8A794F7B3C25">
<Directory Id="dirE449AC0C719DDD618B136F9380896803" Name="ecl" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirEC30CB8F9559AADF029B8A794F7B3C25">
<Directory Id="dirE4E212383E30441F1F43B3FCB74DDD2E" Name="csharp" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirEC30CB8F9559AADF029B8A794F7B3C25">
<Directory Id="dirE518C878E428E98585AE9C7E7A5B2742" Name="lua" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirEC30CB8F9559AADF029B8A794F7B3C25">
<Directory Id="dirE82FE5B1199EBD2FB6D6CB51A54FDBF1" Name="mysql" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirEC30CB8F9559AADF029B8A794F7B3C25">
<Directory Id="dirE97385D326929F1063C2ECE2A2291160" Name="sb" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirB6981C7877773C58E1AF6BDA6BA6F65E">
<Directory Id="dirEC30CB8F9559AADF029B8A794F7B3C25" Name="basic-languages" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirEC30CB8F9559AADF029B8A794F7B3C25">
<Directory Id="dirECE9BA50EABF810E2043B3CAB8D50EFF" Name="scala" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirEC30CB8F9559AADF029B8A794F7B3C25">
<Directory Id="dirEEBBE2EAD2FF3D7241AB0246E0F2EE59" Name="dockerfile" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirEC30CB8F9559AADF029B8A794F7B3C25">
<Directory Id="dirEEBD553161A5477464565F0AA9C66A4E" Name="msdax" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirEC30CB8F9559AADF029B8A794F7B3C25">
<Directory Id="dirEEC36D6CE0850FD998425DA64003EF71" Name="abap" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirB6981C7877773C58E1AF6BDA6BA6F65E">
<Directory Id="dirF07B2D247178B70BDB211F65EFFEFC96" Name="editor" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirEC30CB8F9559AADF029B8A794F7B3C25">
<Directory Id="dirF0808D745B8F1D84EC3E766DED71F25D" Name="powershell" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirEC30CB8F9559AADF029B8A794F7B3C25">
<Directory Id="dirF551ED8D7A1A57AEAD472CE945460F44" Name="typescript" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirEC30CB8F9559AADF029B8A794F7B3C25">
<Directory Id="dirFC530128ACFC59ECC74A19B7BB5EA51E" Name="redis" />
</DirectoryRef>
</Fragment>
</Wix>

View File

@@ -0,0 +1,17 @@
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:Fire="http://wixtoolset.org/schemas/v4/wxs/firewall">
<?include $(sys.CURRENTDIR)\Common.wxi?>
<Fragment>
<ComponentGroup Id="MouseWithoutBordersComponentGroup">
<Component Id="MouseWithoutBordersFirewallComponent" Directory="INSTALLFOLDER" Guid="FEA59459-EC0E-4636-8E76-4C168235982B">
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys\components">
<RegistryValue Type="string" Name="MouseWithoutBordersFirewall_Component" Value="" KeyPath="yes" />
</RegistryKey>
<!-- The program name used here will be generated by generateFileComponents.ps1 -->
<Fire:FirewallException Id="MouseWithoutBordersFirewallException1" Name="PowerToys.MouseWithoutBorders" Scope="localSubnet" IgnoreFailure="yes" Program="[#BaseApplicationsFiles_File_PowerToys.MouseWithoutBorders.exe]" />
</Component>
</ComponentGroup>
</Fragment>
</Wix>

View File

@@ -0,0 +1,85 @@
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
<?include $(sys.CURRENTDIR)\Common.wxi?>
<?define NewPlusAssetsFiles=?>
<?define NewPlusAssetsFilesPath=$(var.BinDir)WinUI3Apps\Assets\NewPlus\?>
<?define NewPlusTemplateFilesPath=$(var.BinDir)WinUI3Apps\Assets\NewPlus\Templates\?>
<?define NewPlusTemplateSubFilesPath=$(var.BinDir)WinUI3Apps\Assets\NewPlus\Templates\Example folder\?>
<Fragment>
<!-- Assets -->
<DirectoryRef Id="WinUI3AppsAssetsFolder">
<Directory Id="NewPlusAssetsInstallFolder" Name="NewPlus" />
</DirectoryRef>
<DirectoryRef Id="NewPlusAssetsInstallFolder" FileSource="$(var.NewPlusAssetsFilesPath)">
<!-- Generated by generateFileComponents.ps1 -->
<!--NewPlusAssetsFiles_Component_Def-->
<!-- NewPlus Shell Extension for Win10 registration -->
<Component Id="NewPlus_ShellExtension_win10" Guid="D5456D4A-6EEC-4B85-944D-6A6A4A74FFA6" Bitness="always64">
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\CLSID\{FF90D477-E32A-4BE8-8CC5-A502A97F5401}">
<RegistryValue Type="string" Value="NewPlus Shell Extension Win10" />
<RegistryValue Type="string" Name="ContextMenuOptIn" Value="" />
<RegistryValue Type="string" Key="InprocServer32" Value="[WinUI3AppsInstallFolder]PowerToys.NewPlus.ShellExtension.win10.dll" />
<RegistryValue Type="string" Key="InprocServer32" Name="ThreadingModel" Value="Apartment" />
</RegistryKey>
<RegistryKey Root="$(var.RegistryScope)" Key="SOFTWARE\Classes\Directory\background\ShellEx\ContextMenuHandlers\NewPlusShellExtensionWin10">
<RegistryValue Type="string" Value="{FF90D477-E32A-4BE8-8CC5-A502A97F5401}" />
</RegistryKey>
</Component>
</DirectoryRef>
<ComponentGroup Id="NewPlusComponentGroup">
<Component Id="RemoveNewPlusFolder" Guid="4189C789-56EB-409D-912E-3F4F3F4F1FFA" Directory="NewPlusAssetsInstallFolder">
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys\components">
<RegistryValue Type="string" Name="RemoveNewPlusFolder" Value="" KeyPath="yes" />
</RegistryKey>
<RemoveFolder Id="RemoveFolderNewPlusAssetsFolder" Directory="NewPlusAssetsInstallFolder" On="uninstall" />
</Component>
<ComponentRef Id="NewPlus_ShellExtension_win10" />
</ComponentGroup>
<!-- Example templates -->
<DirectoryRef Id="WinUI3AppsAssetsFolder">
<Directory Id="NewPlusInstallFolder" Name="NewPlus">
<Directory Id="NewPlusTemplatesInstallFolder" Name="Templates">
<Directory Id="NewPlusTemplatesSubInstallFolder" Name="Example folder" />
</Directory>
</Directory>
</DirectoryRef>
<DirectoryRef Id="NewPlusTemplatesInstallFolder" FileSource="$(var.NewPlusTemplateFilesPath)">
<Component Id="NewPlusTemplateFiles_Component" Guid="39264075-4B7F-40E3-A76F-21E68576D43E" Bitness="always64">
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys\components">
<RegistryValue Type="string" Name="NewPlusTemplateFiles_Component" Value="" KeyPath="yes" />
</RegistryKey>
<File Id="NewPlusTemplateFiles_File_1.md" Source="$(var.NewPlusTemplateFilesPath)Any files or folders placed in the template folder are available via New+.txt" />
</Component>
</DirectoryRef>
<DirectoryRef Id="NewPlusTemplatesSubInstallFolder" FileSource="$(var.NewPlusTemplateSubFilesPath)">
<Component Id="NewPlusTemplateSubFiles_Component" Guid="7618E61C-CCB8-492F-B284-E1AE2954AF0B" Bitness="always64">
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys\components">
<RegistryValue Type="string" Name="NewPlusTemplateSubFiles_Component" Value="" KeyPath="yes" />
</RegistryKey>
<File Id="NewPlusTemplateSubFiles_File_1.md" Source="$(var.NewPlusTemplateSubFilesPath)Example txt file.txt" />
<File Id="NewPlusTemplateSubFiles_File_2.md" Source="$(var.NewPlusTemplateSubFilesPath)Another example txt file.txt" />
</Component>
</DirectoryRef>
<ComponentGroup Id="NewPlusTemplatesComponentGroup">
<Component Id="RemoveNewPlusTemplateFolder" Guid="3E9B15CA-A50C-42DA-977F-5E9914562FE7" Directory="NewPlusInstallFolder">
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys\components">
<RegistryValue Type="string" Name="RemoveNewPlusTemplateFolder" Value="" KeyPath="yes" />
</RegistryKey>
<RemoveFolder Id="RemoveFolderNewPlusInstallFolder" Directory="NewPlusInstallFolder" On="uninstall" />
<RemoveFolder Id="RemoveFolderNewPlusTemplatesInstallFolder" Directory="NewPlusTemplatesInstallFolder" On="uninstall" />
<RemoveFolder Id="RemoveFolderNewPlusTemplatesSubInstallFolder" Directory="NewPlusTemplatesSubInstallFolder" On="uninstall" />
</Component>
<ComponentRef Id="NewPlusTemplateFiles_Component" />
<ComponentRef Id="NewPlusTemplateSubFiles_Component" />
</ComponentGroup>
</Fragment>
</Wix>

View File

@@ -0,0 +1,27 @@
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
<?include $(sys.CURRENTDIR)\Common.wxi?>
<?define PeekAssetsFiles=?>
<?define PeekAssetsFilesPath=$(var.BinDir)WinUI3Apps\Assets\Peek\?>
<Fragment>
<DirectoryRef Id="WinUI3AppsAssetsFolder">
<Directory Id="PeekAssetsFolder" Name="Peek" />
</DirectoryRef>
<DirectoryRef Id="PeekAssetsFolder" FileSource="$(var.PeekAssetsFilesPath)">
<!-- Generated by generateFileComponents.ps1 -->
<!--PeekAssetsFiles_Component_Def-->
</DirectoryRef>
<ComponentGroup Id="PeekComponentGroup">
<Component Id="RemovePeekFolder" Guid="EF9422D7-FF0A-4887-968A-E61B53ACD23A" Directory="PeekAssetsFolder">
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys\components">
<RegistryValue Type="string" Name="RemovePeekFolder" Value="" KeyPath="yes" />
</RegistryKey>
<RemoveFolder Id="RemoveFolderPeekAssetsFolder" Directory="PeekAssetsFolder" On="uninstall" />
</Component>
</ComponentGroup>
</Fragment>
</Wix>

View File

@@ -0,0 +1,44 @@
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
<?include $(sys.CURRENTDIR)\Common.wxi?>
<?define PowerRenameAssetsFiles=?>
<?define PowerRenameAssetsFilesPath=$(var.BinDir)WinUI3Apps\Assets\PowerRename\?>
<Fragment>
<DirectoryRef Id="WinUI3AppsAssetsFolder">
<Directory Id="PowerRenameAssetsFolder" Name="PowerRename" />
</DirectoryRef>
<DirectoryRef Id="PowerRenameAssetsFolder" FileSource="$(var.PowerRenameAssetsFilesPath)">
<!-- Generated by generateFileComponents.ps1 -->
<!--PowerRenameAssetsFiles_Component_Def-->
<!-- !Warning! Make sure to change Component Guid if you update something here -->
<Component Id="Module_PowerRename" Guid="40D43079-240E-402D-8CE8-571BFFA71175" Bitness="always64">
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\CLSID\{0440049F-D1DC-4E46-B27B-98393D79486B}">
<RegistryValue Type="string" Value="PowerRename Shell Extension" />
<RegistryValue Type="string" Name="ContextMenuOptIn" Value="" />
<RegistryValue Type="string" Key="InprocServer32" Value="[WinUI3AppsInstallFolder]PowerToys.PowerRenameExt.dll" />
<RegistryValue Type="string" Key="InprocServer32" Name="ThreadingModel" Value="Apartment" />
</RegistryKey>
<RegistryKey Root="$(var.RegistryScope)" Key="SOFTWARE\Classes\AllFileSystemObjects\ShellEx\ContextMenuHandlers\PowerRenameExt">
<RegistryValue Type="string" Value="{0440049F-D1DC-4E46-B27B-98393D79486B}" />
</RegistryKey>
<RegistryKey Root="$(var.RegistryScope)" Key="SOFTWARE\Classes\Directory\background\ShellEx\ContextMenuHandlers\PowerRenameExt">
<RegistryValue Type="string" Value="{0440049F-D1DC-4E46-B27B-98393D79486B}" />
</RegistryKey>
</Component>
</DirectoryRef>
<ComponentGroup Id="PowerRenameComponentGroup">
<Component Id="RemovePowerRenameFolder" Guid="2028549B-02E3-4D80-BC3F-59AEA37AC73D" Directory="PowerRenameAssetsFolder">
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys\components">
<RegistryValue Type="string" Name="RemovePowerRenameFolder" Value="" KeyPath="yes" />
</RegistryKey>
<RemoveFolder Id="RemoveFolderPowerRenameAssetsFolder" Directory="PowerRenameAssetsFolder" On="uninstall" />
</Component>
<ComponentRef Id="Module_PowerRename" />
</ComponentGroup>
</Fragment>
</Wix>

View File

@@ -0,0 +1,55 @@
<?define UpgradeCode="6341382d-c0a9-4238-9188-be9607e3fab2"?>
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:util="http://wixtoolset.org/schemas/v4/wxs/util" xmlns:bal="http://wixtoolset.org/schemas/v4/wxs/bal">
<?include $(sys.CURRENTDIR)\Common.wxi?>
<Bundle Name="PowerToys (Preview) $(var.PowerToysPlatform)" Version="$(var.Version)" Manufacturer="Microsoft Corporation" IconSourceFile="$(var.BinDir)svgs\icon.ico" UpgradeCode="$(var.UpgradeCode)">
<BootstrapperApplication SourceFile="$(var.Bootstrapper.TargetDir)Bootstrapper.exe" bal:CommandLineVariables="caseInsensitive">
<PayloadGroupRef Id="BA.publish" />
</BootstrapperApplication>
<util:RegistrySearch Variable="HasWebView2PerMachine" Root="HKLM" Key="SOFTWARE\WOW6432Node\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}" Result="exists" />
<util:RegistrySearch Variable="HasWebView2PerUser" Root="HKCU" Key="Software\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}" Result="exists" />
<?if $(var.PerUser) = "true" ?>
<Variable Name="InstallFolder" Type="formatted" Value="[LocalAppDataFolder]PowerToys" bal:Overridable="yes" />
<?else?>
<Variable Name="InstallFolder" Type="formatted" Value="$(var.PlatformProgramFiles)PowerToys" bal:Overridable="yes" />
<?endif?>
<Variable Name="MsiLogFolder" Type="formatted" Value="[LocalAppDataFolder]\Microsoft\PowerToys\" />
<Log Disable="no" Prefix="powertoys-bootstrapper-msi-$(var.Version)" Extension=".log" />
<!-- Only install/upgrade if the version is greater or equal than the currently installed version of PowerToys, to handle the case in which PowerToys was installed from old MSI (before WiX bootstrapper was used) -->
<!-- If the previous installation is a bundle installation, just let WiX run its logic. -->
<Variable Name="MinimumVersion" Type="version" Value="0.0.0.0" />
<Variable Name="TargetPowerToysVersion" Type="version" Value="$(var.Version)" />
<Variable Name="DetectedPowerToysVersion" Type="version" Value="0.0.0.0" />
<Variable Name="DetectedPowerToysUserVersion" Type="version" Value="0.0.0.0" />
<util:ProductSearch Id="SearchInstalledPowerToysVersion" Variable="DetectedPowerToysVersion" UpgradeCode="42B84BF7-5FBF-473B-9C8B-049DC16F7708" Result="version" />
<util:ProductSearch Id="SearchInstalledPowerToysUserVersion" Variable="DetectedPowerToysUserVersion" UpgradeCode="D8B559DB-4C98-487A-A33F-50A8EEE42726" Result="version" />
<?if $(var.PerUser) = "true" ?>
<bal:Condition Message="PowerToys is already installed on this system for all users. We recommend first uninstalling that version before installing this one." Condition="MinimumVersion &gt;= DetectedPowerToysVersion" />
<bal:Condition Message="The same or later version of PowerToys is already installed." Condition="TargetPowerToysVersion &gt;= DetectedPowerToysUserVersion OR WixBundleInstalled" />
<?else?>
<bal:Condition Message="PowerToys is already installed on this system for current user. We recommend first uninstalling that version before installing this one." Condition="MinimumVersion &gt;= DetectedPowerToysUserVersion" />
<bal:Condition Message="A later version of PowerToys is already installed." Condition="TargetPowerToysVersion &gt;= DetectedPowerToysVersion OR WixBundleInstalled" />
<?endif?>
<Variable Name="DetectedWindowsBuildNumber" Type="version" Value="0" />
<util:RegistrySearch Id="SearchWindowsBuildNumber" Root="HKLM" Key="SOFTWARE\Microsoft\Windows NT\CurrentVersion" Value="CurrentBuildNumber" Result="value" Variable="DetectedWindowsBuildNumber" />
<bal:Condition Message="This application is only supported on Windows 10 version v2004 (build 19041) or higher." Condition="DetectedWindowsBuildNumber &gt;= 19041 OR WixBundleInstalled" />
<Chain>
<ExePackage DisplayName="Closing PowerToys application" Name="terminate_powertoys.cmd" Cache="remove" Compressed="yes" Id="TerminatePowerToys" SourceFile="terminate_powertoys.cmd" Permanent="yes" PerMachine="$(var.PerMachineYesNo)" Vital="no">
</ExePackage>
<ExePackage DisplayName="Microsoft Edge WebView2" Name="MicrosoftEdgeWebview2Setup.exe" Compressed="yes" Id="WebView2" DetectCondition="HasWebView2PerMachine OR HasWebView2PerUser" SourceFile="WebView2\MicrosoftEdgeWebview2Setup.exe" Permanent="yes" PerMachine="$(var.PerMachineYesNo)" InstallArguments="/silent /install" RepairArguments="/repair /passive" UninstallArguments="/silent /uninstall">
</ExePackage>
<MsiPackage DisplayName="PowerToys MSI" SourceFile="$(var.PowerToysPlatform)\Release\$(var.MSIPath)\$(var.MSIName)" Compressed="yes" bal:DisplayInternalUICondition="false">
<MsiProperty Name="BOOTSTRAPPERINSTALLFOLDER" Value="[InstallFolder]" />
</MsiPackage>
</Chain>
</Bundle>
</Wix>

View File

@@ -0,0 +1,71 @@
<Project Sdk="WixToolset.Sdk/5.0.2">
<PropertyGroup>
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
</PropertyGroup>
<PropertyGroup>
<DefineConstants>Version=$(Version)</DefineConstants>
<Name>PowerToysVNextBootstrapper</Name>
</PropertyGroup>
<PropertyGroup Label="UserMacros" Condition=" '$(PerUser)' == 'true' ">
<DefineConstants>$(DefineConstants);PerUser=true</DefineConstants>
</PropertyGroup>
<PropertyGroup Label="UserMacros" Condition=" '$(PerUser)' != 'true' ">
<DefineConstants>$(DefineConstants);PerUser=false</DefineConstants>
</PropertyGroup>
<PropertyGroup Label="UserMacros" Condition=" '$(CIBuild)' == 'true' ">
<DefineConstants>$(DefineConstants);CIBuild=true</DefineConstants>
</PropertyGroup>
<PropertyGroup Label="UserMacros" Condition=" '$(CIBuild)' != 'true' ">
<DefineConstants>$(DefineConstants);CIBuild=false</DefineConstants>
</PropertyGroup>
<PropertyGroup>
<Configuration>Release</Configuration>
<Platform Condition="'$(Platform)'=='x64'">x64</Platform>
<Platform Condition="'$(Platform)'!='x64'">arm64</Platform>
<OutputName>PowerToysSetupVNext-$(Version)-$(Platform)</OutputName>
<OutputType>Bundle</OutputType>
<SuppressAclReset>True</SuppressAclReset>
<HarvestDirectoryAdditionalOptions>-generate payloadgroup</HarvestDirectoryAdditionalOptions>
<OutputName Condition=" '$(PerUser)' != 'true' ">PowerToysSetupVNext-$(Version)-$(Platform)</OutputName>
<OutputName Condition=" '$(PerUser)' == 'true' ">PowerToysUserSetupVNext-$(Version)-$(Platform)</OutputName>
<OutputPath Condition=" '$(PerUser)' != 'true' ">$(Platform)\$(Configuration)\MachineSetup</OutputPath>
<OutputPath Condition=" '$(PerUser)' == 'true' ">$(Platform)\$(Configuration)\UserSetup</OutputPath>
<IntermediateOutputPath Condition=" '$(PerUser)' != 'true' ">$(BaseIntermediateOutputPath)$(Platform)\$(Configuration)\MachineSetup</IntermediateOutputPath>
<IntermediateOutputPath Condition=" '$(PerUser)' == 'true' ">$(BaseIntermediateOutputPath)$(Platform)\$(Configuration)\UserSetup</IntermediateOutputPath>
</PropertyGroup>
<ItemGroup>
<BindInputPaths Include="$(MSBuildThisFileDirectory)\Bootstrapper\bin\publish" />
<HarvestDirectory Include="$(MSBuildThisFileDirectory)Bootstrapper\bin\publish">
<DirectoryRefId>BA.publish</DirectoryRefId>
<Transforms>ba.xslt</Transforms>
</HarvestDirectory>
</ItemGroup>
<ItemGroup>
<Compile Include="PowerToys.wxs" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="WixToolset.Util.wixext" />
<PackageReference Include="WixToolset.UI.wixext" />
<PackageReference Include="WixToolset.NetFx.wixext" />
<PackageReference Include="WixToolset.Bal.wixext" />
<PackageReference Include="WixToolset.Heat" />
</ItemGroup>
<ItemGroup>
<Folder Include="CustomDialogs" />
</ItemGroup>
<!-- Prevents NU1503 -->
<Target Name="_IsProjectRestoreSupported" Returns="@(_ValidProjectsForRestore)">
<ItemGroup>
<_ValidProjectsForRestore Include="$(MSBuildProjectFullPath)" />
</ItemGroup>
</Target>
<Target Name="Restore" />
<Target Name="PreBuild" BeforeTargets="PreBuildEvent">
<Message Text="== running dotnet publish for Bootstrapper ==" Importance="high" />
<Exec Command="dotnet publish &quot;$(MSBuildThisFileDirectory)\Bootstrapper\Bootstrapper.csproj&quot; -o &quot;$(MSBuildThisFileDirectory)\Bootstrapper\bin\publish&quot; -c $(Configuration) --self-contained true" />
</Target>
<PropertyGroup>
<BootstrapperPublishDir>$(MSBuildThisFileDirectory)Bootstrapper\bin\publish\</BootstrapperPublishDir>
<DefineConstants>$(DefineConstants);Bootstrapper.TargetDir=$(BootstrapperPublishDir)</DefineConstants>
</PropertyGroup>
</Project>

View File

@@ -0,0 +1,169 @@
<Project Sdk="WixToolset.Sdk/5.0.2">
<Import Project="..\..\src\CmdPalVersion.props" Condition="Exists('..\..\src\CmdPalVersion.props')" />
<PropertyGroup>
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
</PropertyGroup>
<PropertyGroup>
<EnableProjectHarvesting>true</EnableProjectHarvesting>
</PropertyGroup>
<PropertyGroup Condition="'$(Platform)' == 'x64'">
<DefineConstants>Version=$(Version);MonacoSRCHarvestPath=$(ProjectDir)..\..\x64\$(Configuration)\Assets\Monaco\monacoSRC;CmdPalVersion=$(CmdPalVersion)</DefineConstants> <!-- THIS IS AN INNER LOOP OPTIMIZATION
The build pipeline builds the Settings and Launcher projects for Publication
using a specific profile. If you're doing local installer builds, this will
simulate the build pipeline doing that for you. -->
<PreBuildEvent>IF NOT DEFINED IsPipeline (
call "$([MSBuild]::GetVsInstallRoot())\Common7\Tools\VsDevCmd.bat" -arch=amd64 -host_arch=amd64 -winsdk=10.0.19041.0 -vcvars_ver=$(VCToolsVersion)
SET PTRoot=$(SolutionDir)\..
call "..\..\..\publish.cmd" x64
)
call powershell.exe -NonInteractive -executionpolicy Unrestricted -File $(MSBuildThisFileDirectory)\generateMonacoWxs.ps1 -monacoWxsFile "$(MSBuildThisFileDirectory)\MonacoSRC.wxs"
</PreBuildEvent>
</PropertyGroup>
<PropertyGroup Condition="'$(Platform)' != 'x64'">
<DefineConstants>Version=$(Version);MonacoSRCHarvestPath=$(ProjectDir)..\..\ARM64\$(Configuration)\Assets\Monaco\monacoSRC;CmdPalVersion=$(CmdPalVersion);</DefineConstants>
<PreBuildEvent>IF NOT DEFINED IsPipeline (
call "$([MSBuild]::GetVsInstallRoot())\Common7\Tools\VsDevCmd.bat" -arch=arm64 -host_arch=amd64 -winsdk=10.0.19041.0 -vcvars_ver=$(VCToolsVersion)
SET PTRoot=$(SolutionDir)\..
call "..\..\..\publish.cmd" arm64
)
call powershell.exe -NonInteractive -executionpolicy Unrestricted -File $(MSBuildThisFileDirectory)\generateMonacoWxs.ps1 -monacoWxsFile "$(MSBuildThisFileDirectory)\MonacoSRC.wxs"
</PreBuildEvent>
</PropertyGroup>
<PropertyGroup>
<RunPostBuildEvent>Always</RunPostBuildEvent>
<PostBuildEvent>
call move /Y ..\..\..\AdvancedPaste.wxs.bk ..\..\..\AdvancedPaste.wxs
call move /Y ..\..\..\Awake.wxs.bk ..\..\..\Awake.wxs
call move /Y ..\..\..\BaseApplications.wxs.bk ..\..\..\BaseApplications.wxs
call move /Y ..\..\..\CmdPal.wxs.bk ..\..\..\CmdPal.wxs
call move /Y ..\..\..\ColorPicker.wxs.bk ..\..\..\ColorPicker.wxs
call move /Y ..\..\..\Core.wxs.bk ..\..\..\Core.wxs
call move /Y ..\..\..\EnvironmentVariables.wxs.bk ..\..\..\EnvironmentVariables.wxs
call move /Y ..\..\..\FileExplorerPreview.wxs.bk ..\..\..\FileExplorerPreview.wxs
call move /Y ..\..\..\FileLocksmith.wxs.bk ..\..\..\FileLocksmith.wxs
call move /Y ..\..\..\Hosts.wxs.bk ..\..\..\Hosts.wxs
call move /Y ..\..\..\ImageResizer.wxs.bk ..\..\..\ImageResizer.wxs
call move /Y ..\..\..\KeyboardManager.wxs.bk ..\..\..\KeyboardManager.wxs
call move /Y ..\..\..\MouseWithoutBorders.wxs.bk ..\..\..\MouseWithoutBorders.wxs
call move /Y ..\..\..\NewPlus.wxs.bk ..\..\..\NewPlus.wxs
call move /Y ..\..\..\Peek.wxs.bk ..\..\..\Peek.wxs
call move /Y ..\..\..\PowerRename.wxs.bk ..\..\..\PowerRename.wxs
call move /Y ..\..\..\Product.wxs.bk ..\..\..\Product.wxs
call move /Y ..\..\..\RegistryPreview.wxs.bk ..\..\..\RegistryPreview.wxs
call move /Y ..\..\..\Resources.wxs.bk ..\..\..\Resources.wxs
call move /Y ..\..\..\Run.wxs.bk ..\..\..\Run.wxs
call move /Y ..\..\..\Settings.wxs.bk ..\..\..\Settings.wxs
call move /Y ..\..\..\ShortcutGuide.wxs.bk ..\..\..\ShortcutGuide.wxs
call move /Y ..\..\..\Tools.wxs.bk ..\..\..\Tools.wxs
call move /Y ..\..\..\WinAppSDK.wxs.bk ..\..\..\WinAppSDK.wxs
call move /Y ..\..\..\WinUI3Applications.wxs.bk ..\..\..\WinUI3Applications.wxs
call move /Y ..\..\..\Workspaces.wxs.bk ..\..\..\Workspaces.wxs
</PostBuildEvent>
</PropertyGroup>
<PropertyGroup Label="UserMacros" Condition=" '$(PerUser)' == 'true' ">
<DefineConstants>$(DefineConstants);PerUser=true</DefineConstants>
</PropertyGroup>
<PropertyGroup Label="UserMacros" Condition=" '$(PerUser)' != 'true' ">
<DefineConstants>$(DefineConstants);PerUser=false</DefineConstants>
</PropertyGroup>
<PropertyGroup Label="UserMacros" Condition=" '$(CIBuild)' == 'true' ">
<DefineConstants>$(DefineConstants);CIBuild=true</DefineConstants>
</PropertyGroup>
<PropertyGroup Label="UserMacros" Condition=" '$(CIBuild)' != 'true' ">
<DefineConstants>$(DefineConstants);CIBuild=false</DefineConstants>
</PropertyGroup>
<PropertyGroup>
<Name>PowerToysVNextInstaller</Name>
<!-- We do not support debug installer builds -->
<Configuration Condition=" '$(Configuration)' == '' ">Release</Configuration>
<Platform>$(Platform)</Platform>
<ProductVersion>3.10</ProductVersion>
<ProjectGuid>{b6e94700-df38-41f6-a3fd-18b69674ab1e}</ProjectGuid>
<SchemaVersion>2.0</SchemaVersion>
<OutputName Condition=" '$(PerUser)' != 'true' ">PowerToysSetupVNext-$(Version)-$(Platform)</OutputName>
<OutputName Condition=" '$(PerUser)' == 'true' ">PowerToysUserSetupVNext-$(Version)-$(Platform)</OutputName>
<OutputType>Package</OutputType>
<SuppressAclReset>True</SuppressAclReset>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
<!-- 1076 and ICE91 - warning: using this configuration for perMachine install could cause problems. -->
<!-- 1026 - warning: file ID is too long -->
<SuppressIces>ICE91</SuppressIces>
<SuppressSpecificWarnings>1026;1076</SuppressSpecificWarnings>
</PropertyGroup>
<PropertyGroup>
<OutputPath Condition=" '$(PerUser)' != 'true' ">$(Platform)\$(Configuration)\MachineSetup</OutputPath>
<OutputPath Condition=" '$(PerUser)' == 'true' ">$(Platform)\$(Configuration)\UserSetup</OutputPath>
<IntermediateOutputPath Condition=" '$(PerUser)' != 'true' ">$(BaseIntermediateOutputPath)$(Platform)\$(Configuration)\MachineSetup</IntermediateOutputPath>
<IntermediateOutputPath Condition=" '$(PerUser)' == 'true' ">$(BaseIntermediateOutputPath)$(Platform)\$(Configuration)\UserSetup</IntermediateOutputPath>
<SuppressIces>ICE40</SuppressIces>
</PropertyGroup>
<ItemGroup>
<Compile Include="CustomDialogs\PTInstallDirDlg.wxs" />
<Compile Include="CustomDialogs\PTLicenseDlg.wxs" />
<Compile Include="CustomDialogs\WixUI_PTInstallDir.wxs" />
<Compile Include="NewPlus.wxs" />
<Compile Include="Product.wxs" />
<Compile Include="AdvancedPaste.wxs" />
<Compile Include="Awake.wxs" />
<Compile Include="BaseApplications.wxs" />
<Compile Include="CmdPal.wxs" />
<Compile Include="ColorPicker.wxs" />
<Compile Include="EnvironmentVariables.wxs" />
<Compile Include="FileExplorerPreview.wxs" />
<Compile Include="FileLocksmith.wxs" />
<Compile Include="Hosts.wxs" />
<Compile Include="ImageResizer.wxs" />
<Compile Include="KeyboardManager.wxs" />
<Compile Include="Peek.wxs" />
<Compile Include="PowerRename.wxs" />
<Compile Include="RegistryPreview.wxs" />
<Compile Include="Run.wxs" />
<Compile Include="Settings.wxs" />
<Compile Include="ShortcutGuide.wxs" />
<Compile Include="Tools.wxs" />
<Compile Include="MouseWithoutBorders.wxs" />
<Compile Include="WinUI3Applications.wxs" />
<Compile Include="MonacoSRC.wxs" />
<Compile Include="Core.wxs" />
<Compile Include="Resources.wxs" />
<Compile Include="WinAppSDK.wxs" />
<Compile Include="Workspaces.wxs" />
</ItemGroup>
<ItemGroup>
<Folder Include="CustomDialogs" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="WixToolset.Heat" />
<PackageReference Include="WixToolset.Firewall.wixext" />
<PackageReference Include="WixToolset.Util.wixext" />
<PackageReference Include="WixToolset.UI.wixext" />
<PackageReference Include="WixToolset.NetFx.wixext" />
<PackageReference Include="WixToolset.Bal.wixext" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\PowerToysSetupCustomActionsVNext\PowerToysSetupCustomActionsVNext.vcxproj">
<Name>PowerToysSetupCustomActionsVNext</Name>
<Project>{B3A354B0-1E54-4B55-A962-FB5AF9330C19}</Project>
<Private>True</Private>
<DoNotHarvest>True</DoNotHarvest>
<RefProjectOutputGroups>Binaries;Content;Satellites</RefProjectOutputGroups>
<RefTargetDir>INSTALLFOLDER</RefTargetDir>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Content Include="packages.config" />
</ItemGroup>
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
</Target>
<!-- Prevents NU1503 -->
<Target Name="_IsProjectRestoreSupported" Returns="@(_ValidProjectsForRestore)">
<ItemGroup>
<_ValidProjectsForRestore Include="$(MSBuildProjectFullPath)" />
</ItemGroup>
</Target>
<Target Name="Restore" />
</Project>

View File

@@ -0,0 +1,266 @@
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:util="http://wixtoolset.org/schemas/v4/wxs/util" xmlns:ui="http://wixtoolset.org/schemas/v4/wxs/ui">
<?include $(sys.CURRENTDIR)\Common.wxi?>
<!-- WiX Components with multiple files cause issues due to the way Windows installs them.
Windows decides whether to install a component by checking the existence of KeyPath file and its version.
Thus, if some files were updated but KeyPath file was not, the component wouldn't be updated.
Some resource files, e.g. images, do not have version, so even if Component has only a single image and a static GUID, it won't be updated.
Considering all of the above, it's much simpler to just have one file per Component with an implicit Guid.
More info:
- https://stackoverflow.com/a/1604348/657390
- https://stackoverflow.com/a/1422121/657390
- https://robmensching.com/blog/posts/2003/10/18/component-rules-101/
- https://robmensching.com/blog/posts/2003/10/4/windows-installer-components-introduction/
-->
<Package Name="PowerToys (Preview)" Language="1033" Version="$(var.Version)" Manufacturer="Microsoft Corporation" UpgradeCode="$(var.UpgradeCodeGUID)" Scope="$(var.InstallScope)">
<MajorUpgrade DowngradeErrorMessage="A later version of [ProductName] is already installed." />
<Upgrade Id="$(var.UpgradeCodeGUID)">
<UpgradeVersion Minimum="0.0.0" Maximum="$(var.Version)" Property="PREVIOUSVERSIONSINSTALLED" IncludeMinimum="yes" IncludeMaximum="no" />
</Upgrade>
<MediaTemplate EmbedCab="yes" />
<Property Id="REINSTALLMODE" Value="amus" />
<Property Id="WINDOWSBUILDNUMBER" Secure="yes">
<RegistrySearch Id="BuildNumberSearch" Root="HKLM" Key="SOFTWARE\Microsoft\Windows NT\CurrentVersion" Name="CurrentBuildNumber" Type="raw" />
</Property>
<Launch Condition="(WINDOWSBUILDNUMBER &gt;= 19041)" Message="This application is only supported on Windows 10 version v2004 (build 19041) or higher." />
<Icon Id="powertoys.exe" SourceFile="$(var.BinDir)svgs\icon.ico" />
<Property Id="ARPPRODUCTICON" Value="powertoys.exe" />
<Feature Id="CoreFeature" Title="PowerToys" AllowAdvertise="no" TypicalDefault="install" Description="Contains all PowerToys features." AllowAbsent="no">
<ComponentGroupRef Id="CoreComponents" />
<ComponentGroupRef Id="BaseApplicationsComponentGroup" />
<ComponentGroupRef Id="WinUI3ApplicationsComponentGroup" />
<ComponentGroupRef Id="AwakeComponentGroup" />
<ComponentGroupRef Id="ColorPickerComponentGroup" />
<ComponentGroupRef Id="FileExplorerPreviewComponentGroup" />
<ComponentGroupRef Id="FileLocksmithComponentGroup" />
<ComponentGroupRef Id="HostsComponentGroup" />
<ComponentGroupRef Id="ImageResizerComponentGroup" />
<ComponentGroupRef Id="KeyboardManagerComponentGroup" />
<ComponentGroupRef Id="PeekComponentGroup" />
<ComponentGroupRef Id="PowerRenameComponentGroup" />
<ComponentGroupRef Id="RegistryPreviewComponentGroup" />
<ComponentGroupRef Id="RunComponentGroup" />
<ComponentGroupRef Id="SettingsComponentGroup" />
<ComponentGroupRef Id="ShortcutGuideComponentGroup" />
<ComponentGroupRef Id="MouseWithoutBordersComponentGroup" />
<ComponentGroupRef Id="EnvironmentVariablesComponentGroup" />
<ComponentGroupRef Id="AdvancedPasteComponentGroup" />
<ComponentGroupRef Id="NewPlusComponentGroup" />
<ComponentGroupRef Id="NewPlusTemplatesComponentGroup" />
<ComponentGroupRef Id="ResourcesComponentGroup" />
<ComponentGroupRef Id="WindowsAppSDKComponentGroup" />
<ComponentGroupRef Id="ToolComponentGroup" />
<ComponentGroupRef Id="MonacoSRCHeatGenerated" />
<ComponentGroupRef Id="WorkspacesComponentGroup" />
<ComponentGroupRef Id="CmdPalComponentGroup" />
</Feature>
<SetProperty Id="ARPINSTALLLOCATION" Value="[INSTALLFOLDER]" After="CostFinalize" />
<Property Id="WIXUI_INSTALLDIR" Value="INSTALLFOLDER" />
<UI>
<ui:WixUI Id="WixUI_InstallDir" />
<Publish Dialog="WelcomeDlg" Control="Next" Event="NewDialog" Value="InstallDirDlg" Order="99" />
<Publish Dialog="InstallDirDlg" Control="Back" Event="NewDialog" Value="WelcomeDlg" Order="99" />
<Publish Dialog="ExitDialog" Control="Finish" Event="EndDialog" Value="Return" Condition="NOT Installed" />
<Publish Dialog="MaintenanceTypeDlg" Control="RemoveButton" Property="_REMOVE_ALL" Value="Yes" />
<Publish Dialog="UserExit" Control="Finish" Event="DoAction" Value="TelemetryLogInstallCancel" Condition="NOT Installed" />
<Publish Dialog="FatalError" Control="Finish" Event="DoAction" Value="TelemetryLogInstallFail" Condition="NOT Installed" />
<Publish Dialog="UserExit" Control="Finish" Event="DoAction" Value="TelemetryLogUninstallCancel" Condition="Installed AND _REMOVE_ALL=&quot;Yes&quot;" />
<Publish Dialog="FatalError" Control="Finish" Event="DoAction" Value="TelemetryLogUninstallFail" Condition="Installed AND _REMOVE_ALL=&quot;Yes&quot;" />
<Publish Dialog="UserExit" Control="Finish" Event="DoAction" Value="TelemetryLogRepairCancel" Condition="Installed AND NOT (_REMOVE_ALL=&quot;Yes&quot;)" />
<Publish Dialog="FatalError" Control="Finish" Event="DoAction" Value="TelemetryLogRepairFail" Condition="Installed AND NOT (_REMOVE_ALL=&quot;Yes&quot;)" />
</UI>
<WixVariable Id="WixUIBannerBmp" Value="$(var.ProjectDir)\Images\banner.png" />
<WixVariable Id="WixUIDialogBmp" Value="$(var.ProjectDir)\Images\dialog.png" />
<WixVariable Id="WixUILicenseRtf" Value="$(var.RepoDir)\installer\License.rtf" />
<Property Id="INSTALLSTARTMENUSHORTCUT" Value="1" />
<Property Id="WixShellExecTarget" Value="[#PowerToys_ActionRunner.exe]" />
<SetProperty Action="SetDEFAULTBOOTSTRAPPERINSTALLFOLDER" Id="DEFAULTBOOTSTRAPPERINSTALLFOLDER" Value="[$(var.DefaultInstallDir)]PowerToys" Before="SetBOOTSTRAPPERINSTALLFOLDER" Sequence="execute"></SetProperty>
<!-- In case we didn't receive a value from the bootstrapper. -->
<SetProperty Action="SetBOOTSTRAPPERINSTALLFOLDER" Id="BOOTSTRAPPERINSTALLFOLDER" Value="[DEFAULTBOOTSTRAPPERINSTALLFOLDER]" Before="DetectPrevInstallPath" Sequence="execute" Condition="BOOTSTRAPPERINSTALLFOLDER = &quot;&quot;" />
<!-- Have to compare value sent by bootstrapper to default to avoid using it, as a check to verify it's not default. This hack can be removed if it's possible to set the bootstrapper option to the previous install folder-->
<SetProperty Action="SetINSTALLFOLDERTOPREVIOUSINSTALLFOLDER" Id="INSTALLFOLDER" Value="[PREVIOUSINSTALLFOLDER]" After="DetectPrevInstallPath" Sequence="execute" Condition="BOOTSTRAPPERINSTALLFOLDER = DEFAULTBOOTSTRAPPERINSTALLFOLDER AND PREVIOUSINSTALLFOLDER &lt;&gt; &quot;&quot;" />
<SetProperty Action="SetINSTALLFOLDERTOBOOTSTRAPPERINSTALLFOLDER" Id="INSTALLFOLDER" Value="[BOOTSTRAPPERINSTALLFOLDER]" After="DetectPrevInstallPath" Sequence="execute" Condition="BOOTSTRAPPERINSTALLFOLDER &lt;&gt; DEFAULTBOOTSTRAPPERINSTALLFOLDER OR PREVIOUSINSTALLFOLDER = &quot;&quot;" />
<SetProperty Id="InstallScope" Value="$(var.InstallScope)" Before="DetectPrevInstallPath" Sequence="execute"></SetProperty>
<InstallExecuteSequence>
<Custom Action="DetectPrevInstallPath" After="AppSearch" />
<Custom Action="SetLaunchPowerToysParam" Before="LaunchPowerToys" />
<Custom Action="SetInstallCmdPalPackageParam" Before="InstallCmdPalPackage" />
<Custom Action="SetUninstallCommandNotFoundParam" Before="UninstallCommandNotFound" />
<Custom Action="SetUpgradeCommandNotFoundParam" Before="UpgradeCommandNotFound" />
<Custom Action="SetApplyModulesRegistryChangeSetsParam" Before="ApplyModulesRegistryChangeSets" />
<?if $(var.PerUser) = "true" ?>
<Custom Action="SetInstallDSCModuleParam" Before="InstallDSCModule" />
<?endif?>
<Custom Action="SetUnApplyModulesRegistryChangeSetsParam" Before="UnApplyModulesRegistryChangeSets" />
<Custom Action="CheckGPO" After="InstallInitialize" Condition="NOT Installed" />
<Custom Action="ApplyModulesRegistryChangeSets" After="InstallFiles" Condition="NOT Installed" />
<Custom Action="InstallCmdPalPackage" After="InstallFiles" Condition="NOT Installed" />
<Custom Action="RemovePowerToysSchTasks" After="RemoveFiles" />
<!-- TODO: Use to activate embedded MSIX -->
<!--<Custom Action="InstallEmbeddedMSIXTask" After="InstallFinalize">
NOT Installed
</Custom>-->
<?if $(var.PerUser) = "true" ?>
<Custom Action="InstallDSCModule" After="InstallFiles" />
<?endif?>
<Custom Action="TelemetryLogInstallSuccess" After="InstallFinalize" Condition="NOT Installed" />
<Custom Action="TelemetryLogUninstallSuccess" After="InstallFinalize" Condition="Installed and (NOT UPGRADINGPRODUCTCODE) AND (REMOVE=&quot;ALL&quot;)" />
<Custom Action="UnApplyModulesRegistryChangeSets" Before="RemoveFiles" Condition="Installed AND (REMOVE=&quot;ALL&quot;)" />
<Custom Action="UnRegisterContextMenuPackages" Before="RemoveFiles" Condition="Installed AND (REMOVE=&quot;ALL&quot;)" />
<Custom Action="UnsetAdvancedPasteAPIKey" Before="RemoveFiles" Condition="Installed AND (NOT UPGRADINGPRODUCTCODE) AND (REMOVE=&quot;ALL&quot;)" />
<Custom Action="UnRegisterCmdPalPackage" Before="RemoveFiles" Condition="Installed AND (NOT UPGRADINGPRODUCTCODE) AND (REMOVE=&quot;ALL&quot;)" />
<Custom Action="UninstallCommandNotFound" Before="RemoveFiles" Condition="Installed AND (NOT UPGRADINGPRODUCTCODE) AND (REMOVE=&quot;ALL&quot;)" />
<Custom Action="UpgradeCommandNotFound" After="InstallFiles" Condition="WIX_UPGRADE_DETECTED" />
<Custom Action="UninstallServicesTask" After="InstallFinalize" Condition="Installed AND (NOT UPGRADINGPRODUCTCODE) AND (REMOVE=&quot;ALL&quot;)" />
<!-- TODO: Use to activate embedded MSIX -->
<!--<Custom Action="UninstallEmbeddedMSIXTask" After="InstallFinalize">
Installed AND (REMOVE="ALL")
</Custom>-->
<?if $(var.PerUser) = "true" ?>
<Custom Action="UninstallDSCModule" After="InstallFinalize" Condition="Installed AND (REMOVE=&quot;ALL&quot;)" />
<?endif?>
<Custom Action="TerminateProcesses" Before="InstallValidate" />
<Custom Action="LaunchPowerToys" Before="InstallFinalize" Condition="NOT Installed" />
<!-- Clean Video Conference Mute registry keys that might be around from previous installations. We've deprecated this utility since then. -->
<Custom Action="CleanVideoConferenceRegistry" Before="InstallFinalize" Condition="NOT Installed" />
</InstallExecuteSequence>
<CustomAction Id="SetLaunchPowerToysParam" Property="LaunchPowerToys" Value="[INSTALLFOLDER]" />
<CustomAction Id="SetInstallCmdPalPackageParam" Property="InstallCmdPalPackage" Value="[INSTALLFOLDER]" />
<CustomAction Id="LaunchPowerToys" Return="ignore" Impersonate="yes" Execute="deferred" DllEntry="LaunchPowerToysCA" BinaryRef="PTCustomActions" />
<CustomAction Id="TerminateProcesses" Return="ignore" Execute="immediate" DllEntry="TerminateProcessesCA" BinaryRef="PTCustomActions" />
<CustomAction Id="SetApplyModulesRegistryChangeSetsParam" Property="ApplyModulesRegistryChangeSets" Value="[INSTALLFOLDER]" />
<CustomAction Id="SetUnApplyModulesRegistryChangeSetsParam" Property="UnApplyModulesRegistryChangeSets" Value="[INSTALLFOLDER]" />
<CustomAction Id="SetInstallDSCModuleParam" Property="InstallDSCModule" Value="[INSTALLFOLDER]" />
<CustomAction Id="SetUninstallCommandNotFoundParam" Property="UninstallCommandNotFound" Value="[INSTALLFOLDER]" />
<CustomAction Id="SetUpgradeCommandNotFoundParam" Property="UpgradeCommandNotFound" Value="[INSTALLFOLDER]" />
<CustomAction Id="SetCreateWinAppSDKHardlinksParam" Property="CreateWinAppSDKHardlinks" Value="[INSTALLFOLDER]" />
<CustomAction Id="SetDeleteWinAppSDKHardlinksParam" Property="DeleteWinAppSDKHardlinks" Value="[INSTALLFOLDER]" />
<CustomAction Id="SetCreatePTInteropHardlinksParam" Property="CreatePTInteropHardlinks" Value="[INSTALLFOLDER]" />
<CustomAction Id="SetDeletePTInteropHardlinksParam" Property="DeletePTInteropHardlinks" Value="[INSTALLFOLDER]" />
<CustomAction Id="SetCreateDotnetRuntimeHardlinksParam" Property="CreateDotnetRuntimeHardlinks" Value="[INSTALLFOLDER]" />
<CustomAction Id="SetDeleteDotnetRuntimeHardlinksParam" Property="DeleteDotnetRuntimeHardlinks" Value="[INSTALLFOLDER]" />
<CustomAction Id="RemovePowerToysSchTasks" Return="ignore" Impersonate="no" Execute="deferred" DllEntry="RemoveScheduledTasksCA" BinaryRef="PTCustomActions" />
<CustomAction Id="InstallEmbeddedMSIXTask" Return="ignore" Impersonate="yes" DllEntry="InstallEmbeddedMSIXCA" BinaryRef="PTCustomActions" />
<CustomAction Id="UninstallEmbeddedMSIXTask" Return="ignore" Impersonate="yes" DllEntry="UninstallEmbeddedMSIXCA" BinaryRef="PTCustomActions" />
<CustomAction Id="InstallDSCModule" Return="ignore" Impersonate="yes" Execute="deferred" DllEntry="InstallDSCModuleCA" BinaryRef="PTCustomActions" />
<CustomAction Id="UninstallDSCModule" Return="ignore" Impersonate="yes" DllEntry="UninstallDSCModuleCA" BinaryRef="PTCustomActions" />
<CustomAction Id="UninstallServicesTask" Return="ignore" Impersonate="yes" DllEntry="UninstallServicesCA" BinaryRef="PTCustomActions" />
<CustomAction Id="UninstallCommandNotFound" Return="ignore" Impersonate="yes" Execute="deferred" DllEntry="UninstallCommandNotFoundModuleCA" BinaryRef="PTCustomActions" />
<CustomAction Id="UpgradeCommandNotFound" Return="ignore" Impersonate="yes" Execute="deferred" DllEntry="UpgradeCommandNotFoundModuleCA" BinaryRef="PTCustomActions" />
<CustomAction Id="UnsetAdvancedPasteAPIKey" Return="ignore" Impersonate="yes" Execute="deferred" DllEntry="UnsetAdvancedPasteAPIKeyCA" BinaryRef="PTCustomActions" />
<CustomAction Id="TelemetryLogInstallSuccess" Return="ignore" Impersonate="yes" DllEntry="TelemetryLogInstallSuccessCA" BinaryRef="PTCustomActions" />
<CustomAction Id="TelemetryLogInstallCancel" Return="ignore" Impersonate="yes" DllEntry="TelemetryLogInstallCancelCA" BinaryRef="PTCustomActions" />
<CustomAction Id="TelemetryLogInstallFail" Return="ignore" Impersonate="yes" DllEntry="TelemetryLogInstallFailCA" BinaryRef="PTCustomActions" />
<CustomAction Id="TelemetryLogUninstallSuccess" Return="ignore" Impersonate="yes" DllEntry="TelemetryLogUninstallSuccessCA" BinaryRef="PTCustomActions" />
<CustomAction Id="TelemetryLogUninstallCancel" Return="ignore" Impersonate="yes" DllEntry="TelemetryLogUninstallCancelCA" BinaryRef="PTCustomActions" />
<CustomAction Id="TelemetryLogUninstallFail" Return="ignore" Impersonate="yes" DllEntry="TelemetryLogUninstallFailCA" BinaryRef="PTCustomActions" />
<CustomAction Id="TelemetryLogRepairCancel" Return="ignore" Impersonate="yes" DllEntry="TelemetryLogRepairCancelCA" BinaryRef="PTCustomActions" />
<CustomAction Id="TelemetryLogRepairFail" Return="ignore" Impersonate="yes" DllEntry="TelemetryLogRepairFailCA" BinaryRef="PTCustomActions" />
<CustomAction Id="DetectPrevInstallPath" Return="check" Impersonate="yes" DllEntry="DetectPrevInstallPathCA" BinaryRef="PTCustomActions" />
<CustomAction Id="CleanVideoConferenceRegistry" Return="ignore" Impersonate="yes" Execute="deferred" DllEntry="CleanVideoConferenceRegistryCA" BinaryRef="PTCustomActions" />
<CustomAction Id="ApplyModulesRegistryChangeSets" Return="check" Impersonate="yes" Execute="deferred" DllEntry="ApplyModulesRegistryChangeSetsCA" BinaryRef="PTCustomActions" />
<CustomAction Id="UnApplyModulesRegistryChangeSets" Return="check" Impersonate="yes" Execute="deferred" DllEntry="UnApplyModulesRegistryChangeSetsCA" BinaryRef="PTCustomActions" />
<CustomAction Id="UnRegisterContextMenuPackages" Return="ignore" Impersonate="yes" Execute="deferred" DllEntry="UnRegisterContextMenuPackagesCA" BinaryRef="PTCustomActions" />
<CustomAction Id="UnRegisterCmdPalPackage" Return="ignore" Impersonate="yes" Execute="deferred" DllEntry="UnRegisterCmdPalPackageCA" BinaryRef="PTCustomActions" />
<CustomAction Id="CheckGPO" Return="check" Impersonate="yes" DllEntry="CheckGPOCA" BinaryRef="PTCustomActions" />
<CustomAction Id="InstallCmdPalPackage" Return="ignore" Impersonate="yes" Execute="deferred" DllEntry="InstallCmdPalPackageCA" BinaryRef="PTCustomActions" />
<!-- Close 'PowerToys.exe' before uninstall-->
<Property Id="MSIRESTARTMANAGERCONTROL" Value="DisableShutdown" />
<Property Id="MSIFASTINSTALL" Value="DisableShutdown" />
<!-- <util:CloseApplication CloseMessage="yes" Target="PowerToys.exe" ElevatedCloseMessage="yes" RebootPrompt="no" TerminateProcess="0" /> -->
</Package>
<Fragment>
<Binary Id="PTCustomActions" SourceFile="$(var.PowerToysSetupCustomActionsVNext.TargetPath)" />
</Fragment>
<!-- Installation directory structure -->
<Fragment>
<StandardDirectory Id="$(var.DefaultInstallDir)">
<Directory Id="INSTALLFOLDER" Name="PowerToys">
<Directory Id="BaseApplicationsAssetsFolder" Name="Assets">
</Directory>
<Directory Id="DSCModulesReferenceFolder" Name="DSCModules" />
<Directory Id="WinUI3AppsInstallFolder" Name="WinUI3Apps">
<Directory Id="WinUI3AppsMicrosoftUIXamlInstallFolder" Name="Microsoft.UI.Xaml">
<Directory Id="WinUI3AppsMicrosoftUIXamlAssetsInstallFolder" Name="Assets" />
</Directory>
<Directory Id="WinUI3AppsAssetsFolder" Name="Assets">
</Directory>
</Directory>
<Directory Id="ToolsFolder" Name="Tools" />
</Directory>
</StandardDirectory>
<StandardDirectory Id="ProgramMenuFolder">
<Directory Id="ApplicationProgramsFolder" Name="PowerToys (Preview)" />
</StandardDirectory>
<StandardDirectory Id="DesktopFolder" />
</Fragment>
</Wix>

View File

@@ -0,0 +1,28 @@
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
<?include $(sys.CURRENTDIR)\Common.wxi?>
<?define RegistryPreviewAssetsFiles=?>
<?define RegistryPreviewAssetsFilesPath=$(var.BinDir)WinUI3Apps\Assets\RegistryPreview?>
<Fragment>
<!-- Registry Preview -->
<DirectoryRef Id="WinUI3AppsAssetsFolder">
<Directory Id="RegistryPreviewAssetsInstallFolder" Name="RegistryPreview" />
</DirectoryRef>
<DirectoryRef Id="RegistryPreviewAssetsInstallFolder" FileSource="$(var.RegistryPreviewAssetsFilesPath)">
<!-- Generated by generateFileComponents.ps1 -->
<!--RegistryPreviewAssetsFiles_Component_Def-->
</DirectoryRef>
<ComponentGroup Id="RegistryPreviewComponentGroup">
<Component Id="RemoveRegistryPreviewFolder" Guid="D3DBC395-FAC5-44B1-BE44-3FE2B6E0F391" Directory="RegistryPreviewAssetsInstallFolder">
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys\components">
<RegistryValue Type="string" Name="RemoveRegistryPreviewFolder" Value="" KeyPath="yes" />
</RegistryKey>
<RemoveFolder Id="RemoveFolderRegistryPreviewAssetsFolder" Directory="RegistryPreviewAssetsInstallFolder" On="uninstall" />
</Component>
</ComponentGroup>
</Fragment>
</Wix>

View File

@@ -0,0 +1,454 @@
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
<?include $(sys.CURRENTDIR)\Common.wxi?>
<!-- Languages for localization on build farm -->
<!-- qps-ploc;qps-ploca;qps-plocm; -->
<?define LocLanguageList = ar-SA;cs-CZ;de-DE;es-ES;fa-IR;fr-FR;he-IL;hu-HU;it-IT;ja-JP;ko-KR;nl-NL;pl-PL;pt-BR;pt-PT;ru-RU;sv-SE;tr-TR;uk-UA;zh-CN;zh-TW?>
<Fragment>
<!-- Resource directories should be added only if the installer is built on the build farm -->
<?ifdef env.IsPipeline?>
<?foreach ParentDirectory in INSTALLFOLDER;HistoryPluginFolder;CalculatorPluginFolder;FolderPluginFolder;ProgramPluginFolder;ShellPluginFolder;IndexerPluginFolder;UnitConverterPluginFolder;ValueGeneratorPluginFolder;UriPluginFolder;WindowWalkerPluginFolder;OneNotePluginFolder;RegistryPluginFolder;VSCodeWorkspacesPluginFolder;ServicePluginFolder;SystemPluginFolder;TimeDatePluginFolder;WindowsSettingsPluginFolder;WindowsTerminalPluginFolder;WebSearchPluginFolder;PowerToysPluginFolder?>
<DirectoryRef Id="$(var.ParentDirectory)">
<!-- Resource file directories -->
<?foreach Language in $(var.LocLanguageList)?>
<!--NB: Ids can't contain hyphens-->
<?if $(var.Language) = ar-SA?>
<?define IdSafeLanguage = ar_SA?>
<?elseif $(var.Language) = cs-CZ?>
<?define IdSafeLanguage = cs_CZ?>
<?elseif $(var.Language) = de-DE?>
<?define IdSafeLanguage = de_DE?>
<?elseif $(var.Language) = es-ES?>
<?define IdSafeLanguage = es_ES?>
<?elseif $(var.Language) = fa-IR?>
<?define IdSafeLanguage = fa_IR?>
<?elseif $(var.Language) = fr-FR?>
<?define IdSafeLanguage = fr_FR?>
<?elseif $(var.Language) = he-IL?>
<?define IdSafeLanguage = he_IL?>
<?elseif $(var.Language) = hu-HU?>
<?define IdSafeLanguage = hu_HU?>
<?elseif $(var.Language) = it-IT?>
<?define IdSafeLanguage = it_IT?>
<?elseif $(var.Language) = ja-JP?>
<?define IdSafeLanguage = ja_JP?>
<?elseif $(var.Language) = ko-KR?>
<?define IdSafeLanguage = ko_KR?>
<?elseif $(var.Language) = nl-NL?>
<?define IdSafeLanguage = nl_NL?>
<?elseif $(var.Language) = pl-PL?>
<?define IdSafeLanguage = pl_PL?>
<?elseif $(var.Language) = pt-BR?>
<?define IdSafeLanguage = pt_BR?>
<?elseif $(var.Language) = pt-PT?>
<?define IdSafeLanguage = pt_PT?>
<!--
<?elseif $(var.Language) = qps-ploc?>
<?define IdSafeLanguage = qps_ploc?>
<?elseif $(var.Language) = qps-ploca?>
<?define IdSafeLanguage = qps_ploca?>
<?elseif $(var.Language) = qps-plocm?>
<?define IdSafeLanguage = qps_plocm?>
-->
<?elseif $(var.Language) = ru-RU?>
<?define IdSafeLanguage = ru_RU?>
<?elseif $(var.Language) = sv-SE?>
<?define IdSafeLanguage = sv_SE?>
<?elseif $(var.Language) = tr-TR?>
<?define IdSafeLanguage = tr_TR?>
<?elseif $(var.Language) = uk-UA?>
<?define IdSafeLanguage = uk_UA?>
<?elseif $(var.Language) = zh-CN?>
<?define IdSafeLanguage = zh_CN?>
<?elseif $(var.Language) = zh-TW?>
<?define IdSafeLanguage = zh_TW?>
<?else?>
<?define IdSafeLanguage = $(var.Language)?>
<?endif?>
<Directory Id="Resource$(var.IdSafeLanguage)$(var.ParentDirectory)" Name="$(var.Language)" />
<?undef IdSafeLanguage?>
<?endforeach?>
</DirectoryRef>
<?endforeach?>
<?endif?>
<ComponentGroup Id="ResourcesComponentGroup">
<!-- Resource components should be added only if the installer is built on the build farm -->
<?ifdef env.IsPipeline?>
<!-- Components for adding resource files -->
<?foreach Language in $(var.LocLanguageList)?>
<!--NB: Ids can't contain hyphens-->
<?if $(var.Language) = ar-SA?>
<!-- CompGUIDPrefix is language-dependent guid prefix missing the last 2 digits. -->
<?define CompGUIDPrefix = 4CF0A1CD-CA13-408B-AAC1-6E024B86A9?>
<?define IdSafeLanguage = ar_SA?>
<?elseif $(var.Language) = cs-CZ?>
<?define CompGUIDPrefix = 3E93405A-B91B-4E04-BAEC-26BEEE60F9?>
<?define IdSafeLanguage = cs_CZ?>
<?elseif $(var.Language) = de-DE?>
<?define CompGUIDPrefix = AF28C057-7ED9-474C-8E7E-D583BE8ECF?>
<?define IdSafeLanguage = de_DE?>
<?elseif $(var.Language) = es-ES?>
<?define CompGUIDPrefix = DD1FEEBD-55F0-44BA-A0FF-62C5C1C952?>
<?define IdSafeLanguage = es_ES?>
<?elseif $(var.Language) = fa-IR?>
<?define CompGUIDPrefix = 157411C9-CAB8-4CC5-AEA4-5ABEB91E59?>
<?define IdSafeLanguage = fa_IR?>
<?elseif $(var.Language) = fr-FR?>
<?define CompGUIDPrefix = F9F86D61-C747-43FC-8509-F3D1F198E1?>
<?define IdSafeLanguage = fr_FR?>
<?elseif $(var.Language) = he-IL?>
<?define CompGUIDPrefix = AFEA6E19-5B93-4CBB-B0CB-AFB2565C7D?>
<?define IdSafeLanguage = he_IL?>
<?elseif $(var.Language) = hu-HU?>
<?define CompGUIDPrefix = 9A919A40-E457-47F5-97C8-E886F06DDE?>
<?define IdSafeLanguage = hu_HU?>
<?elseif $(var.Language) = it-IT?>
<?define CompGUIDPrefix = 48FBF6D9-32DB-46FF-A64C-225269E738?>
<?define IdSafeLanguage = it_IT?>
<?elseif $(var.Language) = ja-JP?>
<?define CompGUIDPrefix = FB8E04AB-C8E8-43C0-8883-19F73E4EBA?>
<?define IdSafeLanguage = ja_JP?>
<?elseif $(var.Language) = ko-KR?>
<?define CompGUIDPrefix = 86C8F07C-80CA-420A-B6E7-86933D640C?>
<?define IdSafeLanguage = ko_KR?>
<?elseif $(var.Language) = nl-NL?>
<?define CompGUIDPrefix = C68F115F-28DD-4B45-9512-405C432458?>
<?define IdSafeLanguage = nl_NL?>
<?elseif $(var.Language) = pl-PL?>
<?define CompGUIDPrefix = 97494A31-5F57-4EC1-A6A9-994DF0813B?>
<?define IdSafeLanguage = pl_PL?>
<?elseif $(var.Language) = pt-BR?>
<?define CompGUIDPrefix = F4985235-2AB9-446B-BF8E-B14929A160?>
<?define IdSafeLanguage = pt_BR?>
<?elseif $(var.Language) = pt-PT?>
<?define CompGUIDPrefix = 58155841-D53A-4330-89D3-5C0338B928?>
<?define IdSafeLanguage = pt_PT?>
<!--
<?elseif $(var.Language) = qps-ploc?>
<?define CompGUIDPrefix = 75710CB2-DBDA-420B-9676-34D5F9D4A2?>
<?define IdSafeLanguage = qps_ploc?>
<?elseif $(var.Language) = qps-ploca?>
<?define CompGUIDPrefix = 55AF2A35-F959-49AB-B9EF-DFC9964A4F?>
<?define IdSafeLanguage = qps_ploca?>
<?elseif $(var.Language) = qps-plocm?>
<?define CompGUIDPrefix = D8CE2F7B-B0A1-4687-BFB7-1792B2FCCD?>
<?define IdSafeLanguage = qps_plocm?>
-->
<?elseif $(var.Language) = ru-RU?>
<?define CompGUIDPrefix = 157BAF33-8D3F-46B7-9CF9-2C18E601CC?>
<?define IdSafeLanguage = ru_RU?>
<?elseif $(var.Language) = sv-SE?>
<?define CompGUIDPrefix = 85B4199F-5F89-42C3-B7C2-DBCD3E5267?>
<?define IdSafeLanguage = sv_SE?>
<?elseif $(var.Language) = tr-TR?>
<?define CompGUIDPrefix = EA375345-F52A-499B-A45E-108CE67EAF?>
<?define IdSafeLanguage = tr_TR?>
<?elseif $(var.Language) = uk-UA?>
<?define CompGUIDPrefix = 17BA6BA7-8CB6-47CA-BEB1-2FE87A0724?>
<?define IdSafeLanguage = uk_UA?>
<?elseif $(var.Language) = zh-CN?>
<?define CompGUIDPrefix = F8EE7CE9-58EA-4850-B76F-C22362DC0E?>
<?define IdSafeLanguage = zh_CN?>
<?elseif $(var.Language) = zh-TW?>
<?define CompGUIDPrefix = F07F3210-79E2-4C38-AEF7-D8EBE06621?>
<?define IdSafeLanguage = zh_TW?>
<?else?>
<?define IdSafeLanguage = $(var.Language)?>
<?define CompGUIDPrefix = 94D9A417-56FC-435D-8167-A45F5D7A75?>
<?endif?>
<Component Id="Launcher_$(var.IdSafeLanguage)_Component" Directory="Resource$(var.IdSafeLanguage)INSTALLFOLDER" Guid="$(var.CompGUIDPrefix)00">
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys\components">
<RegistryValue Type="string" Name="Launcher_$(var.IdSafeLanguage)_Component" Value="" KeyPath="yes" />
</RegistryKey>
<File Id="Launcher_$(var.IdSafeLanguage)_File" Source="$(var.BinDir)\$(var.Language)\PowerToys.PowerLauncher.resources.dll" />
</Component>
<Component Id="FancyZonesEditor_$(var.IdSafeLanguage)_Component" Directory="Resource$(var.IdSafeLanguage)INSTALLFOLDER" Guid="$(var.CompGUIDPrefix)01">
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys\components">
<RegistryValue Type="string" Name="FancyZonesEditor_$(var.IdSafeLanguage)_Component" Value="" KeyPath="yes" />
</RegistryKey>
<File Id="FancyZonesEditor_$(var.IdSafeLanguage)_File" Source="$(var.BinDir)\$(var.Language)\PowerToys.FancyZonesEditor.resources.dll" />
</Component>
<Component Id="ImageResizer_$(var.IdSafeLanguage)_Component" Directory="Resource$(var.IdSafeLanguage)INSTALLFOLDER" Guid="$(var.CompGUIDPrefix)02">
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys\components">
<RegistryValue Type="string" Name="ImageResizer_$(var.IdSafeLanguage)_Component" Value="" KeyPath="yes" />
</RegistryKey>
<File Id="ImageResizer_$(var.IdSafeLanguage)_File" Source="$(var.BinDir)\$(var.Language)\PowerToys.ImageResizer.resources.dll" />
</Component>
<Component Id="ColorPicker_$(var.IdSafeLanguage)_Component" Directory="Resource$(var.IdSafeLanguage)INSTALLFOLDER" Guid="$(var.CompGUIDPrefix)03">
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys\components">
<RegistryValue Type="string" Name="ColorPicker_$(var.IdSafeLanguage)_Component" Value="" KeyPath="yes" />
</RegistryKey>
<File Id="ColorPicker_$(var.IdSafeLanguage)_File" Source="$(var.BinDir)\$(var.Language)\PowerToys.ColorPickerUI.resources.dll" />
</Component>
<Component Id="MarkdownPreviewHandler_$(var.IdSafeLanguage)_Component" Directory="Resource$(var.IdSafeLanguage)INSTALLFOLDER" Guid="$(var.CompGUIDPrefix)04">
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys\components">
<RegistryValue Type="string" Name="MarkdownPreviewHandler_$(var.IdSafeLanguage)_Component" Value="" KeyPath="yes" />
</RegistryKey>
<File Id="MarkdownPreviewHandler_$(var.IdSafeLanguage)_File" Source="$(var.BinDir)$(var.Language)\PowerToys.MarkdownPreviewHandler.resources.dll" />
</Component>
<Component Id="SVGPreviewHandler_$(var.IdSafeLanguage)_Component" Directory="Resource$(var.IdSafeLanguage)INSTALLFOLDER" Guid="$(var.CompGUIDPrefix)05">
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys\components">
<RegistryValue Type="string" Name="SVGPreviewHandler_$(var.IdSafeLanguage)_Component" Value="" KeyPath="yes" />
</RegistryKey>
<File Id="SVGPreviewHandler_$(var.IdSafeLanguage)_File" Source="$(var.BinDir)\$(var.Language)\PowerToys.SvgPreviewHandler.resources.dll" />
</Component>
<Component Id="PDFPreviewHandler_$(var.IdSafeLanguage)_Component" Directory="Resource$(var.IdSafeLanguage)INSTALLFOLDER" Guid="$(var.CompGUIDPrefix)06">
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys\components">
<RegistryValue Type="string" Name="PDFPreviewHandler_$(var.IdSafeLanguage)_Component" Value="" KeyPath="yes" />
</RegistryKey>
<File Id="PDFPreviewHandler_$(var.IdSafeLanguage)_File" Source="$(var.BinDir)\$(var.Language)\PowerToys.PdfPreviewHandler.resources.dll" />
</Component>
<Component Id="GcodePreviewHandler_$(var.IdSafeLanguage)_Component" Directory="Resource$(var.IdSafeLanguage)INSTALLFOLDER" Guid="$(var.CompGUIDPrefix)07">
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys\components">
<RegistryValue Type="string" Name="GcodePreviewHandler_$(var.IdSafeLanguage)_Component" Value="" KeyPath="yes" />
</RegistryKey>
<File Id="GcodePreviewHandler_$(var.IdSafeLanguage)_File" Source="$(var.BinDir)\$(var.Language)\PowerToys.GcodePreviewHandler.resources.dll" />
</Component>
<!-- PowerToys Run aka Launcher plugin resources -->
<Component Id="Launcher_Calculator_$(var.IdSafeLanguage)_Component" Directory="Resource$(var.IdSafeLanguage)CalculatorPluginFolder" Guid="$(var.CompGUIDPrefix)08">
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys\components">
<RegistryValue Type="string" Name="Launcher_Calculator_$(var.IdSafeLanguage)_Component" Value="" KeyPath="yes" />
</RegistryKey>
<File Id="Launcher_Calculator_$(var.IdSafeLanguage)_File" Source="$(var.BinDir)RunPlugins\Calculator\$(var.Language)\Microsoft.PowerToys.Run.Plugin.Calculator.resources.dll" />
</Component>
<Component Id="Launcher_Folder_$(var.IdSafeLanguage)_Component" Directory="Resource$(var.IdSafeLanguage)FolderPluginFolder" Guid="$(var.CompGUIDPrefix)09">
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys\components">
<RegistryValue Type="string" Name="Launcher_Folder_$(var.IdSafeLanguage)_Component" Value="" KeyPath="yes" />
</RegistryKey>
<File Id="Launcher_Folder_$(var.IdSafeLanguage)_File" Source="$(var.BinDir)RunPlugins\Folder\$(var.Language)\Microsoft.Plugin.Folder.resources.dll" />
</Component>
<Component Id="Launcher_Program_$(var.IdSafeLanguage)_Component" Guid="$(var.CompGUIDPrefix)0A" Directory="Resource$(var.IdSafeLanguage)ProgramPluginFolder">
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys\components">
<RegistryValue Type="string" Name="Launcher_Program_$(var.IdSafeLanguage)_Component" Value="" KeyPath="yes" />
</RegistryKey>
<File Id="Launcher_Program_$(var.IdSafeLanguage)_File" Source="$(var.BinDir)RunPlugins\Program\$(var.Language)\Microsoft.Plugin.Program.resources.dll" />
</Component>
<Component Id="Launcher_Shell_$(var.IdSafeLanguage)_Component" Guid="$(var.CompGUIDPrefix)0B" Directory="Resource$(var.IdSafeLanguage)ShellPluginFolder">
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys\components">
<RegistryValue Type="string" Name="Launcher_Shell_$(var.IdSafeLanguage)_Component" Value="" KeyPath="yes" />
</RegistryKey>
<File Id="Launcher_Shell_$(var.IdSafeLanguage)_File" Source="$(var.BinDir)RunPlugins\Shell\$(var.Language)\Microsoft.Plugin.Shell.resources.dll" />
</Component>
<Component Id="Launcher_Indexer_$(var.IdSafeLanguage)_Component" Guid="$(var.CompGUIDPrefix)0C" Directory="Resource$(var.IdSafeLanguage)IndexerPluginFolder">
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys\components">
<RegistryValue Type="string" Name="Launcher_Indexer_$(var.IdSafeLanguage)_Component" Value="" KeyPath="yes" />
</RegistryKey>
<File Id="Launcher_Indexer_$(var.IdSafeLanguage)_File" Source="$(var.BinDir)RunPlugins\Indexer\$(var.Language)\Microsoft.Plugin.Indexer.resources.dll" />
</Component>
<Component Id="Launcher_Uri_$(var.IdSafeLanguage)_Component" Guid="$(var.CompGUIDPrefix)0D" Directory="Resource$(var.IdSafeLanguage)UriPluginFolder">
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys\components">
<RegistryValue Type="string" Name="Launcher_Uri_$(var.IdSafeLanguage)_Component" Value="" KeyPath="yes" />
</RegistryKey>
<File Id="Launcher_Uri_$(var.IdSafeLanguage)_File" Source="$(var.BinDir)RunPlugins\Uri\$(var.Language)\Microsoft.Plugin.Uri.resources.dll" />
</Component>
<Component Id="Launcher_VSCodeWorkspaces_$(var.IdSafeLanguage)_Component" Guid="$(var.CompGUIDPrefix)0E" Directory="Resource$(var.IdSafeLanguage)VSCodeWorkspacesPluginFolder">
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys\components">
<RegistryValue Type="string" Name="Launcher_VSCodeWorkspaces_$(var.IdSafeLanguage)_Component" Value="" KeyPath="yes" />
</RegistryKey>
<File Id="Launcher_VSCodeWorkspaces_$(var.IdSafeLanguage)_File" Source="$(var.BinDir)RunPlugins\VSCodeWorkspaces\$(var.Language)\Community.PowerToys.Run.Plugin.VSCodeWorkspaces.resources.dll" />
</Component>
<Component Id="Launcher_WindowWalker_$(var.IdSafeLanguage)_Component" Guid="$(var.CompGUIDPrefix)0F" Directory="Resource$(var.IdSafeLanguage)WindowWalkerPluginFolder">
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys\components">
<RegistryValue Type="string" Name="Launcher_WindowWalker_$(var.IdSafeLanguage)_Component" Value="" KeyPath="yes" />
</RegistryKey>
<File Id="Launcher_WindowWalker_$(var.IdSafeLanguage)_File" Source="$(var.BinDir)RunPlugins\WindowWalker\$(var.Language)\Microsoft.Plugin.WindowWalker.resources.dll" />
</Component>
<Component Id="Launcher_Registry_$(var.IdSafeLanguage)_Component" Guid="$(var.CompGUIDPrefix)10" Directory="Resource$(var.IdSafeLanguage)RegistryPluginFolder">
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys\components">
<RegistryValue Type="string" Name="Launcher_Registry_$(var.IdSafeLanguage)_Component" Value="" KeyPath="yes" />
</RegistryKey>
<File Id="Launcher_Registry_$(var.IdSafeLanguage)_File" Source="$(var.BinDir)RunPlugins\Registry\$(var.Language)\Microsoft.PowerToys.Run.Plugin.Registry.resources.dll" />
</Component>
<Component Id="Launcher_Service_$(var.IdSafeLanguage)_Component" Guid="$(var.CompGUIDPrefix)11" Directory="Resource$(var.IdSafeLanguage)ServicePluginFolder">
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys\components">
<RegistryValue Type="string" Name="Launcher_Service_$(var.IdSafeLanguage)_Component" Value="" KeyPath="yes" />
</RegistryKey>
<File Id="Launcher_Service_$(var.IdSafeLanguage)_File" Source="$(var.BinDir)RunPlugins\Service\$(var.Language)\Microsoft.PowerToys.Run.Plugin.Service.resources.dll" />
</Component>
<Component Id="Launcher_System_$(var.IdSafeLanguage)_Component" Guid="$(var.CompGUIDPrefix)12" Directory="Resource$(var.IdSafeLanguage)SystemPluginFolder">
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys\components">
<RegistryValue Type="string" Name="Launcher_System_$(var.IdSafeLanguage)_Component" Value="" KeyPath="yes" />
</RegistryKey>
<File Id="Launcher_System_$(var.IdSafeLanguage)_File" Source="$(var.BinDir)RunPlugins\System\$(var.Language)\Microsoft.PowerToys.Run.Plugin.System.resources.dll" />
</Component>
<Component Id="Launcher_WindowsSettings_$(var.IdSafeLanguage)_Component" Guid="$(var.CompGUIDPrefix)13" Directory="Resource$(var.IdSafeLanguage)WindowsSettingsPluginFolder">
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys\components">
<RegistryValue Type="string" Name="Launcher_WindowsSettings_$(var.IdSafeLanguage)_Component" Value="" KeyPath="yes" />
</RegistryKey>
<File Id="Launcher_WindowsSettings_$(var.IdSafeLanguage)_File" Source="$(var.BinDir)RunPlugins\WindowsSettings\$(var.Language)\Microsoft.PowerToys.Run.Plugin.WindowsSettings.resources.dll" />
</Component>
<Component Id="Launcher_WindowsTerminal_$(var.IdSafeLanguage)_Component" Guid="$(var.CompGUIDPrefix)15" Directory="Resource$(var.IdSafeLanguage)WindowsTerminalPluginFolder">
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys\components">
<RegistryValue Type="string" Name="Launcher_WindowsTerminal_$(var.IdSafeLanguage)_Component" Value="" KeyPath="yes" />
</RegistryKey>
<File Id="Launcher_WindowsTerminal_$(var.IdSafeLanguage)_File" Source="$(var.BinDir)RunPlugins\WindowsTerminal\$(var.Language)\Microsoft.PowerToys.Run.Plugin.WindowsTerminal.resources.dll" />
</Component>
<Component Id="Launcher_WebSearch_$(var.IdSafeLanguage)_Component" Guid="$(var.CompGUIDPrefix)16" Directory="Resource$(var.IdSafeLanguage)WebSearchPluginFolder">
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys\components">
<RegistryValue Type="string" Name="Launcher_WebSearch_$(var.IdSafeLanguage)_Component" Value="" KeyPath="yes" />
</RegistryKey>
<File Id="Launcher_WebSearch_$(var.IdSafeLanguage)_File" Source="$(var.BinDir)RunPlugins\WebSearch\$(var.Language)\Community.PowerToys.Run.Plugin.WebSearch.resources.dll" />
</Component>
<Component Id="Launcher_UnitConverter_$(var.IdSafeLanguage)_Component" Guid="$(var.CompGUIDPrefix)17" Directory="Resource$(var.IdSafeLanguage)UnitConverterPluginFolder">
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys\components">
<RegistryValue Type="string" Name="Launcher_UnitConverter_$(var.IdSafeLanguage)_Component" Value="" KeyPath="yes" />
</RegistryKey>
<File Id="Launcher_UnitConverter_$(var.IdSafeLanguage)_File" Source="$(var.BinDir)RunPlugins\UnitConverter\$(var.Language)\Community.PowerToys.Run.Plugin.UnitConverter.resources.dll" />
</Component>
<Component Id="Launcher_TimeDate_$(var.IdSafeLanguage)_Component" Guid="$(var.CompGUIDPrefix)18" Directory="Resource$(var.IdSafeLanguage)TimeDatePluginFolder">
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys\components">
<RegistryValue Type="string" Name="Launcher_TimeDate_$(var.IdSafeLanguage)_Component" Value="" KeyPath="yes" />
</RegistryKey>
<File Id="Launcher_TimeDate_$(var.IdSafeLanguage)_File" Source="$(var.BinDir)RunPlugins\TimeDate\$(var.Language)\Microsoft.PowerToys.Run.Plugin.TimeDate.resources.dll" />
</Component>
<Component Id="Launcher_OneNote_$(var.IdSafeLanguage)_Component" Guid="$(var.CompGUIDPrefix)19" Directory="Resource$(var.IdSafeLanguage)OneNotePluginFolder">
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys\components">
<RegistryValue Type="string" Name="Resource$(var.IdSafeLanguage)OneNotePluginFolder" Value="" KeyPath="yes" />
</RegistryKey>
<File Id="Launcher_OneNote_$(var.IdSafeLanguage)_File" Source="$(var.BinDir)RunPlugins\OneNote\$(var.Language)\Microsoft.PowerToys.Run.Plugin.OneNote.resources.dll" />
</Component>
<Component Id="MonacoPreviewHandler_$(var.IdSafeLanguage)_Component" Directory="Resource$(var.IdSafeLanguage)INSTALLFOLDER" Guid="$(var.CompGUIDPrefix)1A">
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys\components">
<RegistryValue Type="string" Name="MonacoPreviewHandler_$(var.IdSafeLanguage)_Component" Value="" KeyPath="yes" />
</RegistryKey>
<File Id="MonacoPreviewHandler_$(var.IdSafeLanguage)_File" Source="$(var.BinDir)\$(var.Language)\PowerToys.MonacoPreviewHandler.resources.dll" />
</Component>
<Component Id="Launcher_History_$(var.IdSafeLanguage)_Component" Directory="Resource$(var.IdSafeLanguage)HistoryPluginFolder" Guid="$(var.CompGUIDPrefix)1B">
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys\components">
<RegistryValue Type="string" Name="Launcher_History_$(var.IdSafeLanguage)_Component" Value="" KeyPath="yes" />
</RegistryKey>
<File Id="Launcher_History_$(var.IdSafeLanguage)_File" Source="$(var.BinDir)RunPlugins\History\$(var.Language)\Microsoft.PowerToys.Run.Plugin.History.resources.dll" />
</Component>
<Component Id="Launcher_PowerToys_$(var.IdSafeLanguage)_Component" Directory="Resource$(var.IdSafeLanguage)PowerToysPluginFolder" Guid="$(var.CompGUIDPrefix)1C">
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys\components">
<RegistryValue Type="string" Name="Launcher_PowerToys_$(var.IdSafeLanguage)_Component" Value="" KeyPath="yes" />
</RegistryKey>
<File Id="Launcher_PowerToys_$(var.IdSafeLanguage)_File" Source="$(var.BinDir)RunPlugins\PowerToys\$(var.Language)\Microsoft.PowerToys.Run.Plugin.PowerToys.resources.dll" />
</Component>
<Component Id="Launcher_ValueGenerator_$(var.IdSafeLanguage)_Component" Guid="$(var.CompGUIDPrefix)1D" Directory="Resource$(var.IdSafeLanguage)ValueGeneratorPluginFolder">
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys\components">
<RegistryValue Type="string" Name="Launcher_ValueGenerator_$(var.IdSafeLanguage)_Component" Value="" KeyPath="yes" />
</RegistryKey>
<File Id="Launcher_ValueGenerator_$(var.IdSafeLanguage)_File" Source="$(var.BinDir)RunPlugins\ValueGenerator\$(var.Language)\Community.PowerToys.Run.Plugin.ValueGenerator.resources.dll" />
</Component>
<Component Id="QoiPreviewHandler_$(var.IdSafeLanguage)_Component" Directory="Resource$(var.IdSafeLanguage)INSTALLFOLDER" Guid="$(var.CompGUIDPrefix)1E">
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys\components">
<RegistryValue Type="string" Name="QoiPreviewHandler_$(var.IdSafeLanguage)_Component" Value="" KeyPath="yes" />
</RegistryKey>
<File Id="QoiPreviewHandler_$(var.IdSafeLanguage)_File" Source="$(var.BinDir)\$(var.Language)\PowerToys.QoiPreviewHandler.resources.dll" />
</Component>
<Component Id="Awake_$(var.IdSafeLanguage)_Component" Directory="Resource$(var.IdSafeLanguage)INSTALLFOLDER" Guid="$(var.CompGUIDPrefix)1F">
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys\components">
<RegistryValue Type="string" Name="Awake_$(var.IdSafeLanguage)_Component" Value="" KeyPath="yes" />
</RegistryKey>
<File Id="Awake_$(var.IdSafeLanguage)_File" Source="$(var.BinDir)\$(var.Language)\PowerToys.Awake.resources.dll" />
</Component>
<Component Id="PowerOCR_$(var.IdSafeLanguage)_Component" Directory="Resource$(var.IdSafeLanguage)INSTALLFOLDER" Guid="$(var.CompGUIDPrefix)20">
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys\components">
<RegistryValue Type="string" Name="PowerOCR_$(var.IdSafeLanguage)_Component" Value="" KeyPath="yes" />
</RegistryKey>
<File Id="PowerOCR_$(var.IdSafeLanguage)_File" Source="$(var.BinDir)\$(var.Language)\PowerToys.PowerOCR.resources.dll" />
</Component>
<Component Id="WorkspacesEditor_$(var.IdSafeLanguage)_Component" Directory="Resource$(var.IdSafeLanguage)INSTALLFOLDER" Guid="$(var.CompGUIDPrefix)21">
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys\components">
<RegistryValue Type="string" Name="WorkspacesEditor_$(var.IdSafeLanguage)_Component" Value="" KeyPath="yes" />
</RegistryKey>
<File Id="WorkspacesEditor_$(var.IdSafeLanguage)_File" Source="$(var.BinDir)\$(var.Language)\PowerToys.WorkspacesEditor.resources.dll" />
</Component>
<?undef IdSafeLanguage?>
<?undef CompGUIDPrefix?>
<?endforeach?>
<?endif?>
<?ifdef env.IsPipeline?>
<Component Id="RemoveResourcesFolder" Guid="9BC0A5A1-CBC5-47C8-8544-3F8A8C0D45F5" Directory="INSTALLFOLDER">
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys\components">
<RegistryValue Type="string" Name="RemoveResourcesFolder" Value="" KeyPath="yes" />
</RegistryKey>
<?foreach Language in $(var.LocLanguageList)?>
<!--NB: Ids can't contain hyphens-->
<?if $(var.Language) = ar-SA?>
<?define IdSafeLanguage = ar_SA?>
<?elseif $(var.Language) = cs-CZ?>
<?define IdSafeLanguage = cs_CZ?>
<?elseif $(var.Language) = de-DE?>
<?define IdSafeLanguage = de_DE?>
<?elseif $(var.Language) = es-ES?>
<?define IdSafeLanguage = es_ES?>
<?elseif $(var.Language) = fa-IR?>
<?define IdSafeLanguage = fa_IR?>
<?elseif $(var.Language) = fr-FR?>
<?define IdSafeLanguage = fr_FR?>
<?elseif $(var.Language) = he-IL?>
<?define IdSafeLanguage = he_IL?>
<?elseif $(var.Language) = hu-HU?>
<?define IdSafeLanguage = hu_HU?>
<?elseif $(var.Language) = it-IT?>
<?define IdSafeLanguage = it_IT?>
<?elseif $(var.Language) = ja-JP?>
<?define IdSafeLanguage = ja_JP?>
<?elseif $(var.Language) = ko-KR?>
<?define IdSafeLanguage = ko_KR?>
<?elseif $(var.Language) = nl-NL?>
<?define IdSafeLanguage = nl_NL?>
<?elseif $(var.Language) = pl-PL?>
<?define IdSafeLanguage = pl_PL?>
<?elseif $(var.Language) = pt-BR?>
<?define IdSafeLanguage = pt_BR?>
<?elseif $(var.Language) = pt-PT?>
<?define IdSafeLanguage = pt_PT?>
<!--
<?elseif $(var.Language) = qps-ploc?>
<?define IdSafeLanguage = qps_ploc?>
<?elseif $(var.Language) = qps-ploca?>
<?define IdSafeLanguage = qps_ploca?>
<?elseif $(var.Language) = qps-plocm?>
<?define IdSafeLanguage = qps_plocm?>
-->
<?elseif $(var.Language) = ru-RU?>
<?define IdSafeLanguage = ru_RU?>
<?elseif $(var.Language) = sv-SE?>
<?define IdSafeLanguage = sv_SE?>
<?elseif $(var.Language) = tr-TR?>
<?define IdSafeLanguage = tr_TR?>
<?elseif $(var.Language) = uk-UA?>
<?define IdSafeLanguage = uk_UA?>
<?elseif $(var.Language) = zh-CN?>
<?define IdSafeLanguage = zh_CN?>
<?elseif $(var.Language) = zh-TW?>
<?define IdSafeLanguage = zh_TW?>
<?else?>
<?define IdSafeLanguage = $(var.Language)?>
<?endif?>
<RemoveFolder Id="RemoveFolderResourcesResource$(var.IdSafeLanguage)INSTALLFOLDER" Directory="Resource$(var.IdSafeLanguage)INSTALLFOLDER" On="uninstall" />
<RemoveFolder Id="RemoveFolderResourcesResource$(var.IdSafeLanguage)CalculatorPluginFolder" Directory="Resource$(var.IdSafeLanguage)CalculatorPluginFolder" On="uninstall" />
<RemoveFolder Id="RemoveFolderResourcesResource$(var.IdSafeLanguage)FolderPluginFolder" Directory="Resource$(var.IdSafeLanguage)FolderPluginFolder" On="uninstall" />
<RemoveFolder Id="RemoveFolderResourcesResource$(var.IdSafeLanguage)ProgramPluginFolder" Directory="Resource$(var.IdSafeLanguage)ProgramPluginFolder" On="uninstall" />
<RemoveFolder Id="RemoveFolderResourcesResource$(var.IdSafeLanguage)ShellPluginFolder" Directory="Resource$(var.IdSafeLanguage)ShellPluginFolder" On="uninstall" />
<RemoveFolder Id="RemoveFolderResourcesResource$(var.IdSafeLanguage)IndexerPluginFolder" Directory="Resource$(var.IdSafeLanguage)IndexerPluginFolder" On="uninstall" />
<RemoveFolder Id="RemoveFolderResourcesResource$(var.IdSafeLanguage)UriPluginFolder" Directory="Resource$(var.IdSafeLanguage)UriPluginFolder" On="uninstall" />
<RemoveFolder Id="RemoveFolderResourcesResource$(var.IdSafeLanguage)VSCodeWorkspacesPluginFolder" Directory="Resource$(var.IdSafeLanguage)VSCodeWorkspacesPluginFolder" On="uninstall" />
<RemoveFolder Id="RemoveFolderResourcesResource$(var.IdSafeLanguage)WindowWalkerPluginFolder" Directory="Resource$(var.IdSafeLanguage)WindowWalkerPluginFolder" On="uninstall" />
<RemoveFolder Id="RemoveFolderResourcesResource$(var.IdSafeLanguage)RegistryPluginFolder" Directory="Resource$(var.IdSafeLanguage)RegistryPluginFolder" On="uninstall" />
<RemoveFolder Id="RemoveFolderResourcesResource$(var.IdSafeLanguage)ServicePluginFolder" Directory="Resource$(var.IdSafeLanguage)ServicePluginFolder" On="uninstall" />
<RemoveFolder Id="RemoveFolderResourcesResource$(var.IdSafeLanguage)SystemPluginFolder" Directory="Resource$(var.IdSafeLanguage)SystemPluginFolder" On="uninstall" />
<RemoveFolder Id="RemoveFolderResourcesResource$(var.IdSafeLanguage)WindowsSettingsPluginFolder" Directory="Resource$(var.IdSafeLanguage)WindowsSettingsPluginFolder" On="uninstall" />
<RemoveFolder Id="RemoveFolderResourcesResource$(var.IdSafeLanguage)WindowsTerminalPluginFolder" Directory="Resource$(var.IdSafeLanguage)WindowsTerminalPluginFolder" On="uninstall" />
<RemoveFolder Id="RemoveFolderResourcesResource$(var.IdSafeLanguage)WebSearchPluginFolder" Directory="Resource$(var.IdSafeLanguage)WebSearchPluginFolder" On="uninstall" />
<RemoveFolder Id="RemoveFolderResourcesResource$(var.IdSafeLanguage)UnitConverterPluginFolder" Directory="Resource$(var.IdSafeLanguage)UnitConverterPluginFolder" On="uninstall" />
<RemoveFolder Id="RemoveFolderResourcesResource$(var.IdSafeLanguage)TimeDatePluginFolder" Directory="Resource$(var.IdSafeLanguage)TimeDatePluginFolder" On="uninstall" />
<RemoveFolder Id="RemoveFolderResourcesResource$(var.IdSafeLanguage)OneNotePluginFolder" Directory="Resource$(var.IdSafeLanguage)OneNotePluginFolder" On="uninstall" />
<RemoveFolder Id="RemoveFolderResourcesResource$(var.IdSafeLanguage)HistoryPluginFolder" Directory="Resource$(var.IdSafeLanguage)HistoryPluginFolder" On="uninstall" />
<RemoveFolder Id="RemoveFolderResourcesResource$(var.IdSafeLanguage)PowerToysPluginFolder" Directory="Resource$(var.IdSafeLanguage)PowerToysPluginFolder" On="uninstall" />
<RemoveFolder Id="RemoveFolderResourcesResource$(var.IdSafeLanguage)ValueGeneratorPluginFolder" Directory="Resource$(var.IdSafeLanguage)ValueGeneratorPluginFolder" On="uninstall" />
<?undef IdSafeLanguage?>
<?endforeach?>
</Component>
<?endif?>
</ComponentGroup>
</Fragment>
</Wix>

View File

@@ -0,0 +1,446 @@
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
<?include $(sys.CURRENTDIR)\Common.wxi?>
<?define launcherImagesComponentFiles=?>
<?define launcherImagesComponentFilesPath=$(var.BinDir)Assets\PowerLauncher\?>
<?define calcComponentFiles=?>
<?define calcComponentFilesPath=$(var.BinDir)RunPlugins\Calculator\?>
<?define calcImagesComponentFiles=?>
<?define calcImagesComponentFilesPath=$(var.BinDir)RunPlugins\Calculator\Images\?>
<?define FolderComponentFiles=?>
<?define FolderComponentFilesPath=$(var.BinDir)RunPlugins\Folder\?>
<?define FolderImagesComponentFiles=?>
<?define FolderImagesComponentFilesPath=$(var.BinDir)RunPlugins\Folder\Images?>
<?define ProgramComponentFiles=?>
<?define ProgramComponentFilesPath=$(var.BinDir)RunPlugins\Program\?>
<?define ProgramImagesComponentFiles=?>
<?define ProgramImagesComponentFilesPath=$(var.BinDir)RunPlugins\Program\Images\?>
<?define ShellComponentFiles=?>
<?define ShellComponentFilesPath=$(var.BinDir)RunPlugins\Shell\?>
<?define ShellImagesComponentFiles=?>
<?define ShellImagesComponentFilesPath=$(var.BinDir)RunPlugins\Shell\Images\?>
<?define IndexerComponentFiles=?>
<?define IndexerComponentFilesPath=$(var.BinDir)RunPlugins\Indexer\?>
<?define IndexerImagesComponentFiles=?>
<?define IndexerImagesComponentFilesPath=$(var.BinDir)RunPlugins\Indexer\Images\?>
<?define UnitConvCompFiles=?>
<?define UnitConvCompFilesPath=$(var.BinDir)RunPlugins\UnitConverter\?>
<?define UnitConvImagesCompFiles=?>
<?define UnitConvImagesCompFilesPath=$(var.BinDir)RunPlugins\UnitConverter\Images\?>
<?define WebSrchCompFiles=?>
<?define WebSrchCompFilesPath=$(var.BinDir)RunPlugins\WebSearch\?>
<?define WebSrchImagesCompFiles=?>
<?define WebSrchImagesCompFilesPath=$(var.BinDir)RunPlugins\WebSearch\Images\?>
<?define HistoryPluginComponentFiles=?>
<?define HistoryPluginComponentFilesPath=$(var.BinDir)RunPlugins\History\?>
<?define HistoryPluginImagesComponentFiles=?>
<?define HistoryPluginImagesComponentFilesPath=$(var.BinDir)RunPlugins\History\Images\?>
<?define UriComponentFiles=?>
<?define UriComponentFilesPath=$(var.BinDir)RunPlugins\Uri\?>
<?define UriImagesComponentFiles=?>
<?define UriImagesComponentFilesPath=$(var.BinDir)RunPlugins\Uri\Images\?>
<?define VSCWrkCompFiles=?>
<?define VSCWrkCompFilesPath=$(var.BinDir)RunPlugins\VSCodeWorkspaces\?>
<?define VSCWrkImagesCompFiles=?>
<?define VSCWrkImagesCompFilesPath=$(var.BinDir)RunPlugins\VSCodeWorkspaces\Images\?>
<?define WindowWlkrCompFiles=?>
<?define WindowWlkrCompFilesPath=$(var.BinDir)RunPlugins\WindowWalker\?>
<?define WindowWlkrImagesCompFiles=?>
<?define WindowWlkrImagesCompFilesPath=$(var.BinDir)RunPlugins\WindowWalker\Images\?>
<?define OneNoteComponentFiles=?>
<?define OneNoteComponentFilesPath=$(var.BinDir)RunPlugins\OneNote\?>
<?define OneNoteImagesComponentFiles=?>
<?define OneNoteImagesComponentFilesPath=$(var.BinDir)RunPlugins\OneNote\Images\?>
<?define RegistryComponentFiles=?>
<?define RegistryComponentFilesPath=$(var.BinDir)RunPlugins\Registry\?>
<?define RegistryImagesComponentFiles=?>
<?define RegistryImagesComponentFilesPath=$(var.BinDir)RunPlugins\Registry\Images\?>
<?define ServiceComponentFiles=?>
<?define ServiceComponentFilesPath=$(var.BinDir)RunPlugins\Service\?>
<?define ServiceImagesComponentFiles=?>
<?define ServiceImagesComponentFilesPath=$(var.BinDir)RunPlugins\Service\Images\?>
<?define SystemComponentFiles=?>
<?define SystemComponentFilesPath=$(var.BinDir)RunPlugins\System\?>
<?define SystemImagesComponentFiles=?>
<?define SystemImagesComponentFilesPath=$(var.BinDir)RunPlugins\System\Images\?>
<?define TimeDateComponentFiles=?>
<?define TimeDateComponentFilesPath=$(var.BinDir)RunPlugins\TimeDate\?>
<?define TimeDateImagesComponentFiles=?>
<?define TimeDateImagesComponentFilesPath=$(var.BinDir)RunPlugins\TimeDate\Images\?>
<?define WinSetCmpFiles=?>
<?define WinSetCmpFilesPath=$(var.BinDir)RunPlugins\WindowsSettings\?>
<?define WinSetImagesCmpFiles=?>
<?define WinSetImagesCmpFilesPath=$(var.BinDir)RunPlugins\WindowsSettings\Images\?>
<?define WinTermCmpFiles=?>
<?define WinTermCmpFilesPath=$(var.BinDir)RunPlugins\WindowsTerminal\?>
<?define WinTermImagesCmpFiles=?>
<?define WinTermImagesCmpFilesPath=$(var.BinDir)RunPlugins\WindowsTerminal\Images\?>
<?define PowerToysCmpFiles=?>
<?define PowerToysCmpFilesPath=$(var.BinDir)RunPlugins\PowerToys\?>
<?define PowerToysImagesCmpFiles=?>
<?define PowerToysImagesCmpFilesPath=$(var.BinDir)RunPlugins\PowerToys\Images\?>
<?define ValueGeneratorCmpFiles=?>
<?define ValueGeneratorCmpFilesPath=$(var.BinDir)RunPlugins\ValueGenerator\?>
<?define ValueGeneratorImagesCmpFiles=?>
<?define ValueGeneratorImagesCmpFilesPath=$(var.BinDir)RunPlugins\ValueGenerator\Images\?>
<Fragment>
<DirectoryRef Id="BaseApplicationsAssetsFolder">
<Directory Id="LauncherImagesFolder" Name="PowerLauncher" />
</DirectoryRef>
<DirectoryRef Id="INSTALLFOLDER">
<!-- Plugins -->
<Directory Id="LauncherPluginsFolder" Name="RunPlugins">
<Directory Id="WebSearchPluginFolder" Name="WebSearch">
<Directory Id="WebSearchImagesFolder" Name="Images" />
</Directory>
<Directory Id="CalculatorPluginFolder" Name="Calculator">
<Directory Id="CalculatorImagesFolder" Name="Images" />
</Directory>
<Directory Id="FolderPluginFolder" Name="Folder">
<Directory Id="FolderPluginImagesFolder" Name="Images" />
</Directory>
<Directory Id="ProgramPluginFolder" Name="Program">
<Directory Id="ProgramImagesFolder" Name="Images" />
</Directory>
<Directory Id="ShellPluginFolder" Name="Shell">
<Directory Id="ShellImagesFolder" Name="Images" />
</Directory>
<Directory Id="IndexerPluginFolder" Name="Indexer">
<Directory Id="IndexerImagesFolder" Name="Images" />
</Directory>
<Directory Id="UriPluginFolder" Name="Uri">
<Directory Id="UriImagesFolder" Name="Images" />
</Directory>
<Directory Id="HistoryPluginFolder" Name="History">
<Directory Id="HistoryImagesFolder" Name="Images" />
</Directory>
<Directory Id="UnitConverterPluginFolder" Name="UnitConverter">
<Directory Id="UnitConverterImagesFolder" Name="Images" />
</Directory>
<Directory Id="VSCodeWorkspacesPluginFolder" Name="VSCodeWorkspaces">
<Directory Id="VSCodeWorkspaceImagesFolder" Name="Images" />
</Directory>
<Directory Id="WindowWalkerPluginFolder" Name="WindowWalker">
<Directory Id="WindowWalkerImagesFolder" Name="Images" />
</Directory>
<Directory Id="OneNotePluginFolder" Name="OneNote">
<Directory Id="OneNoteImagesFolder" Name="Images" />
</Directory>
<Directory Id="PowerToysPluginFolder" Name="PowerToys">
<Directory Id="PowerToysImagesFolder" Name="Images" />
</Directory>
<Directory Id="RegistryPluginFolder" Name="Registry">
<Directory Id="RegistryImagesFolder" Name="Images" />
</Directory>
<Directory Id="ServicePluginFolder" Name="Service">
<Directory Id="ServiceImagesFolder" Name="Images" />
</Directory>
<Directory Id="WindowsTerminalPluginFolder" Name="WindowsTerminal">
<Directory Id="WindowsTerminalImagesFolder" Name="Images" />
</Directory>
<Directory Id="SystemPluginFolder" Name="System">
<Directory Id="SystemImagesFolder" Name="Images" />
</Directory>
<Directory Id="TimeDatePluginFolder" Name="TimeDate">
<Directory Id="TimeDateImagesFolder" Name="Images" />
</Directory>
<Directory Id="WindowsSettingsPluginFolder" Name="WindowsSettings">
<Directory Id="WindowsSettingsImagesFolder" Name="Images" />
</Directory>
<Directory Id="ValueGeneratorPluginFolder" Name="ValueGenerator">
<Directory Id="ValueGeneratorImagesFolder" Name="Images" />
</Directory>
</Directory>
</DirectoryRef>
<DirectoryRef Id="LauncherImagesFolder" FileSource="$(var.launcherImagesComponentFilesPath)">
<!-- Generated by generateFileComponents.ps1 -->
<!--launcherImagesComponentFiles_Component_Def-->
</DirectoryRef>
<!-- Calculator Plugin -->
<DirectoryRef Id="CalculatorPluginFolder" FileSource="$(var.calcComponentFilesPath)">
<!-- Generated by generateFileComponents.ps1 -->
<!--calcComponentFiles_Component_Def-->
</DirectoryRef>
<DirectoryRef Id="CalculatorImagesFolder" FileSource="$(var.calcImagesComponentFilesPath)">
<!-- Generated by generateFileComponents.ps1 -->
<!--calcImagesComponentFiles_Component_Def-->
</DirectoryRef>
<!-- Folder Plugin -->
<DirectoryRef Id="FolderPluginFolder" FileSource="$(var.FolderComponentFilesPath)">
<!-- Generated by generateFileComponents.ps1 -->
<!--FolderComponentFiles_Component_Def-->
</DirectoryRef>
<DirectoryRef Id="FolderPluginImagesFolder" FileSource="$(var.FolderImagesComponentFilesPath)">
<!-- Generated by generateFileComponents.ps1 -->
<!--FolderImagesComponentFiles_Component_Def-->
</DirectoryRef>
<!-- Program Plugin -->
<DirectoryRef Id="ProgramPluginFolder" FileSource="$(var.ProgramComponentFilesPath)">
<!-- Generated by generateFileComponents.ps1 -->
<!--ProgramComponentFiles_Component_Def-->
</DirectoryRef>
<DirectoryRef Id="ProgramImagesFolder" FileSource="$(var.ProgramImagesComponentFilesPath)">
<!-- Generated by generateFileComponents.ps1 -->
<!--ProgramImagesComponentFiles_Component_Def-->
</DirectoryRef>
<!-- Shell Plugin -->
<DirectoryRef Id="ShellPluginFolder" FileSource="$(var.ShellComponentFilesPath)">
<!-- Generated by generateFileComponents.ps1 -->
<!--ShellComponentFiles_Component_Def-->
</DirectoryRef>
<DirectoryRef Id="ShellImagesFolder" FileSource="$(var.ShellImagesComponentFilesPath)">
<!-- Generated by generateFileComponents.ps1 -->
<!--ShellImagesComponentFiles_Component_Def-->
</DirectoryRef>
<!-- Indexer Plugin -->
<DirectoryRef Id="IndexerPluginFolder" FileSource="$(var.IndexerComponentFilesPath)">
<!-- Generated by generateFileComponents.ps1 -->
<!--IndexerComponentFiles_Component_Def-->
</DirectoryRef>
<DirectoryRef Id="IndexerImagesFolder" FileSource="$(var.IndexerImagesComponentFilesPath)">
<!-- Generated by generateFileComponents.ps1 -->
<!--IndexerImagesComponentFiles_Component_Def-->
</DirectoryRef>
<!-- UnitConverter Plugin -->
<DirectoryRef Id="UnitConverterPluginFolder" FileSource="$(var.UnitConvCompFilesPath)">
<!-- Generated by generateFileComponents.ps1 -->
<!--UnitConvCompFiles_Component_Def-->
</DirectoryRef>
<DirectoryRef Id="UnitConverterImagesFolder" FileSource="$(var.UnitConvImagesCompFilesPath)">
<!-- Generated by generateFileComponents.ps1 -->
<!--UnitConvImagesCompFiles_Component_Def-->
</DirectoryRef>
<!-- WebSearch Plugin -->
<DirectoryRef Id="WebSearchPluginFolder" FileSource="$(var.WebSrchCompFilesPath)">
<!-- Generated by generateFileComponents.ps1 -->
<!--WebSrchCompFiles_Component_Def-->
</DirectoryRef>
<DirectoryRef Id="WebSearchImagesFolder" FileSource="$(var.WebSrchImagesCompFilesPath)">
<!-- Generated by generateFileComponents.ps1 -->
<!--WebSrchImagesCompFiles_Component_Def-->
</DirectoryRef>
<!-- History Plugin -->
<DirectoryRef Id="HistoryPluginFolder" FileSource="$(var.HistoryPluginComponentFilesPath)">
<!-- Generated by generateFileComponents.ps1 -->
<!--HistoryPluginComponentFiles_Component_Def-->
</DirectoryRef>
<DirectoryRef Id="HistoryImagesFolder" FileSource="$(var.HistoryPluginImagesComponentFilesPath)">
<!-- Generated by generateFileComponents.ps1 -->
<!--HistoryPluginImagesComponentFiles_Component_Def-->
</DirectoryRef>
<!-- Uri Plugin -->
<DirectoryRef Id="UriPluginFolder" FileSource="$(var.UriComponentFilesPath)">
<!-- Generated by generateFileComponents.ps1 -->
<!--UriComponentFiles_Component_Def-->
</DirectoryRef>
<DirectoryRef Id="UriImagesFolder" FileSource="$(var.UriImagesComponentFilesPath)">
<!-- Generated by generateFileComponents.ps1 -->
<!--UriImagesComponentFiles_Component_Def-->
</DirectoryRef>
<!-- VSCodeWorkspaces Plugin -->
<DirectoryRef Id="VSCodeWorkspacesPluginFolder" FileSource="$(var.VSCWrkCompFilesPath)">
<!-- Generated by generateFileComponents.ps1 -->
<!--VSCWrkCompFiles_Component_Def-->
</DirectoryRef>
<DirectoryRef Id="VSCodeWorkspaceImagesFolder" FileSource="$(var.VSCWrkImagesCompFilesPath)">
<!-- Generated by generateFileComponents.ps1 -->
<!--VSCWrkImagesCompFiles_Component_Def-->
</DirectoryRef>
<!-- WindowWalker Plugin -->
<DirectoryRef Id="WindowWalkerPluginFolder" FileSource="$(var.WindowWlkrCompFilesPath)">
<!-- Generated by generateFileComponents.ps1 -->
<!--WindowWlkrCompFiles_Component_Def-->
</DirectoryRef>
<DirectoryRef Id="WindowWalkerImagesFolder" FileSource="$(var.WindowWlkrImagesCompFilesPath)">
<!-- Generated by generateFileComponents.ps1 -->
<!--WindowWlkrImagesCompFiles_Component_Def-->
</DirectoryRef>
<!-- OneNote Plugin -->
<DirectoryRef Id="OneNotePluginFolder" FileSource="$(var.OneNoteComponentFilesPath)">
<!-- Generated by generateFileComponents.ps1 -->
<!--OneNoteComponentFiles_Component_Def-->
</DirectoryRef>
<DirectoryRef Id="OneNoteImagesFolder" FileSource="$(var.OneNoteImagesComponentFilesPath)">
<!-- Generated by generateFileComponents.ps1 -->
<!--OneNoteImagesComponentFiles_Component_Def-->
</DirectoryRef>
<!-- Registry Plugin -->
<DirectoryRef Id="RegistryPluginFolder" FileSource="$(var.RegistryComponentFilesPath)">
<!-- Generated by generateFileComponents.ps1 -->
<!--RegistryComponentFiles_Component_Def-->
</DirectoryRef>
<DirectoryRef Id="RegistryImagesFolder" FileSource="$(var.RegistryImagesComponentFilesPath)">
<!-- Generated by generateFileComponents.ps1 -->
<!--RegistryImagesComponentFiles_Component_Def-->
</DirectoryRef>
<!-- Service Plugin -->
<DirectoryRef Id="ServicePluginFolder" FileSource="$(var.ServiceComponentFilesPath)">
<!-- Generated by generateFileComponents.ps1 -->
<!--ServiceComponentFiles_Component_Def-->
</DirectoryRef>
<DirectoryRef Id="ServiceImagesFolder" FileSource="$(var.ServiceImagesComponentFilesPath)">
<!-- Generated by generateFileComponents.ps1 -->
<!--ServiceImagesComponentFiles_Component_Def-->
</DirectoryRef>
<!-- System Plugin -->
<DirectoryRef Id="SystemPluginFolder" FileSource="$(var.SystemComponentFilesPath)">
<!-- Generated by generateFileComponents.ps1 -->
<!--SystemComponentFiles_Component_Def-->
</DirectoryRef>
<DirectoryRef Id="SystemImagesFolder" FileSource="$(var.SystemImagesComponentFilesPath)">
<!-- Generated by generateFileComponents.ps1 -->
<!--SystemImagesComponentFiles_Component_Def-->
</DirectoryRef>
<!-- TimeDate Plugin -->
<DirectoryRef Id="TimeDatePluginFolder" FileSource="$(var.TimeDateComponentFilesPath)">
<!-- Generated by generateFileComponents.ps1 -->
<!--TimeDateComponentFiles_Component_Def-->
</DirectoryRef>
<DirectoryRef Id="TimeDateImagesFolder" FileSource="$(var.TimeDateImagesComponentFilesPath)">
<!-- Generated by generateFileComponents.ps1 -->
<!--TimeDateImagesComponentFiles_Component_Def-->
</DirectoryRef>
<!-- WindowsSettings Plugin -->
<DirectoryRef Id="WindowsSettingsPluginFolder" FileSource="$(var.WinSetCmpFilesPath)">
<!-- Generated by generateFileComponents.ps1 -->
<!--WinSetCmpFiles_Component_Def-->
</DirectoryRef>
<DirectoryRef Id="WindowsSettingsImagesFolder" FileSource="$(var.WinSetImagesCmpFilesPath)">
<!-- Generated by generateFileComponents.ps1 -->
<!--WinSetImagesCmpFiles_Component_Def-->
</DirectoryRef>
<!-- WindowsTerminal Plugin -->
<DirectoryRef Id="WindowsTerminalPluginFolder" FileSource="$(var.WinTermCmpFilesPath)">
<!-- Generated by generateFileComponents.ps1 -->
<!--WinTermCmpFiles_Component_Def-->
</DirectoryRef>
<DirectoryRef Id="WindowsTerminalImagesFolder" FileSource="$(var.WinTermImagesCmpFilesPath)">
<!-- Generated by generateFileComponents.ps1 -->
<!--WinTermImagesCmpFiles_Component_Def-->
</DirectoryRef>
<!-- PowerToys Plugin -->
<DirectoryRef Id="PowerToysPluginFolder" FileSource="$(var.PowerToysCmpFilesPath)">
<!-- Generated by generateFileComponents.ps1 -->
<!--PowerToysCmpFiles_Component_Def-->
</DirectoryRef>
<DirectoryRef Id="PowerToysImagesFolder" FileSource="$(var.PowerToysImagesCmpFilesPath)">
<!-- Generated by generateFileComponents.ps1 -->
<!--PowerToysImagesCmpFiles_Component_Def-->
</DirectoryRef>
<DirectoryRef Id="ValueGeneratorPluginFolder" FileSource="$(var.ValueGeneratorCmpFilesPath)">
<!-- Generated by generateFileComponents.ps1 -->
<!--ValueGeneratorCmpFiles_Component_Def-->
</DirectoryRef>
<DirectoryRef Id="ValueGeneratorImagesFolder" FileSource="$(var.ValueGeneratorImagesCmpFilesPath)">
<!-- Generated by generateFileComponents.ps1 -->
<!--ValueGeneratorImagesCmpFiles_Component_Def-->
</DirectoryRef>
<ComponentGroup Id="RunComponentGroup">
<Component Id="RemoveLauncherFolder" Guid="3FFDC0B6-82BC-4C57-AEB1-C710DB108C23" Directory="INSTALLFOLDER">
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys\components">
<RegistryValue Type="string" Name="RemoveLauncherFolder" Value="" KeyPath="yes" />
</RegistryKey>
<RemoveFolder Id="RemoveFolderLauncherImagesFolder" Directory="LauncherImagesFolder" On="uninstall" />
<RemoveFolder Id="RemoveFolderLauncherPluginsFolder" Directory="LauncherPluginsFolder" On="uninstall" />
<RemoveFolder Id="RemoveFolderCalculatorPluginFolder" Directory="CalculatorPluginFolder" On="uninstall" />
<RemoveFolder Id="RemoveFolderCalculatorImagesFolder" Directory="CalculatorImagesFolder" On="uninstall" />
<RemoveFolder Id="RemoveFolderFolderPluginFolder" Directory="FolderPluginFolder" On="uninstall" />
<RemoveFolder Id="RemoveFolderFolderPluginImagesFolder" Directory="FolderPluginImagesFolder" On="uninstall" />
<RemoveFolder Id="RemoveFolderProgramPluginFolder" Directory="ProgramPluginFolder" On="uninstall" />
<RemoveFolder Id="RemoveFolderProgramImagesFolder" Directory="ProgramImagesFolder" On="uninstall" />
<RemoveFolder Id="RemoveFolderShellPluginFolder" Directory="ShellPluginFolder" On="uninstall" />
<RemoveFolder Id="RemoveFolderShellImagesFolder" Directory="ShellImagesFolder" On="uninstall" />
<RemoveFolder Id="RemoveFolderIndexerPluginFolder" Directory="IndexerPluginFolder" On="uninstall" />
<RemoveFolder Id="RemoveFolderIndexerImagesFolder" Directory="IndexerImagesFolder" On="uninstall" />
<RemoveFolder Id="RemoveFolderUnitConverterPluginFolder" Directory="UnitConverterPluginFolder" On="uninstall" />
<RemoveFolder Id="RemoveFolderUnitConverterImagesFolder" Directory="UnitConverterImagesFolder" On="uninstall" />
<RemoveFolder Id="RemoveFolderWebSearchPluginFolder" Directory="WebSearchPluginFolder" On="uninstall" />
<RemoveFolder Id="RemoveFolderWebSearchImagesFolder" Directory="WebSearchImagesFolder" On="uninstall" />
<RemoveFolder Id="RemoveFolderHistoryPluginFolder" Directory="HistoryPluginFolder" On="uninstall" />
<RemoveFolder Id="RemoveFolderHistoryImagesFolder" Directory="HistoryImagesFolder" On="uninstall" />
<RemoveFolder Id="RemoveFolderUriPluginFolder" Directory="UriPluginFolder" On="uninstall" />
<RemoveFolder Id="RemoveFolderUriImagesFolder" Directory="UriImagesFolder" On="uninstall" />
<RemoveFolder Id="RemoveFolderVSCodeWorkspacesPluginFolder" Directory="VSCodeWorkspacesPluginFolder" On="uninstall" />
<RemoveFolder Id="RemoveFolderVSCodeWorkspaceImagesFolder" Directory="VSCodeWorkspaceImagesFolder" On="uninstall" />
<RemoveFolder Id="RemoveFolderWindowWalkerPluginFolder" Directory="WindowWalkerPluginFolder" On="uninstall" />
<RemoveFolder Id="RemoveFolderWindowWalkerImagesFolder" Directory="WindowWalkerImagesFolder" On="uninstall" />
<RemoveFolder Id="RemoveFolderOneNotePluginFolder" Directory="OneNotePluginFolder" On="uninstall" />
<RemoveFolder Id="RemoveFolderOneNoteImagesFolder" Directory="OneNoteImagesFolder" On="uninstall" />
<RemoveFolder Id="RemoveFolderRegistryPluginFolder" Directory="RegistryPluginFolder" On="uninstall" />
<RemoveFolder Id="RemoveFolderRegistryImagesFolder" Directory="RegistryImagesFolder" On="uninstall" />
<RemoveFolder Id="RemoveFolderServicePluginFolder" Directory="ServicePluginFolder" On="uninstall" />
<RemoveFolder Id="RemoveFolderServiceImagesFolder" Directory="ServiceImagesFolder" On="uninstall" />
<RemoveFolder Id="RemoveFolderSystemPluginFolder" Directory="SystemPluginFolder" On="uninstall" />
<RemoveFolder Id="RemoveFolderSystemImagesFolder" Directory="SystemImagesFolder" On="uninstall" />
<RemoveFolder Id="RemoveFolderTimeDatePluginFolder" Directory="TimeDatePluginFolder" On="uninstall" />
<RemoveFolder Id="RemoveFolderTimeDateImagesFolder" Directory="TimeDateImagesFolder" On="uninstall" />
<RemoveFolder Id="RemoveFolderWindowsSettingsPluginFolder" Directory="WindowsSettingsPluginFolder" On="uninstall" />
<RemoveFolder Id="RemoveFolderWindowsSettingsImagesFolder" Directory="WindowsSettingsImagesFolder" On="uninstall" />
<RemoveFolder Id="RemoveFolderWindowsTerminalPluginFolder" Directory="WindowsTerminalPluginFolder" On="uninstall" />
<RemoveFolder Id="RemoveFolderWindowsTerminalImagesFolder" Directory="WindowsTerminalImagesFolder" On="uninstall" />
<RemoveFolder Id="RemoveFolderPowerToysPluginFolder" Directory="PowerToysPluginFolder" On="uninstall" />
<RemoveFolder Id="RemoveFolderPowerToysImagesFolder" Directory="PowerToysImagesFolder" On="uninstall" />
<RemoveFolder Id="RemoveFolderValueGeneratorPluginFolder" Directory="ValueGeneratorPluginFolder" On="uninstall" />
<RemoveFolder Id="RemoveFolderValueGeneratorImagesFolder" Directory="ValueGeneratorImagesFolder" On="uninstall" />
</Component>
</ComponentGroup>
</Fragment>
</Wix>

View File

@@ -0,0 +1,78 @@
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
<?include $(sys.CURRENTDIR)\Common.wxi?>
<?define SettingsV2AssetsFiles=?>
<?define SettingsV2AssetsFilesPath=$(var.BinDir)WinUI3Apps\Assets\Settings\?>
<?define SettingsV2AssetsModulesFiles=?>
<?define SettingsV2AssetsModulesFilesPath=$(var.BinDir)WinUI3Apps\Assets\Settings\Modules\?>
<?define SettingsV2OOBEAssetsModulesFiles=?>
<?define SettingsV2OOBEAssetsModulesFilesPath=$(var.BinDir)WinUI3Apps\Assets\Settings\Modules\OOBE\?>
<?define SettingsV2OOBEAssetsFluentIconsFiles=?>
<?define SettingsV2OOBEAssetsFluentIconsFilesPath=$(var.BinDir)WinUI3Apps\Assets\Settings\Icons\?>
<Fragment>
<DirectoryRef Id="WinUI3AppsAssetsFolder">
<Directory Id="SettingsV2AssetsInstallFolder" Name="Settings">
<Directory Id="SettingsAppAssetsScriptsFolder" Name="Scripts" />
<Directory Id="SettingsV2OOBEAssetsFluentIconsInstallFolder" Name="Icons" />
<Directory Id="SettingsV2AssetsModulesInstallFolder" Name="Modules">
<Directory Id="SettingsV2OOBEAssetsModulesInstallFolder" Name="OOBE" />
</Directory>
</Directory>
</DirectoryRef>
<DirectoryRef Id="SettingsV2AssetsInstallFolder" FileSource="$(var.SettingsV2AssetsFilesPath)">
<!-- Generated by generateFileComponents.ps1 -->
<!--SettingsV2AssetsFiles_Component_Def-->
</DirectoryRef>
<DirectoryRef Id="SettingsV2AssetsModulesInstallFolder" FileSource="$(var.SettingsV2AssetsModulesFilesPath)">
<!-- Generated by generateFileComponents.ps1 -->
<!--SettingsV2AssetsModulesFiles_Component_Def-->
</DirectoryRef>
<DirectoryRef Id="SettingsV2OOBEAssetsModulesInstallFolder" FileSource="$(var.SettingsV2OOBEAssetsModulesFilesPath)">
<!-- Generated by generateFileComponents.ps1 -->
<!--SettingsV2OOBEAssetsModulesFiles_Component_Def-->
</DirectoryRef>
<DirectoryRef Id="SettingsV2OOBEAssetsFluentIconsInstallFolder" FileSource="$(var.SettingsV2OOBEAssetsFluentIconsFilesPath)">
<!-- Generated by generateFileComponents.ps1 -->
<!--SettingsV2OOBEAssetsFluentIconsFiles_Component_Def-->
</DirectoryRef>
<DirectoryRef Id="SettingsAppAssetsScriptsFolder" FileSource="$(var.SettingsV2AssetsFilesPath)\Scripts\">
<Component Id="CommandNotFound_Scripts" Guid="898EFA1E-EDD3-4F4B-8C7F-4A14B0D05B02" Bitness="always64">
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys\components">
<RegistryValue Type="string" Name="CommandNotFound_Scripts" Value="" KeyPath="yes" />
</RegistryKey>
<File Id="CommandNotFound_Scripts_EnableModule.ps1" Source="$(var.SettingsV2AssetsFilesPath)\Scripts\EnableModule.ps1" />
<File Id="CommandNotFound_Scripts_UpgradeModule.ps1" Source="$(var.SettingsV2AssetsFilesPath)\Scripts\UpgradeModule.ps1" />
<File Id="CommandNotFound_Scripts_DisableModule.ps1" Source="$(var.SettingsV2AssetsFilesPath)\Scripts\DisableModule.ps1" />
<File Id="CommandNotFound_Scripts_CheckCmdNotFoundRequirements.ps1" Source="$(var.SettingsV2AssetsFilesPath)\Scripts\CheckCmdNotFoundRequirements.ps1" />
<File Id="CommandNotFound_Scripts_InstallWinGetClientModule.ps1" Source="$(var.SettingsV2AssetsFilesPath)\Scripts\InstallWinGetClientModule.ps1" />
<File Id="CommandNotFound_Scripts_InstallPowerShell7.ps1" Source="$(var.SettingsV2AssetsFilesPath)\Scripts\InstallPowerShell7.ps1" />
</Component>
</DirectoryRef>
<ComponentGroup Id="SettingsComponentGroup">
<Component Id="RemoveSettingsFolder" Guid="2D3AEF68-4E5A-4FF9-A5C0-9E53391AC754" Directory="SettingsV2AssetsInstallFolder">
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys\components">
<RegistryValue Type="string" Name="RemoveSettingsFolder" Value="" KeyPath="yes" />
</RegistryKey>
<RemoveFolder Id="RemoveFolderSettingsV2AssetsInstallFolder" Directory="SettingsV2AssetsInstallFolder" On="uninstall" />
<RemoveFolder Id="RemoveFolderSettingsV2OOBEAssetsFluentIconsInstallFolder" Directory="SettingsV2OOBEAssetsFluentIconsInstallFolder" On="uninstall" />
<RemoveFolder Id="RemoveFolderSettingsV2AssetsModulesInstallFolder" Directory="SettingsV2AssetsModulesInstallFolder" On="uninstall" />
<RemoveFolder Id="RemoveFolderSettingsV2OOBEAssetsModulesInstallFolder" Directory="SettingsV2OOBEAssetsModulesInstallFolder" On="uninstall" />
<RemoveFolder Id="RemoveFolderSettingsAppAssetsScriptsFolder" Directory="SettingsAppAssetsScriptsFolder" On="uninstall" />
</Component>
<ComponentRef Id="CommandNotFound_Scripts" />
</ComponentGroup>
</Fragment>
</Wix>

View File

@@ -0,0 +1,29 @@
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
<?include $(sys.CURRENTDIR)\Common.wxi?>
<?define ShortcutGuideSvgFiles=?>
<?define ShortcutGuideSvgFilesPath=$(var.BinDir)\Assets\ShortcutGuide\?>
<Fragment>
<!-- Shortcut guide files -->
<DirectoryRef Id="BaseApplicationsAssetsFolder">
<Directory Id="ShortcutGuideSvgsInstallFolder" Name="ShortcutGuide" />
</DirectoryRef>
<DirectoryRef Id="ShortcutGuideSvgsInstallFolder" FileSource="$(var.ShortcutGuideSvgFilesPath)">
<!-- Generated by generateFileComponents.ps1 -->
<!--ShortcutGuideSvgFiles_Component_Def-->
</DirectoryRef>
<!-- Shortcut guide -->
<ComponentGroup Id="ShortcutGuideComponentGroup">
<Component Id="RemoveShortcutGuideFolder" Guid="AD1ABC55-B593-4A60-A86A-BA8C0ED493A5" Directory="ShortcutGuideSvgsInstallFolder">
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys\components">
<RegistryValue Type="string" Name="RemoveShortcutGuideFolder" Value="" KeyPath="yes" />
</RegistryKey>
<RemoveFolder Id="RemoveFolderShortcutGuideSvgsInstallFolder" Directory="ShortcutGuideSvgsInstallFolder" On="uninstall" />
</Component>
</ComponentGroup>
</Fragment>
</Wix>

View File

@@ -0,0 +1,47 @@
# PowerShell script to list all files in the SilentFilesInUseBA directory
# Usage: .\ListFiles.ps1
$directory = "c:\PowerToys\installer\PowerToysSetupVNext\SilentFilesInUseBA"
Write-Host "=== Files in SilentFilesInUseBA Directory ===" -ForegroundColor Green
Write-Host "Directory: $directory" -ForegroundColor Yellow
Write-Host ""
if (Test-Path $directory) {
# Get all files (not directories) recursively
$files = Get-ChildItem -Path $directory -File -Recurse | Sort-Object FullName
if ($files.Count -eq 0) {
Write-Host "No files found in the directory." -ForegroundColor Red
} else {
Write-Host "Found $($files.Count) file(s):" -ForegroundColor Cyan
Write-Host ""
foreach ($file in $files) {
$relativePath = $file.FullName.Replace($directory, "").TrimStart('\')
$size = if ($file.Length -lt 1KB) { "$($file.Length) bytes" }
elseif ($file.Length -lt 1MB) { "{0:N1} KB" -f ($file.Length / 1KB) }
else { "{0:N1} MB" -f ($file.Length / 1MB) }
Write-Host " $relativePath" -ForegroundColor White
Write-Host " Size: $size" -ForegroundColor Gray
Write-Host " Modified: $($file.LastWriteTime.ToString('yyyy-MM-dd HH:mm:ss'))" -ForegroundColor Gray
Write-Host ""
}
}
# Also list directories
$directories = Get-ChildItem -Path $directory -Directory -Recurse | Sort-Object FullName
if ($directories.Count -gt 0) {
Write-Host "Directories found:" -ForegroundColor Cyan
foreach ($dir in $directories) {
$relativePath = $dir.FullName.Replace($directory, "").TrimStart('\')
Write-Host " $relativePath\" -ForegroundColor Magenta
}
}
} else {
Write-Host "Directory does not exist: $directory" -ForegroundColor Red
}
Write-Host ""
Write-Host "=== End of File List ===" -ForegroundColor Green

Some files were not shown because too many files have changed in this diff Show More