aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSean Hall <r.sean.hall@gmail.com>2021-03-28 14:51:21 -0500
committerSean Hall <r.sean.hall@gmail.com>2021-03-30 16:05:00 -0500
commit3221757bb210b23e4c8d859d20aa20b43c0df582 (patch)
tree4391705303589d48a5f93ac1ba9c5701c9daeba7
parent7cc4271c9d78ed60e354f585d03b612a9efb7cf3 (diff)
downloadwix-3221757bb210b23e4c8d859d20aa20b43c0df582.tar.gz
wix-3221757bb210b23e4c8d859d20aa20b43c0df582.tar.bz2
wix-3221757bb210b23e4c8d859d20aa20b43c0df582.zip
Port the update bundle tests from old repo.
-rw-r--r--src/TestBA/TestBA.cs11
-rw-r--r--src/TestData/Templates/PackagePerUser.wxs3
-rw-r--r--src/TestData/UpdateBundleTests/BundleAv1/BundleA.props10
-rw-r--r--src/TestData/UpdateBundleTests/BundleAv1/BundleAv1.wixproj12
-rw-r--r--src/TestData/UpdateBundleTests/BundleAv1/BundleAv1.wxs10
-rw-r--r--src/TestData/UpdateBundleTests/BundleAv2/BundleAv2.wixproj15
-rw-r--r--src/TestData/UpdateBundleTests/BundleAv2/BundleAv2.wxs10
-rw-r--r--src/TestData/UpdateBundleTests/BundleBv1/Bundle.wxs42
-rw-r--r--src/TestData/UpdateBundleTests/BundleBv1/BundleB.props7
-rw-r--r--src/TestData/UpdateBundleTests/BundleBv1/BundleBv1.wixproj18
-rw-r--r--src/TestData/UpdateBundleTests/BundleBv1/BundleBv1.wxs10
-rw-r--r--src/TestData/UpdateBundleTests/BundleBv1/FeedBv1.0.xml32
-rw-r--r--src/TestData/UpdateBundleTests/BundleBv1/FeedBv2.0.xml51
-rw-r--r--src/TestData/UpdateBundleTests/BundleBv2/BundleBv2.wixproj18
-rw-r--r--src/TestData/UpdateBundleTests/BundleBv2/BundleBv2.wxs10
-rw-r--r--src/TestData/UpdateBundleTests/PackageAv1/PackageA.props9
-rw-r--r--src/TestData/UpdateBundleTests/PackageAv1/PackageAv1.wixproj4
-rw-r--r--src/TestData/UpdateBundleTests/PackageAv2/PackageAv2.wixproj7
-rw-r--r--src/TestData/UpdateBundleTests/PackageBv1/PackageB.props9
-rw-r--r--src/TestData/UpdateBundleTests/PackageBv1/PackageBv1.wixproj4
-rw-r--r--src/TestData/UpdateBundleTests/PackageBv2/PackageBv2.wixproj7
-rw-r--r--src/Wix.Build.targets3
-rw-r--r--src/WixToolsetTest.BurnE2E/BurnE2ETests.cs7
-rw-r--r--src/WixToolsetTest.BurnE2E/IWebServer.cs20
-rw-r--r--src/WixToolsetTest.BurnE2E/TestBAController.cs6
-rw-r--r--src/WixToolsetTest.BurnE2E/UpdateBundleTests.cs245
-rw-r--r--src/WixToolsetTest.BurnE2E/WebServer/CoreOwinWebServer.cs69
-rw-r--r--src/WixToolsetTest.BurnE2E/WixToolsetTest.BurnE2E.csproj3
28 files changed, 640 insertions, 12 deletions
diff --git a/src/TestBA/TestBA.cs b/src/TestBA/TestBA.cs
index f86a5807..18b1fd0c 100644
--- a/src/TestBA/TestBA.cs
+++ b/src/TestBA/TestBA.cs
@@ -178,20 +178,15 @@ namespace WixToolset.Test.BA
178 { 178 {
179 // The list of updates is sorted in descending version, so the first callback should be the largest update available. 179 // The list of updates is sorted in descending version, so the first callback should be the largest update available.
180 // This update should be either larger than ours (so we are out of date), the same as ours (so we are current) 180 // This update should be either larger than ours (so we are out of date), the same as ours (so we are current)
181 // or smaller than ours (we have a private build). If we really wanted to, we could leave the e.StopProcessingUpdates alone and 181 // or smaller than ours (we have a private build).
182 // enumerate all of the updates. 182 // Enumerate all of the updates anyway in case something's broken.
183 this.Log(String.Format("Potential update v{0} from '{1}'; current version: v{2}", e.Version, e.UpdateLocation, this.Version)); 183 this.Log(String.Format("Potential update v{0} from '{1}'; current version: v{2}", e.Version, e.UpdateLocation, this.Version));
184 if (this.Engine.CompareVersions(e.Version, this.Version) > 0) 184 if (!this.UpdateAvailable && this.Engine.CompareVersions(e.Version, this.Version) > 0)
185 { 185 {
186 this.Log(String.Format("Selected update v{0}", e.Version)); 186 this.Log(String.Format("Selected update v{0}", e.Version));
187 this.Engine.SetUpdate(null, e.UpdateLocation, e.Size, UpdateHashType.None, null); 187 this.Engine.SetUpdate(null, e.UpdateLocation, e.Size, UpdateHashType.None, null);
188 this.UpdateAvailable = true; 188 this.UpdateAvailable = true;
189 } 189 }
190 else
191 {
192 this.UpdateAvailable = false;
193 }
194 e.StopProcessingUpdates = true;
195 } 190 }
196 191
197 protected override void OnDetectUpdateComplete(DetectUpdateCompleteEventArgs e) 192 protected override void OnDetectUpdateComplete(DetectUpdateCompleteEventArgs e)
diff --git a/src/TestData/Templates/PackagePerUser.wxs b/src/TestData/Templates/PackagePerUser.wxs
index e985966c..25133fb4 100644
--- a/src/TestData/Templates/PackagePerUser.wxs
+++ b/src/TestData/Templates/PackagePerUser.wxs
@@ -36,8 +36,7 @@
36 36
37 <Fragment> 37 <Fragment>
38 <Directory Id="TARGETDIR" Name="SourceDir"> 38 <Directory Id="TARGETDIR" Name="SourceDir">
39 <Directory Id="LocalAppDataFolder" /> 39 <Directory Id="LocalAppDataFolder">
40 <Directory Id="ProgramFilesFolder">
41 <Directory Id="WixDir" Name="~Test WiX"> 40 <Directory Id="WixDir" Name="~Test WiX">
42 <Directory Id="TestDir" Name="$(var.TestGroupName)"> 41 <Directory Id="TestDir" Name="$(var.TestGroupName)">
43 <Directory Id="INSTALLFOLDER" Name="$(var.PackageName)" /> 42 <Directory Id="INSTALLFOLDER" Name="$(var.PackageName)" />
diff --git a/src/TestData/UpdateBundleTests/BundleAv1/BundleA.props b/src/TestData/UpdateBundleTests/BundleAv1/BundleA.props
new file mode 100644
index 00000000..19b37770
--- /dev/null
+++ b/src/TestData/UpdateBundleTests/BundleAv1/BundleA.props
@@ -0,0 +1,10 @@
1<!-- 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. -->
2<Project>
3 <PropertyGroup>
4 <OutputType>Bundle</OutputType>
5 <UpgradeCode>{AF745E41-CEAC-4C9F-83D8-663BAB1AF5CC}</UpgradeCode>
6 </PropertyGroup>
7 <ItemGroup>
8 <Compile Include="..\..\Templates\Bundle.wxs" Link="Bundle.wxs" />
9 </ItemGroup>
10</Project>
diff --git a/src/TestData/UpdateBundleTests/BundleAv1/BundleAv1.wixproj b/src/TestData/UpdateBundleTests/BundleAv1/BundleAv1.wixproj
new file mode 100644
index 00000000..69d0408f
--- /dev/null
+++ b/src/TestData/UpdateBundleTests/BundleAv1/BundleAv1.wixproj
@@ -0,0 +1,12 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <Import Project="BundleA.props" />
4 <ItemGroup>
5 <ProjectReference Include="..\PackageAv1\PackageAv1.wixproj" />
6 <ProjectReference Include="..\..\TestBA\TestBAWixlib\testbawixlib.wixproj" />
7 </ItemGroup>
8 <ItemGroup>
9 <PackageReference Include="WixToolset.Bal.wixext" Version="4.0.90" />
10 <PackageReference Include="WixToolset.NetFx.wixext" Version="4.0.64" />
11 </ItemGroup>
12</Project> \ No newline at end of file
diff --git a/src/TestData/UpdateBundleTests/BundleAv1/BundleAv1.wxs b/src/TestData/UpdateBundleTests/BundleAv1/BundleAv1.wxs
new file mode 100644
index 00000000..7bf16212
--- /dev/null
+++ b/src/TestData/UpdateBundleTests/BundleAv1/BundleAv1.wxs
@@ -0,0 +1,10 @@
1<!-- 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. -->
2
3
4<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
5 <Fragment>
6 <PackageGroup Id="BundlePackages">
7 <MsiPackage Id="PackageA" SourceFile="$(var.PackageAv1.TargetPath)" />
8 </PackageGroup>
9 </Fragment>
10</Wix>
diff --git a/src/TestData/UpdateBundleTests/BundleAv2/BundleAv2.wixproj b/src/TestData/UpdateBundleTests/BundleAv2/BundleAv2.wixproj
new file mode 100644
index 00000000..78e773db
--- /dev/null
+++ b/src/TestData/UpdateBundleTests/BundleAv2/BundleAv2.wixproj
@@ -0,0 +1,15 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <Import Project="..\BundleAv1\BundleA.props" />
4 <PropertyGroup>
5 <Version>2.0.0.0</Version>
6 </PropertyGroup>
7 <ItemGroup>
8 <ProjectReference Include="..\PackageAv2\PackageAv2.wixproj" />
9 <ProjectReference Include="..\..\TestBA\TestBAWixlib\testbawixlib.wixproj" />
10 </ItemGroup>
11 <ItemGroup>
12 <PackageReference Include="WixToolset.Bal.wixext" Version="4.0.90" />
13 <PackageReference Include="WixToolset.NetFx.wixext" Version="4.0.64" />
14 </ItemGroup>
15</Project> \ No newline at end of file
diff --git a/src/TestData/UpdateBundleTests/BundleAv2/BundleAv2.wxs b/src/TestData/UpdateBundleTests/BundleAv2/BundleAv2.wxs
new file mode 100644
index 00000000..5cbee5a8
--- /dev/null
+++ b/src/TestData/UpdateBundleTests/BundleAv2/BundleAv2.wxs
@@ -0,0 +1,10 @@
1<!-- 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. -->
2
3
4<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
5 <Fragment>
6 <PackageGroup Id="BundlePackages">
7 <MsiPackage Id="PackageA" SourceFile="$(var.PackageAv2.TargetPath)" />
8 </PackageGroup>
9 </Fragment>
10</Wix>
diff --git a/src/TestData/UpdateBundleTests/BundleBv1/Bundle.wxs b/src/TestData/UpdateBundleTests/BundleBv1/Bundle.wxs
new file mode 100644
index 00000000..906121f4
--- /dev/null
+++ b/src/TestData/UpdateBundleTests/BundleBv1/Bundle.wxs
@@ -0,0 +1,42 @@
1<!-- 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. -->
2
3<?ifndef Version?>
4<?define Version = 1.0.0.0?>
5<?endif?>
6
7<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:bal="http://wixtoolset.org/schemas/v4/wxs/bal">
8 <Bundle Name="~$(var.TestGroupName) - $(var.BundleName)" Version="$(var.Version)" UpgradeCode="$(var.UpgradeCode)" Compressed="yes">
9 <!-- Update should be the only thing different from the template -->
10 <Update Location="$(var.WebServerBaseUrl)BundleB/feed" />
11
12 <Log Prefix="~$(var.TestGroupName)_$(var.BundleName)" />
13
14 <Variable Name="TestGroupName" Value="$(var.TestGroupName)" />
15
16 <?ifdef SoftwareTag?>
17 <SoftwareTag Regid="regid.1995-08.com.example" InstallPath="[CommonAppDataFolder]regid.1995-08.com.example" />
18 <?endif?>
19
20 <?ifndef BA?>
21 <!-- pulled in through the PackageGroupRef below -->
22 <?elseif $(var.BA) = "TestBAdnc"?>
23 <!-- pulled in through the PackageGroupRef below -->
24 <?elseif $(var.BA) = "hyperlinkLicense"?>
25 <BootstrapperApplication>
26 <bal:WixStandardBootstrapperApplication LicenseUrl="" Theme="hyperlinkLicense" />
27 </BootstrapperApplication>
28 <?else?>
29 <BootstrapperApplicationRef Id="$(var.BA)" />
30 <?endif?>
31
32 <Chain>
33 <?ifndef BA?>
34 <PackageGroupRef Id="TestBA" />
35 <?elseif $(var.BA) = "TestBAdnc"?>
36 <PackageGroupRef Id="TestBAdnc" />
37 <?endif?>
38
39 <PackageGroupRef Id="BundlePackages" />
40 </Chain>
41 </Bundle>
42</Wix>
diff --git a/src/TestData/UpdateBundleTests/BundleBv1/BundleB.props b/src/TestData/UpdateBundleTests/BundleBv1/BundleB.props
new file mode 100644
index 00000000..8a275612
--- /dev/null
+++ b/src/TestData/UpdateBundleTests/BundleBv1/BundleB.props
@@ -0,0 +1,7 @@
1<!-- 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. -->
2<Project>
3 <PropertyGroup>
4 <OutputType>Bundle</OutputType>
5 <UpgradeCode>{BF325BA5-5012-47C7-828C-577B6979CB28}</UpgradeCode>
6 </PropertyGroup>
7</Project>
diff --git a/src/TestData/UpdateBundleTests/BundleBv1/BundleBv1.wixproj b/src/TestData/UpdateBundleTests/BundleBv1/BundleBv1.wixproj
new file mode 100644
index 00000000..ca40fbdd
--- /dev/null
+++ b/src/TestData/UpdateBundleTests/BundleBv1/BundleBv1.wixproj
@@ -0,0 +1,18 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <Import Project="BundleB.props" />
4 <ItemGroup>
5 <ProjectReference Include="..\PackageBv1\PackageBv1.wixproj" />
6 <ProjectReference Include="..\..\TestBA\TestBAWixlib\testbawixlib.wixproj" />
7 </ItemGroup>
8 <ItemGroup>
9 <Feeds Include="*.xml" />
10 </ItemGroup>
11 <ItemGroup>
12 <PackageReference Include="WixToolset.Bal.wixext" Version="4.0.90" />
13 <PackageReference Include="WixToolset.NetFx.wixext" Version="4.0.64" />
14 </ItemGroup>
15 <Target Name="CopyFeeds" AfterTargets="AfterBuild">
16 <Copy SourceFiles="@(Feeds)" DestinationFolder="$(OutputPath)" />
17 </Target>
18</Project> \ No newline at end of file
diff --git a/src/TestData/UpdateBundleTests/BundleBv1/BundleBv1.wxs b/src/TestData/UpdateBundleTests/BundleBv1/BundleBv1.wxs
new file mode 100644
index 00000000..00d927ec
--- /dev/null
+++ b/src/TestData/UpdateBundleTests/BundleBv1/BundleBv1.wxs
@@ -0,0 +1,10 @@
1<!-- 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. -->
2
3
4<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
5 <Fragment>
6 <PackageGroup Id="BundlePackages">
7 <MsiPackage Id="PackageB" SourceFile="$(var.PackageBv1.TargetPath)" />
8 </PackageGroup>
9 </Fragment>
10</Wix>
diff --git a/src/TestData/UpdateBundleTests/BundleBv1/FeedBv1.0.xml b/src/TestData/UpdateBundleTests/BundleBv1/FeedBv1.0.xml
new file mode 100644
index 00000000..743548be
--- /dev/null
+++ b/src/TestData/UpdateBundleTests/BundleBv1/FeedBv1.0.xml
@@ -0,0 +1,32 @@
1<?xml version='1.0' ?>
2<!-- 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. -->
3
4
5<feed xmlns="http://www.w3.org/2005/Atom" xmlns:as="http://appsyndication.org/2006/appsyn">
6 <title type="text">BundleB v1.0</title>
7 <subtitle type="text">Bundle Subtitle.</subtitle>
8 <as:application type="application/exe">1116353B-7C6E-4C29-BFA1-D4A972CD421D</as:application>
9 <updated>2014-07-14T12:39:00.000Z</updated>
10 <id>http://localhost:9999/e2e/BundleB/feed</id>
11 <link rel="self" type="application/atom+xml" href="http://localhost:9999/e2e/BundleB/feed"/>
12 <generator version="0.1">manual build</generator>
13 <entry>
14 <title>Bundle v1.0</title>
15 <id>v1.0</id>
16 <author>
17 <name>Bundle_Author</name>
18 <uri>http://mycompany.com/software</uri>
19 <email>Bundle_Author@mycompany.com</email>
20 </author>
21 <link rel="alternate" href="http://www.mycompany.com/content/view/software"/>
22 <link rel="enclosure" href="http://localhost:9999/e2e/BundleB/1.0/BundleB.exe" length="0" type="application/octet-stream"/>
23 <content type="html">
24 &lt;p&gt;Change list:&lt;/p&gt;&lt;ul&gt;
25 &lt;li&gt;Initial release.&lt;/li&gt;
26 &lt;/ul&gt;
27 </content>
28 <as:upgrade version="1.0.0.0-preview" />
29 <as:version>1.0.0.0</as:version>
30 <updated>2014-07-14T12:39:00.000Z</updated>
31 </entry>
32</feed>
diff --git a/src/TestData/UpdateBundleTests/BundleBv1/FeedBv2.0.xml b/src/TestData/UpdateBundleTests/BundleBv1/FeedBv2.0.xml
new file mode 100644
index 00000000..c8e3f6ea
--- /dev/null
+++ b/src/TestData/UpdateBundleTests/BundleBv1/FeedBv2.0.xml
@@ -0,0 +1,51 @@
1<?xml version='1.0' ?>
2<!-- 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. -->
3
4
5<feed xmlns="http://www.w3.org/2005/Atom" xmlns:as="http://appsyndication.org/2006/appsyn">
6 <title type="text">BundleB v2.0</title>
7 <subtitle type="text">Bundle Subtitle.</subtitle>
8 <as:application type="application/exe">1116353B-7C6E-4C29-BFA1-D4A972CD421D</as:application>
9 <updated>2014-07-14T12:39:00.000Z</updated>
10 <id>http://localhost:9999/e2e/BundleB/feed</id>
11 <link rel="self" type="application/atom+xml" href="http://localhost:9999/e2e/BundleB/feed"/>
12 <generator version="0.1">manual build</generator>
13 <entry>
14 <title>Bundle v2.0</title>
15 <id>v2.0</id>
16 <author>
17 <name>Bundle_Author</name>
18 <uri>http://mycompany.com/software</uri>
19 <email>Bundle_Author@mycompany.com</email>
20 </author>
21 <link rel="alternate" href="http://www.mycompany.com/content/view/software"/>
22 <link rel="enclosure" href="http://localhost:9999/e2e/BundleB/2.0/BundleB.exe" length="0" type="application/octet-stream"/>
23 <content type="html">
24 &lt;p&gt;Change list:&lt;/p&gt;&lt;ul&gt;
25 &lt;li&gt;Updated release.&lt;/li&gt;
26 &lt;/ul&gt;
27 </content>
28 <as:upgrade version="1.0" />
29 <as:version>2.0.0.0</as:version>
30 <updated>2014-11-10T12:39:00.000Z</updated>
31 </entry>
32 <entry>
33 <title>Bundle v1.0</title>
34 <id>v1.0</id>
35 <author>
36 <name>Bundle_Author</name>
37 <uri>http://mycompany.com/software</uri>
38 <email>Bundle_Author@mycompany.com</email>
39 </author>
40 <link rel="alternate" href="http://www.mycompany.com/content/view/software"/>
41 <link rel="enclosure" href="http://localhost:9999/e2e/BundleB/1.0/BundleB.exe" length="0" type="application/octet-stream"/>
42 <content type="html">
43 &lt;p&gt;Change list:&lt;/p&gt;&lt;ul&gt;
44 &lt;li&gt;Initial release.&lt;/li&gt;
45 &lt;/ul&gt;
46 </content>
47 <as:upgrade version="1.0.0.0-preview" />
48 <as:version>1.0.0.0</as:version>
49 <updated>2014-11-09T12:39:00.000Z</updated>
50 </entry>
51</feed>
diff --git a/src/TestData/UpdateBundleTests/BundleBv2/BundleBv2.wixproj b/src/TestData/UpdateBundleTests/BundleBv2/BundleBv2.wixproj
new file mode 100644
index 00000000..cc2aec76
--- /dev/null
+++ b/src/TestData/UpdateBundleTests/BundleBv2/BundleBv2.wixproj
@@ -0,0 +1,18 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <Import Project="..\BundleBv1\BundleB.props" />
4 <PropertyGroup>
5 <Version>2.0.0.0</Version>
6 </PropertyGroup>
7 <ItemGroup>
8 <Compile Include="..\BundleBv1\Bundle.wxs" />
9 </ItemGroup>
10 <ItemGroup>
11 <ProjectReference Include="..\PackageBv2\PackageBv2.wixproj" />
12 <ProjectReference Include="..\..\TestBA\TestBAWixlib\testbawixlib.wixproj" />
13 </ItemGroup>
14 <ItemGroup>
15 <PackageReference Include="WixToolset.Bal.wixext" Version="4.0.90" />
16 <PackageReference Include="WixToolset.NetFx.wixext" Version="4.0.64" />
17 </ItemGroup>
18</Project> \ No newline at end of file
diff --git a/src/TestData/UpdateBundleTests/BundleBv2/BundleBv2.wxs b/src/TestData/UpdateBundleTests/BundleBv2/BundleBv2.wxs
new file mode 100644
index 00000000..2043b084
--- /dev/null
+++ b/src/TestData/UpdateBundleTests/BundleBv2/BundleBv2.wxs
@@ -0,0 +1,10 @@
1<!-- 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. -->
2
3
4<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
5 <Fragment>
6 <PackageGroup Id="BundlePackages">
7 <MsiPackage Id="PackageB" SourceFile="$(var.PackageBv2.TargetPath)" />
8 </PackageGroup>
9 </Fragment>
10</Wix>
diff --git a/src/TestData/UpdateBundleTests/PackageAv1/PackageA.props b/src/TestData/UpdateBundleTests/PackageAv1/PackageA.props
new file mode 100644
index 00000000..bc734540
--- /dev/null
+++ b/src/TestData/UpdateBundleTests/PackageAv1/PackageA.props
@@ -0,0 +1,9 @@
1<!-- 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. -->
2<Project>
3 <PropertyGroup>
4 <UpgradeCode>{AB55C215-3268-4005-9657-6B0567F0A4B1}</UpgradeCode>
5 </PropertyGroup>
6 <ItemGroup>
7 <Compile Include="..\..\Templates\Package.wxs" Link="Package.wxs" />
8 </ItemGroup>
9</Project> \ No newline at end of file
diff --git a/src/TestData/UpdateBundleTests/PackageAv1/PackageAv1.wixproj b/src/TestData/UpdateBundleTests/PackageAv1/PackageAv1.wixproj
new file mode 100644
index 00000000..45d3b2c8
--- /dev/null
+++ b/src/TestData/UpdateBundleTests/PackageAv1/PackageAv1.wixproj
@@ -0,0 +1,4 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <Import Project="PackageA.props" />
4</Project> \ No newline at end of file
diff --git a/src/TestData/UpdateBundleTests/PackageAv2/PackageAv2.wixproj b/src/TestData/UpdateBundleTests/PackageAv2/PackageAv2.wixproj
new file mode 100644
index 00000000..b419f663
--- /dev/null
+++ b/src/TestData/UpdateBundleTests/PackageAv2/PackageAv2.wixproj
@@ -0,0 +1,7 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <Import Project="..\PackageAv1\PackageA.props" />
4 <PropertyGroup>
5 <Version>2.0.0.0</Version>
6 </PropertyGroup>
7</Project> \ No newline at end of file
diff --git a/src/TestData/UpdateBundleTests/PackageBv1/PackageB.props b/src/TestData/UpdateBundleTests/PackageBv1/PackageB.props
new file mode 100644
index 00000000..e677cb7e
--- /dev/null
+++ b/src/TestData/UpdateBundleTests/PackageBv1/PackageB.props
@@ -0,0 +1,9 @@
1<!-- 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. -->
2<Project>
3 <PropertyGroup>
4 <UpgradeCode>{6B971C9E-2FB0-4BF7-8D77-D2DF71FD9A14}</UpgradeCode>
5 </PropertyGroup>
6 <ItemGroup>
7 <Compile Include="..\..\Templates\PackagePerUser.wxs" Link="PackagePerUser.wxs" />
8 </ItemGroup>
9</Project> \ No newline at end of file
diff --git a/src/TestData/UpdateBundleTests/PackageBv1/PackageBv1.wixproj b/src/TestData/UpdateBundleTests/PackageBv1/PackageBv1.wixproj
new file mode 100644
index 00000000..7b6f83a3
--- /dev/null
+++ b/src/TestData/UpdateBundleTests/PackageBv1/PackageBv1.wixproj
@@ -0,0 +1,4 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <Import Project="PackageB.props" />
4</Project> \ No newline at end of file
diff --git a/src/TestData/UpdateBundleTests/PackageBv2/PackageBv2.wixproj b/src/TestData/UpdateBundleTests/PackageBv2/PackageBv2.wixproj
new file mode 100644
index 00000000..126d0f53
--- /dev/null
+++ b/src/TestData/UpdateBundleTests/PackageBv2/PackageBv2.wixproj
@@ -0,0 +1,7 @@
1<!-- 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. -->
2<Project Sdk="WixToolset.Sdk">
3 <Import Project="..\PackageBv1\PackageB.props" />
4 <PropertyGroup>
5 <Version>2.0.0.0</Version>
6 </PropertyGroup>
7</Project> \ No newline at end of file
diff --git a/src/Wix.Build.targets b/src/Wix.Build.targets
index 20a9bf66..17a46e2a 100644
--- a/src/Wix.Build.targets
+++ b/src/Wix.Build.targets
@@ -4,7 +4,8 @@
4 <PropertyGroup> 4 <PropertyGroup>
5 <BundleName Condition=" '$(BundleName)' == '' ">$(MSBuildProjectName)</BundleName> 5 <BundleName Condition=" '$(BundleName)' == '' ">$(MSBuildProjectName)</BundleName>
6 <PackageName Condition=" '$(PackageName)' == '' ">$(MSBuildProjectName)</PackageName> 6 <PackageName Condition=" '$(PackageName)' == '' ">$(MSBuildProjectName)</PackageName>
7 <DefineConstants>TestGroupName=$(TestGroupName);PackageName=$(PackageName);BundleName=$(BundleName);$(DefineConstants)</DefineConstants> 7 <WebServerBaseUrl Condition=" '$(WebServerBaseUrl)' == '' ">http://localhost:9999/e2e/</WebServerBaseUrl>
8 <DefineConstants>TestGroupName=$(TestGroupName);PackageName=$(PackageName);BundleName=$(BundleName);WebServerBaseUrl=$(WebServerBaseUrl);$(DefineConstants)</DefineConstants>
8 <DefineConstants Condition=" '$(BA)' != '' ">BA=$(BA);$(DefineConstants)</DefineConstants> 9 <DefineConstants Condition=" '$(BA)' != '' ">BA=$(BA);$(DefineConstants)</DefineConstants>
9 <DefineConstants Condition=" '$(CabPrefix)' != '' ">CabPrefix=$(CabPrefix);$(DefineConstants)</DefineConstants> 10 <DefineConstants Condition=" '$(CabPrefix)' != '' ">CabPrefix=$(CabPrefix);$(DefineConstants)</DefineConstants>
10 <DefineConstants Condition=" '$(IncludeSoftwareTag)' == 'true' ">SoftwareTag=1;$(DefineConstants)</DefineConstants> 11 <DefineConstants Condition=" '$(IncludeSoftwareTag)' == 'true' ">SoftwareTag=1;$(DefineConstants)</DefineConstants>
diff --git a/src/WixToolsetTest.BurnE2E/BurnE2ETests.cs b/src/WixToolsetTest.BurnE2E/BurnE2ETests.cs
index c9294f73..392b675d 100644
--- a/src/WixToolsetTest.BurnE2E/BurnE2ETests.cs
+++ b/src/WixToolsetTest.BurnE2E/BurnE2ETests.cs
@@ -36,6 +36,13 @@ namespace WixToolsetTest.BurnE2E
36 return controller; 36 return controller;
37 } 37 }
38 38
39 protected IWebServer CreateWebServer()
40 {
41 var webServer = new CoreOwinWebServer();
42 this.Installers.Push(webServer);
43 return webServer;
44 }
45
39 public void Dispose() 46 public void Dispose()
40 { 47 {
41 while (this.Installers.TryPop(out var installer)) 48 while (this.Installers.TryPop(out var installer))
diff --git a/src/WixToolsetTest.BurnE2E/IWebServer.cs b/src/WixToolsetTest.BurnE2E/IWebServer.cs
new file mode 100644
index 00000000..3bb8a23e
--- /dev/null
+++ b/src/WixToolsetTest.BurnE2E/IWebServer.cs
@@ -0,0 +1,20 @@
1// 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.
2
3namespace WixToolsetTest.BurnE2E
4{
5 using System;
6 using System.Collections.Generic;
7
8 public interface IWebServer : IDisposable
9 {
10 /// <summary>
11 /// Registers a collection of relative URLs (the key) with its absolute path to the file (the value).
12 /// </summary>
13 void AddFiles(Dictionary<string, string> physicalPathsByRelativeUrl);
14
15 /// <summary>
16 /// Starts the web server on a new thread.
17 /// </summary>
18 void Start();
19 }
20} \ No newline at end of file
diff --git a/src/WixToolsetTest.BurnE2E/TestBAController.cs b/src/WixToolsetTest.BurnE2E/TestBAController.cs
index 8e3053b3..103b603b 100644
--- a/src/WixToolsetTest.BurnE2E/TestBAController.cs
+++ b/src/WixToolsetTest.BurnE2E/TestBAController.cs
@@ -155,6 +155,12 @@ namespace WixToolsetTest.BurnE2E
155 Registry.LocalMachine.DeleteSubKey(key); 155 Registry.LocalMachine.DeleteSubKey(key);
156 } 156 }
157 157
158 public void SetVerifyArguments(string verifyArguments)
159 {
160 this.SetBurnTestValue("VerifyArguments", verifyArguments);
161
162 }
163
158 private void SetPackageState(string packageId, string name, string value) 164 private void SetPackageState(string packageId, string name, string value)
159 { 165 {
160 var key = String.Format(@"{0}\{1}", this.TestBaseRegKeyPath, packageId ?? String.Empty); 166 var key = String.Format(@"{0}\{1}", this.TestBaseRegKeyPath, packageId ?? String.Empty);
diff --git a/src/WixToolsetTest.BurnE2E/UpdateBundleTests.cs b/src/WixToolsetTest.BurnE2E/UpdateBundleTests.cs
new file mode 100644
index 00000000..9fcd428b
--- /dev/null
+++ b/src/WixToolsetTest.BurnE2E/UpdateBundleTests.cs
@@ -0,0 +1,245 @@
1// 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.
2
3namespace WixToolsetTest.BurnE2E
4{
5 using System;
6 using System.Collections.Generic;
7 using System.Diagnostics;
8 using System.IO;
9 using Xunit;
10 using Xunit.Abstractions;
11
12 public class UpdateBundleTests : BurnE2ETests
13 {
14 public UpdateBundleTests(ITestOutputHelper testOutputHelper) : base(testOutputHelper) { }
15
16 [Fact]
17 public void CanLaunchUpdateBundleFromLocalSourceInsteadOfInstall()
18 {
19 var packageAv1 = this.CreatePackageInstaller("PackageAv1");
20 var packageAv2 = this.CreatePackageInstaller("PackageAv2");
21 var bundleAv1 = this.CreateBundleInstaller("BundleAv1");
22 var bundleAv2 = this.CreateBundleInstaller("BundleAv2");
23
24 var updateBundleSwitch = String.Concat("\"", "-updatebundle:", bundleAv2.Bundle, "\"");
25
26 packageAv1.VerifyInstalled(false);
27 packageAv2.VerifyInstalled(false);
28
29 // Install the v2 bundle by getting v1 to launch it as an update bundle.
30 bundleAv1.Install(arguments: updateBundleSwitch);
31 bundleAv1.VerifyUnregisteredAndRemovedFromPackageCache();
32 bundleAv2.VerifyRegisteredAndInPackageCache();
33
34 packageAv1.VerifyInstalled(false);
35 packageAv2.VerifyInstalled(true);
36
37 bundleAv2.Uninstall();
38 bundleAv2.VerifyUnregisteredAndRemovedFromPackageCache();
39 packageAv2.VerifyInstalled(false);
40 }
41
42 [Fact]
43 public void CanLaunchUpdateBundleFromLocalSourceInsteadOfModify()
44 {
45 var packageAv1 = this.CreatePackageInstaller("PackageAv1");
46 var packageAv2 = this.CreatePackageInstaller("PackageAv2");
47 var bundleAv1 = this.CreateBundleInstaller("BundleAv1");
48 var bundleAv2 = this.CreateBundleInstaller("BundleAv2");
49
50 var updateBundleSwitch = String.Concat("\"", "-updatebundle:", bundleAv2.Bundle, "\"");
51
52 packageAv1.VerifyInstalled(false);
53 packageAv2.VerifyInstalled(false);
54
55 bundleAv1.Install();
56 bundleAv1.VerifyRegisteredAndInPackageCache();
57
58 packageAv1.VerifyInstalled(true);
59 packageAv2.VerifyInstalled(false);
60
61 // Install the v2 bundle by getting v1 to launch it as an update bundle.
62 bundleAv1.Modify(arguments: updateBundleSwitch);
63 bundleAv1.VerifyUnregisteredAndRemovedFromPackageCache();
64 bundleAv2.VerifyRegisteredAndInPackageCache();
65
66 packageAv1.VerifyInstalled(false);
67 packageAv2.VerifyInstalled(true);
68
69 bundleAv2.Uninstall();
70 bundleAv2.VerifyUnregisteredAndRemovedFromPackageCache();
71 packageAv2.VerifyInstalled(false);
72 }
73
74 [Fact]
75 public void ForwardsArgumentsToUpdateBundle()
76 {
77 var packageAv1 = this.CreatePackageInstaller("PackageAv1");
78 var packageAv2 = this.CreatePackageInstaller("PackageAv2");
79 var bundleAv1 = this.CreateBundleInstaller("BundleAv1");
80 var bundleAv2 = this.CreateBundleInstaller("BundleAv2");
81 var testBAController = this.CreateTestBAController();
82
83 const string verifyArguments = "these arguments should exist";
84 var updateBundleSwitch = String.Concat("\"", "-updatebundle:", bundleAv2.Bundle, "\" ", verifyArguments);
85
86 testBAController.SetVerifyArguments(verifyArguments);
87
88 packageAv1.VerifyInstalled(false);
89 packageAv2.VerifyInstalled(false);
90
91 // Install the v2 bundle by getting v1 to launch it as an update bundle.
92 bundleAv1.Install(arguments: updateBundleSwitch);
93 bundleAv1.VerifyUnregisteredAndRemovedFromPackageCache();
94 bundleAv2.VerifyRegisteredAndInPackageCache();
95
96 packageAv1.VerifyInstalled(false);
97 packageAv2.VerifyInstalled(true);
98
99 // Attempt to uninstall bundleA2 without the verify arguments passed and expect failure code.
100 bundleAv2.Uninstall(expectedExitCode: -1);
101
102 // Remove the required arguments and uninstall again.
103 testBAController.SetVerifyArguments(null);
104 bundleAv2.Uninstall();
105 bundleAv2.VerifyUnregisteredAndRemovedFromPackageCache();
106 packageAv2.VerifyInstalled(false);
107 }
108
109 // Installs bundle Bv1.0 then tries to update to latest version during modify (but no server exists).
110 [Fact]
111 public void CanCheckUpdateServerDuringModifyAndDoNothingWhenServerIsntResponsive()
112 {
113 var packageB = this.CreatePackageInstaller("PackageBv1");
114 var bundleB = this.CreateBundleInstaller("BundleBv1");
115
116 packageB.VerifyInstalled(false);
117
118 bundleB.Install();
119 bundleB.VerifyRegisteredAndInPackageCache();
120
121 packageB.VerifyInstalled(true);
122
123 // Run the v1 bundle requesting an update bundle.
124 bundleB.Modify(arguments: "-checkupdate");
125 bundleB.VerifyRegisteredAndInPackageCache();
126
127 // Verify nothing changed.
128 packageB.VerifyInstalled(true);
129
130 bundleB.Uninstall();
131 bundleB.VerifyUnregisteredAndRemovedFromPackageCache();
132 packageB.VerifyInstalled(false);
133 }
134
135 // Installs bundle Bv1.0 then tries to update to latest version during modify (server exists, no feed).
136 [Fact]
137 public void CanCheckUpdateServerDuringModifyAndDoNothingWhenFeedIsMissing()
138 {
139 var packageB = this.CreatePackageInstaller("PackageBv1");
140 var bundleB = this.CreateBundleInstaller("BundleBv1");
141 var webServer = this.CreateWebServer();
142
143 webServer.Start();
144
145 packageB.VerifyInstalled(false);
146
147 bundleB.Install();
148 bundleB.VerifyRegisteredAndInPackageCache();
149
150 packageB.VerifyInstalled(true);
151
152 // Run the v1 bundle requesting an update bundle.
153 bundleB.Modify(arguments: "-checkupdate");
154 bundleB.VerifyRegisteredAndInPackageCache();
155
156 // Verify nothing changed.
157 packageB.VerifyInstalled(true);
158
159 bundleB.Uninstall();
160 bundleB.VerifyUnregisteredAndRemovedFromPackageCache();
161 packageB.VerifyInstalled(false);
162 }
163
164 // Installs bundle Bv1.0 then tries to update to latest version during modify (server exists, v1.0 feed).
165 [Fact]
166 public void CanCheckUpdateServerDuringModifyAndDoNothingWhenAlreadyLatestVersion()
167 {
168 var packageB = this.CreatePackageInstaller("PackageBv1");
169 var bundleB = this.CreateBundleInstaller("BundleBv1");
170 var webServer = this.CreateWebServer();
171
172 webServer.AddFiles(new Dictionary<string, string>
173 {
174 { "/BundleB/feed", Path.Combine(this.TestContext.TestDataFolder, "FeedBv1.0.xml") },
175 });
176 webServer.Start();
177
178 packageB.VerifyInstalled(false);
179
180 bundleB.Install();
181 bundleB.VerifyRegisteredAndInPackageCache();
182
183 packageB.VerifyInstalled(true);
184
185 // Run the v1 bundle requesting an update bundle.
186 bundleB.Modify(arguments: "-checkupdate");
187 bundleB.VerifyRegisteredAndInPackageCache();
188
189 // Verify nothing changed.
190 packageB.VerifyInstalled(true);
191
192 bundleB.Uninstall();
193 bundleB.VerifyUnregisteredAndRemovedFromPackageCache();
194 packageB.VerifyInstalled(false);
195 }
196
197 // Installs bundle Bv1.0 then does an update to bundle Bv2.0 during modify (server exists, v2.0 feed).
198 [Fact]
199 public void CanLaunchUpdateBundleFromDownloadInsteadOfModify()
200 {
201 var packageBv1 = this.CreatePackageInstaller("PackageBv1");
202 var packageBv2 = this.CreatePackageInstaller("PackageBv2");
203 var bundleBv1 = this.CreateBundleInstaller("BundleBv1");
204 var bundleBv2 = this.CreateBundleInstaller("BundleBv2");
205 var webServer = this.CreateWebServer();
206
207 webServer.AddFiles(new Dictionary<string, string>
208 {
209 { "/BundleB/feed", Path.Combine(this.TestContext.TestDataFolder, "FeedBv2.0.xml") },
210 { "/BundleB/2.0/BundleB.exe", bundleBv2.Bundle },
211 });
212 webServer.Start();
213
214 packageBv1.VerifyInstalled(false);
215 packageBv2.VerifyInstalled(false);
216
217 bundleBv1.Install();
218 bundleBv1.VerifyRegisteredAndInPackageCache();
219
220 packageBv1.VerifyInstalled(true);
221 packageBv2.VerifyInstalled(false);
222
223 // Run the v1 bundle requesting an update bundle.
224 bundleBv1.Modify(arguments: "-checkupdate");
225
226 // The modify -> update is asynchronous, so we need to wait until the real BundleB is done
227 var childBundles = Process.GetProcessesByName(Path.GetFileNameWithoutExtension(bundleBv2.Bundle));
228 foreach (var childBundle in childBundles)
229 {
230 childBundle.WaitForExit();
231 }
232
233 bundleBv1.VerifyUnregisteredAndRemovedFromPackageCache();
234 bundleBv2.VerifyRegisteredAndInPackageCache();
235
236 packageBv1.VerifyInstalled(false);
237 packageBv2.VerifyInstalled(true);
238
239 bundleBv2.Uninstall();
240 bundleBv2.VerifyUnregisteredAndRemovedFromPackageCache();
241 packageBv1.VerifyInstalled(false);
242 packageBv2.VerifyInstalled(false);
243 }
244 }
245}
diff --git a/src/WixToolsetTest.BurnE2E/WebServer/CoreOwinWebServer.cs b/src/WixToolsetTest.BurnE2E/WebServer/CoreOwinWebServer.cs
new file mode 100644
index 00000000..66db226c
--- /dev/null
+++ b/src/WixToolsetTest.BurnE2E/WebServer/CoreOwinWebServer.cs
@@ -0,0 +1,69 @@
1// 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.
2
3namespace WixToolsetTest.BurnE2E
4{
5 using System;
6 using System.Collections.Generic;
7 using System.IO;
8 using Microsoft.AspNetCore.Builder;
9 using Microsoft.AspNetCore.Hosting;
10 using Microsoft.Extensions.FileProviders;
11 using Microsoft.Extensions.FileProviders.Physical;
12 using Microsoft.Extensions.Hosting;
13 using Microsoft.Extensions.Primitives;
14
15 public class CoreOwinWebServer : IWebServer, IFileProvider
16 {
17 private Dictionary<string, string> PhysicalPathsByRelativeUrl { get; } = new Dictionary<string, string>();
18
19 private IHost WebHost { get; set; }
20
21 public void AddFiles(Dictionary<string, string> physicalPathsByRelativeUrl)
22 {
23 foreach (var kvp in physicalPathsByRelativeUrl)
24 {
25 this.PhysicalPathsByRelativeUrl.Add(kvp.Key, kvp.Value);
26 }
27 }
28
29 public void Start()
30 {
31 this.WebHost = Host.CreateDefaultBuilder()
32 .ConfigureWebHostDefaults(webBuilder =>
33 {
34 // Use localhost instead of * to avoid firewall issues.
35 webBuilder.UseUrls("http://localhost:9999");
36 webBuilder.Configure(appBuilder =>
37 {
38 appBuilder.UseStaticFiles(new StaticFileOptions
39 {
40 FileProvider = this,
41 RequestPath = "/e2e",
42 ServeUnknownFileTypes = true,
43 });
44 });
45 })
46 .Build();
47 this.WebHost.Start();
48 }
49
50 public void Dispose()
51 {
52 this.WebHost?.StopAsync(TimeSpan.FromSeconds(5)).GetAwaiter().GetResult();
53 }
54
55 public IDirectoryContents GetDirectoryContents(string subpath) => throw new NotImplementedException();
56
57 public IFileInfo GetFileInfo(string subpath)
58 {
59 if (this.PhysicalPathsByRelativeUrl.TryGetValue(subpath, out var filepath))
60 {
61 return new PhysicalFileInfo(new FileInfo(filepath));
62 }
63
64 return new NotFoundFileInfo(subpath);
65 }
66
67 public IChangeToken Watch(string filter) => throw new NotImplementedException();
68 }
69} \ No newline at end of file
diff --git a/src/WixToolsetTest.BurnE2E/WixToolsetTest.BurnE2E.csproj b/src/WixToolsetTest.BurnE2E/WixToolsetTest.BurnE2E.csproj
index 170f5c73..75fdc9b3 100644
--- a/src/WixToolsetTest.BurnE2E/WixToolsetTest.BurnE2E.csproj
+++ b/src/WixToolsetTest.BurnE2E/WixToolsetTest.BurnE2E.csproj
@@ -13,10 +13,11 @@
13 </ItemGroup> 13 </ItemGroup>
14 14
15 <ItemGroup> 15 <ItemGroup>
16 <ProjectReference Include="..\WixTestTools\WixTestTools.csproj" /> 16 <ProjectReference Include="..\WixTestTools\WixTestTools.csproj" />
17 </ItemGroup> 17 </ItemGroup>
18 18
19 <ItemGroup> 19 <ItemGroup>
20 <PackageReference Include="Microsoft.AspNetCore.Owin" Version="3.1.13" />
20 <PackageReference Include="Microsoft.Win32.Registry" Version="5.0.0" /> 21 <PackageReference Include="Microsoft.Win32.Registry" Version="5.0.0" />
21 <PackageReference Include="System.Security.Principal.Windows" Version="5.0.0" /> 22 <PackageReference Include="System.Security.Principal.Windows" Version="5.0.0" />
22 <PackageReference Include="WixBuildTools.TestSupport" Version="4.0.48" /> 23 <PackageReference Include="WixBuildTools.TestSupport" Version="4.0.48" />