Skip to content

[WiX 5] Migrate SDK from v3 to v5 #48699

New issue

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

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

Already on GitHub? Sign in to your account

Merged
merged 56 commits into from
Jul 26, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
1a383a9
Add WiX SDK to global.json
joeloff Apr 24, 2025
78ef998
Add WiX packages for CPM
joeloff Apr 24, 2025
0498cc7
Add WiX files to editor config
joeloff Apr 24, 2025
fbeaf9a
Add directory fragment
joeloff Apr 24, 2025
ba026e9
Rename and convert provider key fragment to v5
joeloff Apr 24, 2025
5376bce
Add project to generate targets for .wixproj
joeloff May 1, 2025
93d82c2
Add .wxl to .editorconfig
joeloff May 2, 2025
6097207
Add .wixproj for SDK placeholder MSI
joeloff May 3, 2025
1174585
Delete old placeholder source
joeloff May 3, 2025
13575cf
Delete placeholder MSI targets, .ps1
joeloff May 3, 2025
eae53c7
Merge branch 'main' into wix5
joeloff May 12, 2025
53f8f29
Condition DefineConstants for non-Wix projects
joeloff May 13, 2025
6538603
Replace dotnethome_x64.wxs with Arcade copy
joeloff May 13, 2025
1d85ec3
Generalize GenerateUpgradeCode and RenameOutput targets
joeloff May 15, 2025
597e613
Onboard templates and toolset MSIs
joeloff May 22, 2025
0d0e221
Convert .wxl files to v4 schema
joeloff May 22, 2025
9f1b031
Local upgradePolicies source to work around Arcade issue
joeloff May 23, 2025
0cf48df
Migrate bundle, 1st pass and cleanup
joeloff May 23, 2025
86563a2
Bundle UI changes
joeloff May 27, 2025
9b8cc2c
Fix bundle output path
joeloff May 27, 2025
dba9968
Set OutputPath/OutputName to avoid copying files
joeloff May 27, 2025
e254b01
Cleanup code
joeloff May 27, 2025
83e34db
Fix local builds when alternating -pack option
joeloff May 28, 2025
d8116cd
Clarify unconditional include
joeloff May 28, 2025
1cf816c
Merge branch 'main' into wix5
joeloff May 28, 2025
05bc7fc
Add workload manifests to bundle
joeloff May 28, 2025
7f30869
Update WiX package version
joeloff Jun 13, 2025
81a0bf6
Add theme files to editorconfig
joeloff Jun 13, 2025
89bcde4
UI changes and authoring updates
joeloff Jun 13, 2025
2a195d0
Delete old copy of .NET bundle
joeloff Jun 13, 2025
be170d3
Use dotnet.ico for MSIs
joeloff Jun 13, 2025
75b67aa
Merge branch 'main' into wix5
joeloff Jun 13, 2025
f518704
Add .ico file for thmviewer
joeloff Jun 13, 2025
ae28b5b
UI changes
joeloff Jun 17, 2025
8948dac
Update comment
joeloff Jun 17, 2025
bb4137a
Merge branch 'main' into wix5
joeloff Jun 17, 2025
32ede71
Remove Arcade work-around and include file
joeloff Jun 17, 2025
d2941f4
Remove .wxi references
joeloff Jun 17, 2025
e86002d
Remove control frame
joeloff Jun 18, 2025
77e98af
Ensure bundles are always x86
joeloff Jun 18, 2025
c464656
clean up formatting
joeloff Jun 19, 2025
7575954
Merge main
joeloff Jun 19, 2025
1109be8
Update finalizer
joeloff Jun 19, 2025
c6be598
Update modify text
joeloff Jun 19, 2025
f1f9ba8
Update FilesInUse strings
joeloff Jun 26, 2025
17dbaf3
Update WiX build
joeloff Jun 26, 2025
035903c
Merge main
joeloff Jun 26, 2025
d908c78
Merge branch 'main' into wix5
joeloff Jul 17, 2025
8bc686c
Update to latest Arcade, add CreateWixBuildWixpack
joeloff Jul 18, 2025
84e034b
Merge main
joeloff Jul 18, 2025
135f19c
Remove version override
joeloff Jul 21, 2025
c42e1c7
Update src/Layout/redist/targets/GenerateMSIs.targets
joeloff Jul 21, 2025
bf3363d
Update src/Layout/pkg/windows/bundles/sdk/LCID/1033/bundle.wxl
joeloff Jul 21, 2025
dabe3a7
Update src/Layout/pkg/dotnet-sdk.proj
joeloff Jul 25, 2025
57a4dda
Merge branch 'main' into wix5
joeloff Jul 25, 2025
9843cb1
PR feedback
joeloff Jul 26, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -475,6 +475,10 @@ indent_brace_style = Allman
[*.{csproj,vbproj,vcxproj,vcxproj.filters,proj,nativeproj,locproj}]
indent_size = 2

# WiX files
[*.{wixproj,wxs,wxi,wxl,thm}]
indent_size = 2

[*.{csproj,vbproj,proj,nativeproj,locproj}]
charset = utf-8-bom

Expand Down
5 changes: 5 additions & 0 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,11 @@
<PackageVersion Include="Microsoft.Web.Xdt" Version="$(MicrosoftWebXdtPackageVersion)" />
<PackageVersion Include="Microsoft.Win32.SystemEvents" Version="$(MicrosoftWin32SystemEventsPackageVersion)" />
<PackageVersion Include="Microsoft.Windows.CsWin32" Version="$(MicrosoftWindowsCsWin32PackageVersion)" />
<PackageVersion Include="Microsoft.WixToolset.Bal.wixext" Version="$(MicrosoftWixToolsetVersion)" />
<PackageVersion Include="Microsoft.WixToolset.Dependency.wixext" Version="$(MicrosoftWixToolsetVersion)" />
<PackageVersion Include="Microsoft.WixToolset.Heat" Version="$(MicrosoftWixToolsetVersion)" />
<PackageVersion Include="Microsoft.WixToolset.Util.wixext" Version="$(MicrosoftWixToolsetVersion)" />
<PackageVersion Include="Microsoft.WixToolset.UI.wixext" Version="$(MicrosoftWixToolsetVersion)" />
<PackageVersion Include="MSBuild.StructuredLogger" Version="2.2.386" />
<PackageVersion Include="Moq" Version="$(MoqPackageVersion)" />
<PackageVersion Include="NETStandard.Library.NETFramework" Version="$(NETStandardLibraryNETFrameworkVersion)" />
Expand Down
6 changes: 5 additions & 1 deletion build.cmd
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
@echo off

setlocal

echo %* | findstr /C:"-pack" >nul
if %errorlevel%==0 (
set SkipBuildingInstallers=
set skipFlags="/p:SkipUsingCrossgen=false /p:SkipBuildingInstallers=false"
) else (
REM skip crossgen for inner-loop builds to save a ton of time
set skipFlags="/p:SkipUsingCrossgen=true /p:SkipBuildingInstallers=true"
)
set DOTNET_SYSTEM_NET_SECURITY_NOREVOCATIONCHECKBYDEFAULT=true
powershell -NoLogo -NoProfile -ExecutionPolicy ByPass -command "& """%~dp0eng\common\build.ps1""" -restore -build -msbuildEngine dotnet %skipFlags% %*"

endlocal
exit /b %ErrorLevel%
3 changes: 2 additions & 1 deletion global.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.25373.106",
"Microsoft.DotNet.Helix.Sdk": "10.0.0-beta.25373.106",
"Microsoft.Build.NoTargets": "3.7.0",
"Microsoft.Build.Traversal": "3.4.0"
"Microsoft.Build.Traversal": "3.4.0",
"Microsoft.WixToolset.Sdk": "5.0.2-dotnet.2737382"
}
}
11 changes: 10 additions & 1 deletion src/Layout/finalizer/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@
using Microsoft.Win32;
using Microsoft.Win32.Msi;

if (args.Length < 3)
if (args.Length < 4)
{
return (int)Error.INVALID_COMMAND_LINE;
}

string logPath = args[0];
string sdkVersion = args[1];
string platform = args[2];
int bundleAction = Convert.ToInt32(args[3]);

using StreamWriter logStream = new StreamWriter(logPath);

Expand All @@ -21,8 +22,16 @@
Logger.Log($"{nameof(logPath)}: {logPath}");
Logger.Log($"{nameof(sdkVersion)}: {sdkVersion}");
Logger.Log($"{nameof(platform)}: {platform}");
Logger.Log($"{nameof(bundleAction)}: {bundleAction}");
int exitCode = (int)Error.SUCCESS;

// The finalizer should only run when the parent bundle is being removed if WixBundleAction is set to BOOTSTRAPPER_ACTION_UNINSTALL
// or BOOTSTRAPPER_ACTION_UNSAFE_UNINSTALL.
if (bundleAction < 3 || bundleAction > 4)
{
return exitCode;
}

try
{
// Step 1: Parse and format SDK feature band version
Expand Down
18 changes: 17 additions & 1 deletion src/Layout/pkg/dotnet-sdk.proj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.Build.NoTargets">
<Project Sdk="Microsoft.Build.NoTargets">

<PropertyGroup>
<BuildSdkRpm Condition="'$(BuildSdkRpm)' == '' and '$(IsRPMBasedDistro)' == 'true'">true</BuildSdkRpm>
Expand Down Expand Up @@ -33,6 +33,22 @@

<ItemGroup>
<ProjectReference Include="..\redist\redist.csproj" ReferenceOutputAssembly="false" />
</ItemGroup>

<ItemGroup Condition="'$(OS)' == 'Windows_NT'">
<!-- These project references ensure that package references for WiX extensions are correctly restored. The Idle target is a no-op as the
projects are built later when computed properties are available. These properties do not exist when projects are evaluated. -->
Comment on lines +39 to +40
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a crazy "hack". I've never seen that Idle target used before. Is this something @rainersigwald suggested?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, @rainersigwald and I chatted about this. The problem with invoking msbuild tasks is that restore gets broken. I spent a couple of weeks prototyping different approaches. This is the only solution that allows restore to work and have a consistent MSBuild SDK experience. The alternative is to move back to the WiX CLI, basically do what the .ps1 scripts used to do. And after talking to Rob (from WiX toolset), he mentioned that the SDK style approach is the preferred way.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Submitted #49964 as a clean-up

<ProjectReference Include="windows\msis\placeholder\placeholder.wixproj" ReferenceOutputAssembly="false" SkipGetTargetFrameworkProperties="true"
Targets="Idle" />
<ProjectReference Include="windows\msis\templates\templates.wixproj" ReferenceOutputAssembly="false" SkipGetTargetFrameworkProperties="true"
Targets="Idle" />
<ProjectReference Include="windows\msis\toolset\toolset.wixproj" ReferenceOutputAssembly="false" SkipGetTargetFrameworkProperties="true"
Targets="Idle" />
<ProjectReference Include="windows\bundles\sdk\bundle.wixproj" ReferenceOutputAssembly="false" SkipGetTargetFrameworkProperties="true"
Targets="Idle" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.DotNet.Build.Tasks.Installers" />
</ItemGroup>

Expand Down
28 changes: 28 additions & 0 deletions src/Layout/pkg/windows/Directory.Build.props
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the MIT license. See License.txt in the project root for full license information. -->
<Project>
<Import Project="$([MSBuild]::GetPathOfFileAbove('Directory.Build.props', '$(MSBuildThisFileDirectory)../'))" />

<PropertyGroup>
<!-- Currently, WiX only supports 'full' for the -pdbType option. This affects both bundle and package projects. -->
<DebugType>full</DebugType>

<!-- .wixproj defaults to AnyCPU which eventually defaults to x86. InstallerPlatform determines the bitness of
the installer and should always match for MSIs. For bundles, we have to remain on x86. -->
<InstallerPlatform Condition="'$(InstallerPlatform)' == ''">$(TargetArchitecture)</InstallerPlatform>
<Platform>$(InstallerPlatform)</Platform>
<PlatformName>$(InstallerPlatform)</PlatformName>
</PropertyGroup>

<PropertyGroup Condition="'$(MSBuildProjectExtension)' == '.wixproj'">
<DefineConstants>$(DefineConstants);SdkFeatureBandVersion=$(CliProductBandVersion)00</DefineConstants>
<DefineConstants>$(DefineConstants);ProductLanguage=1033</DefineConstants>
<DefineConstants>$(DefineConstants);Manufacturer=Microsoft Corporation</DefineConstants>
<DefineConstants>$(DefineConstants);MajorVersion=$(VersionMajor)</DefineConstants>
<DefineConstants>$(DefineConstants);MinorVersion=$(VersionMinor)</DefineConstants>
<DefineConstants>$(DefineConstants);TargetArchitecture=$(TargetArchitecture)</DefineConstants>

<!-- Technically we don't support .NET on any version of Windows where the version of Windows Installer is less than 5.0. -->
<DefineConstants Condition="'$(InstallerPlatform)' != 'arm64'">$(DefineConstants);InstallerVersion=200</DefineConstants>
<DefineConstants Condition="'$(InstallerPlatform)' == 'arm64'">$(DefineConstants);InstallerVersion=500</DefineConstants>
</PropertyGroup>
</Project>
73 changes: 73 additions & 0 deletions src/Layout/pkg/windows/Directory.Build.targets
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the MIT license. See License.txt in the project root for full license information. -->
<Project>
<Import Project="$([MSBuild]::GetPathOfFileAbove('Directory.Build.targets', '$(MSBuildThisFileDirectory)../'))" />

<PropertyGroup Condition="'$(MSBuildProjectExtension)' == '.wixproj'">
<!-- Example: Microsoft .NET SDK 10.0.100 -->
<DefineConstants>$(DefineConstants);SdkBrandName=$(SdkBrandName)</DefineConstants>
<!-- Example: Microsoft .NET SDK 10.0.100 (x64) -->
<DefineConstants>$(DefineConstants);SdkPlatformBrandName=$(SdkBrandName) ($(TargetArchitecture))</DefineConstants>

<!-- NativeMachine values match the expected values for image file machine constants
https://docs.microsoft.com/en-us/windows/win32/sysinfo/image-file-machine-constants -->
<DefineConstants>$(DefineConstants);NativeMachine_x86=332</DefineConstants>
<DefineConstants>$(DefineConstants);NativeMachine_x64=34404</DefineConstants>
<DefineConstants>$(DefineConstants);NativeMachine_arm64=43620</DefineConstants>

<!-- This is the full semenatic version of the SDK. -->
<DefineConstants>$(DefineConstants);Version=$(Version)</DefineConstants>
<!-- BundleVersion is used by MSIs when generating provider keys, but ProductVersion is never used when generating bundles. -->
<DefineConstants Condition="'$(ProductVersion)' != ''">$(DefineConstants);ProductVersion=$(ProductVersion)</DefineConstants>
<DefineConstants Condition="'$(BundleVersion)' != ''">$(DefineConstants);BundleVersion=$(BundleVersion)</DefineConstants>
</PropertyGroup>

<!-- MSI upgrade codes are generated based on the name of the installer, which typically includes the version and platform information. -->
<Target Name="GenerateUpgradeCode" BeforeTargets="CoreCompile">
<Error Condition="'$(InstallerPath)' == '' AND '$(UpgradeCode)' == ''"
Text="Unable to compute UpgradeCode. The InstallerPath property is not set." />

<!-- Only use the file name when generating the GUID. Full paths may be inconsistent across different build environments. -->
<GenerateGuidFromName Name="$([System.IO.Path]::GetFileName($(InstallerPath)))" Condition="'$(UpgradeCode)' == ''">
<Output TaskParameter="GeneratedGuid" PropertyName="UpgradeCode" />
</GenerateGuidFromName>

<PropertyGroup>
<DefineConstants>$(DefineConstants);UpgradeCode=$(UpgradeCode)</DefineConstants>
</PropertyGroup>
</Target>

<!-- This target does nothing. It's intended to allow ProjectReference items to specify a target that has
no build impact, but allow projects to participate in restore operations. -->
<Target Name="Idle" />

<!-- This target is intended to catch changes that require someone to investigate. -->
<Target Name="ValidateBuild" BeforeTargets="CoreCompile">
<!-- Bundles must target x86 for back compat. -->
<Error Condition="'$(OutputType)' == 'Bundle' AND '$(InstallerPlatform)' != 'x86'"
Text="Bundles must target x86. InstallerPlatform=$(InstallerPlatform)" />
</Target>

<Target Name="GenerateWixpackPackage" AfterTargets="CoreCompile">
<PropertyGroup>
<WixpackWorkingDir>$(IntermediateOutputPath)wixpack</WixpackWorkingDir>
<WixpackOutputDir>$(ArtifactsNonShippingPackagesDir)</WixpackOutputDir>
</PropertyGroup>

<CreateWixBuildWixpack
BindTrackingFile="$(IntermediateOutputPath)$(BindTrackingFilePrefix)%(CultureGroup.OutputSuffix)$(BindTrackingFileExtension)"
Cultures="%(CultureGroup.Identity)"
DefineConstants="$(DefineConstants);$(SolutionDefineConstants);$(ProjectDefineConstants);$(ProjectReferenceDefineConstants)"
Extensions="@(_ResolvedWixExtensionPaths)"
InstallerPlatform="$(InstallerPlatform)"
InstallerFile="$(IntermediateOutputPath)%(CultureGroup.OutputFolder)$(TargetFileName)"
IntermediateDirectory="$(IntermediateOutputPath)%(CultureGroup.OutputFolder)"
OutputFolder="$(WixpackOutputDir)"
OutputType="$(OutputType)"
PdbFile="$(IntermediateOutputPath)%(CultureGroup.OutputFolder)$(TargetPdbFileName)"
PdbType="$(DebugType)"
SourceFiles="@(Compile)"
WixpackWorkingDir="$(WixpackWorkingDir)">
<Output TaskParameter="OutputFile" PropertyName="_WixBuildCommandPackageNameOutput" />
</CreateWixBuildWixpack>
</Target>
</Project>
84 changes: 0 additions & 84 deletions src/Layout/pkg/windows/LCID/1028/bundle.wxl

This file was deleted.

Loading