diff options
author | Bob Arnson <bob@firegiant.com> | 2025-03-20 21:14:12 -0400 |
---|---|---|
committer | Bob Arnson <bob@firegiant.com> | 2025-03-20 22:56:24 -0400 |
commit | 9286dc177012bc8741fb1c206e00d0fbcd02f598 (patch) | |
tree | beff33ceaa3442ac37d7052a328e9791ecb6d2b7 | |
parent | bf13a0b67dd644eb7d74cb0cfb6876840f73d82b (diff) | |
download | wix-bob/UpdateRegistrationAcrossUpgrades.tar.gz wix-bob/UpdateRegistrationAcrossUpgrades.tar.bz2 wix-bob/UpdateRegistrationAcrossUpgrades.zip |
E2E test to validate update registration.bob/UpdateRegistrationAcrossUpgrades
12 files changed, 270 insertions, 0 deletions
diff --git a/src/test/burn/TestData/OptionalUpdateRegistrationTests/BundleAv1/Bundle.wxs b/src/test/burn/TestData/OptionalUpdateRegistrationTests/BundleAv1/Bundle.wxs new file mode 100644 index 00000000..0d9f786a --- /dev/null +++ b/src/test/burn/TestData/OptionalUpdateRegistrationTests/BundleAv1/Bundle.wxs | |||
@@ -0,0 +1,58 @@ | |||
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 TestVersion?> | ||
4 | <?define TestVersion = 1.0.0.0?> | ||
5 | <?endif?> | ||
6 | <?ifndef BundleLogDirectory?> | ||
7 | <?define BundleLogDirectory = .?> | ||
8 | <?endif?> | ||
9 | |||
10 | <Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:bal="http://wixtoolset.org/schemas/v4/wxs/bal"> | ||
11 | <Bundle Name="~$(var.TestGroupName) - $(var.BundleName)" Version="$(var.TestVersion)" Manufacturer="Acme" UpgradeCode="$(var.UpgradeCode)" Compressed="yes"> | ||
12 | <Log Prefix="$(var.BundleLogDirectory)\~$(var.TestGroupName)_$(var.BundleName)" /> | ||
13 | |||
14 | <Variable Name="TestGroupName" Value="$(var.TestGroupName)" /> | ||
15 | |||
16 | <OptionalUpdateRegistration ProductFamily="GreetingsAndFelicitations" Department="Setup Geeks" Classification="Bundle" /> | ||
17 | |||
18 | <?ifdef SoftwareTag?> | ||
19 | <SoftwareTag Regid="regid.1995-08.com.example" InstallPath="[CommonAppDataFolder]TestingSwidTags" /> | ||
20 | <?endif?> | ||
21 | |||
22 | <?ifndef BA?> | ||
23 | <!-- pulled in through the PackageGroupRef below --> | ||
24 | <?elseif $(var.BA) = "TestBA_x64"?> | ||
25 | <!-- pulled in through the PackageGroupRef below --> | ||
26 | <?elseif $(var.BA) = "WixBA"?> | ||
27 | <!-- pulled in through the PackageGroupRef below --> | ||
28 | <?elseif $(var.BA) = "hyperlinkLicense"?> | ||
29 | <BootstrapperApplication> | ||
30 | <bal:WixStandardBootstrapperApplication LicenseUrl="" Theme="hyperlinkLicense" /> | ||
31 | <PayloadGroupRef Id="ExtraPayloads" /> | ||
32 | </BootstrapperApplication> | ||
33 | <?elseif $(var.BA) = "iui"?> | ||
34 | <BootstrapperApplication> | ||
35 | <bal:WixInternalUIBootstrapperApplication /> | ||
36 | </BootstrapperApplication> | ||
37 | <?else?> | ||
38 | <BootstrapperApplicationRef Id="$(var.BA)" /> | ||
39 | <?endif?> | ||
40 | |||
41 | <Chain> | ||
42 | <?ifndef BA?> | ||
43 | <PackageGroupRef Id="TestBA" /> | ||
44 | <?elseif $(var.BA) = "TestBA_x64"?> | ||
45 | <PackageGroupRef Id="TestBA_x64" /> | ||
46 | <?elseif $(var.BA) = "WixBA"?> | ||
47 | <PackageGroupRef Id="WixBA" /> | ||
48 | <?endif?> | ||
49 | |||
50 | <PackageGroupRef Id="BundlePackages" /> | ||
51 | </Chain> | ||
52 | </Bundle> | ||
53 | |||
54 | <Fragment> | ||
55 | <PayloadGroup Id="virtual ExtraPayloads" /> | ||
56 | </Fragment> | ||
57 | |||
58 | </Wix> | ||
diff --git a/src/test/burn/TestData/OptionalUpdateRegistrationTests/BundleAv1/BundleA.props b/src/test/burn/TestData/OptionalUpdateRegistrationTests/BundleAv1/BundleA.props new file mode 100644 index 00000000..1887f94e --- /dev/null +++ b/src/test/burn/TestData/OptionalUpdateRegistrationTests/BundleAv1/BundleA.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>{9510DDE7-CD4F-45B3-9D57-3F7EA04DB33D}</UpgradeCode> | ||
6 | </PropertyGroup> | ||
7 | </Project> | ||
diff --git a/src/test/burn/TestData/OptionalUpdateRegistrationTests/BundleAv1/BundleAv1.wixproj b/src/test/burn/TestData/OptionalUpdateRegistrationTests/BundleAv1/BundleAv1.wixproj new file mode 100644 index 00000000..0dea1e40 --- /dev/null +++ b/src/test/burn/TestData/OptionalUpdateRegistrationTests/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.BootstrapperApplications.wixext" /> | ||
10 | <PackageReference Include="WixToolset.NetFx.wixext" /> | ||
11 | </ItemGroup> | ||
12 | </Project> | ||
diff --git a/src/test/burn/TestData/OptionalUpdateRegistrationTests/BundleAv1/BundleAv1.wxs b/src/test/burn/TestData/OptionalUpdateRegistrationTests/BundleAv1/BundleAv1.wxs new file mode 100644 index 00000000..7bf16212 --- /dev/null +++ b/src/test/burn/TestData/OptionalUpdateRegistrationTests/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/test/burn/TestData/OptionalUpdateRegistrationTests/BundleAv2/BundleAv2.wixproj b/src/test/burn/TestData/OptionalUpdateRegistrationTests/BundleAv2/BundleAv2.wixproj new file mode 100644 index 00000000..271bf54b --- /dev/null +++ b/src/test/burn/TestData/OptionalUpdateRegistrationTests/BundleAv2/BundleAv2.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="..\BundleAv1\BundleA.props" /> | ||
4 | <PropertyGroup> | ||
5 | <TestVersion>2.0.0.0</TestVersion> | ||
6 | </PropertyGroup> | ||
7 | <ItemGroup> | ||
8 | <Compile Include="..\BundleAv1\Bundle.wxs" /> | ||
9 | </ItemGroup> | ||
10 | <ItemGroup> | ||
11 | <ProjectReference Include="..\PackageAv2\PackageAv2.wixproj" /> | ||
12 | <ProjectReference Include="..\..\TestBA\TestBAWixlib\testbawixlib.wixproj" /> | ||
13 | </ItemGroup> | ||
14 | <ItemGroup> | ||
15 | <PackageReference Include="WixToolset.BootstrapperApplications.wixext" /> | ||
16 | <PackageReference Include="WixToolset.NetFx.wixext" /> | ||
17 | </ItemGroup> | ||
18 | </Project> | ||
diff --git a/src/test/burn/TestData/OptionalUpdateRegistrationTests/BundleAv2/BundleAv2.wxs b/src/test/burn/TestData/OptionalUpdateRegistrationTests/BundleAv2/BundleAv2.wxs new file mode 100644 index 00000000..5cbee5a8 --- /dev/null +++ b/src/test/burn/TestData/OptionalUpdateRegistrationTests/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/test/burn/TestData/OptionalUpdateRegistrationTests/PackageAv1/PackageA.props b/src/test/burn/TestData/OptionalUpdateRegistrationTests/PackageAv1/PackageA.props new file mode 100644 index 00000000..25ae3f42 --- /dev/null +++ b/src/test/burn/TestData/OptionalUpdateRegistrationTests/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>{30746E93-9A4A-48EC-BAEA-3093A2530E73}</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/test/burn/TestData/OptionalUpdateRegistrationTests/PackageAv1/PackageAv1.wixproj b/src/test/burn/TestData/OptionalUpdateRegistrationTests/PackageAv1/PackageAv1.wixproj new file mode 100644 index 00000000..45d3b2c8 --- /dev/null +++ b/src/test/burn/TestData/OptionalUpdateRegistrationTests/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/test/burn/TestData/OptionalUpdateRegistrationTests/PackageAv2/PackageAv2.wixproj b/src/test/burn/TestData/OptionalUpdateRegistrationTests/PackageAv2/PackageAv2.wixproj new file mode 100644 index 00000000..d4455f2b --- /dev/null +++ b/src/test/burn/TestData/OptionalUpdateRegistrationTests/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 | <TestVersion>2.0.0.0</TestVersion> | ||
6 | </PropertyGroup> | ||
7 | </Project> | ||
diff --git a/src/test/burn/WixTestTools/BundleUpdateRegistration.cs b/src/test/burn/WixTestTools/BundleUpdateRegistration.cs new file mode 100644 index 00000000..2ce68122 --- /dev/null +++ b/src/test/burn/WixTestTools/BundleUpdateRegistration.cs | |||
@@ -0,0 +1,57 @@ | |||
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 | namespace WixTestTools | ||
4 | { | ||
5 | using System; | ||
6 | using Microsoft.Win32; | ||
7 | |||
8 | public class BundleUpdateRegistration | ||
9 | { | ||
10 | public const string BURN_UPDATE_REGISTRATION_REGISTRY_BUNDLE_PACKAGE_NAME = "PackageName"; | ||
11 | public const string BURN_UPDATE_REGISTRATION_REGISTRY_BUNDLE_PACKAGE_VERSION = "PackageVersion"; | ||
12 | public const string BURN_UPDATE_REGISTRATION_REGISTRY_BUNDLE_PUBLISHER = "Publisher"; | ||
13 | public const string BURN_UPDATE_REGISTRATION_REGISTRY_BUNDLE_PUBLISHING_GROUP = "PublishingGroup"; | ||
14 | |||
15 | public string PackageName { get; set; } | ||
16 | |||
17 | public string PackageVersion { get; set; } | ||
18 | |||
19 | public string Publisher { get; set; } | ||
20 | |||
21 | public string PublishingGroup { get; set; } | ||
22 | |||
23 | public static bool TryGetPerMachineBundleUpdateRegistration(string manufacturer, string productFamily, string name, bool x64, out BundleUpdateRegistration registration) | ||
24 | { | ||
25 | return TryGetUpdateRegistration(manufacturer, productFamily, name, x64, perUser: false, out registration); | ||
26 | } | ||
27 | |||
28 | public static bool TryGetPerUserBundleUpdateRegistration(string manufacturer, string productFamily, string name, out BundleUpdateRegistration registration) | ||
29 | { | ||
30 | return TryGetUpdateRegistration(manufacturer, productFamily, name, x64: true, perUser: true, out registration); | ||
31 | } | ||
32 | |||
33 | private static bool TryGetUpdateRegistration(string manufacturer, string productFamily, string name, bool x64, bool perUser, out BundleUpdateRegistration registration) | ||
34 | { | ||
35 | var baseKey = perUser ? Registry.CurrentUser : Registry.LocalMachine; | ||
36 | var baseKeyPath = x64 ? @$"SOFTWARE\{manufacturer}\Updates\{productFamily}\{name}" | ||
37 | : @$"SOFTWARE\WOW6432Node\{manufacturer}\Updates\{productFamily}\{name}"; | ||
38 | using var idKey = baseKey.OpenSubKey(baseKeyPath); | ||
39 | |||
40 | if (idKey == null) | ||
41 | { | ||
42 | registration = null; | ||
43 | return false; | ||
44 | } | ||
45 | |||
46 | registration = new BundleUpdateRegistration() | ||
47 | { | ||
48 | PackageName = idKey.GetValue(BURN_UPDATE_REGISTRATION_REGISTRY_BUNDLE_PACKAGE_NAME) as string, | ||
49 | PackageVersion = idKey.GetValue(BURN_UPDATE_REGISTRATION_REGISTRY_BUNDLE_PACKAGE_VERSION) as string, | ||
50 | Publisher = idKey.GetValue(BURN_UPDATE_REGISTRATION_REGISTRY_BUNDLE_PUBLISHER) as string, | ||
51 | PublishingGroup = idKey.GetValue(BURN_UPDATE_REGISTRATION_REGISTRY_BUNDLE_PUBLISHING_GROUP) as string, | ||
52 | }; | ||
53 | |||
54 | return true; | ||
55 | } | ||
56 | } | ||
57 | } | ||
diff --git a/src/test/burn/WixTestTools/BundleVerifier.cs b/src/test/burn/WixTestTools/BundleVerifier.cs index da61d96e..b6181047 100644 --- a/src/test/burn/WixTestTools/BundleVerifier.cs +++ b/src/test/burn/WixTestTools/BundleVerifier.cs | |||
@@ -6,6 +6,7 @@ namespace WixTestTools | |||
6 | using System.IO; | 6 | using System.IO; |
7 | using System.Linq; | 7 | using System.Linq; |
8 | using System.Text; | 8 | using System.Text; |
9 | using System.Xml.Linq; | ||
9 | using Microsoft.Win32; | 10 | using Microsoft.Win32; |
10 | using WixInternal.TestSupport; | 11 | using WixInternal.TestSupport; |
11 | using WixToolset.Data; | 12 | using WixToolset.Data; |
@@ -23,6 +24,8 @@ namespace WixTestTools | |||
23 | 24 | ||
24 | private WixBundleSymbol BundleSymbol { get; set; } | 25 | private WixBundleSymbol BundleSymbol { get; set; } |
25 | 26 | ||
27 | private WixUpdateRegistrationSymbol UpdateRegistrationSymbol { get; set; } | ||
28 | |||
26 | private WixBundleSymbol GetBundleSymbol() | 29 | private WixBundleSymbol GetBundleSymbol() |
27 | { | 30 | { |
28 | if (this.BundleSymbol == null) | 31 | if (this.BundleSymbol == null) |
@@ -36,6 +39,19 @@ namespace WixTestTools | |||
36 | return this.BundleSymbol; | 39 | return this.BundleSymbol; |
37 | } | 40 | } |
38 | 41 | ||
42 | private WixUpdateRegistrationSymbol GetUpdateRegistrationSymbol() | ||
43 | { | ||
44 | if (this.UpdateRegistrationSymbol == null) | ||
45 | { | ||
46 | using var wixOutput = WixOutput.Read(this.BundlePdb); | ||
47 | var intermediate = Intermediate.Load(wixOutput); | ||
48 | var section = intermediate.Sections.Single(); | ||
49 | this.UpdateRegistrationSymbol = section.Symbols.OfType<WixUpdateRegistrationSymbol>().Single(); | ||
50 | } | ||
51 | |||
52 | return this.UpdateRegistrationSymbol; | ||
53 | } | ||
54 | |||
39 | public string GetFullBurnPolicyRegistryPath() | 55 | public string GetFullBurnPolicyRegistryPath() |
40 | { | 56 | { |
41 | var bundleSymbol = this.GetBundleSymbol(); | 57 | var bundleSymbol = this.GetBundleSymbol(); |
@@ -118,6 +134,27 @@ namespace WixTestTools | |||
118 | } | 134 | } |
119 | } | 135 | } |
120 | 136 | ||
137 | public bool TryGetUpdateRegistration(out BundleUpdateRegistration registration) | ||
138 | { | ||
139 | var bundleSymbol = this.GetBundleSymbol(); | ||
140 | var x64 = bundleSymbol.Platform != Platform.X86; | ||
141 | |||
142 | var updateRegistrationSymbol = this.GetUpdateRegistrationSymbol(); | ||
143 | var manufacturer = updateRegistrationSymbol.Manufacturer; | ||
144 | var productFamily = updateRegistrationSymbol.ProductFamily; | ||
145 | var name = updateRegistrationSymbol.Name; | ||
146 | |||
147 | |||
148 | if (bundleSymbol.PerMachine) | ||
149 | { | ||
150 | return BundleUpdateRegistration.TryGetPerMachineBundleUpdateRegistration(manufacturer, productFamily, name, x64, out registration); | ||
151 | } | ||
152 | else | ||
153 | { | ||
154 | return BundleUpdateRegistration.TryGetPerUserBundleUpdateRegistration(manufacturer, productFamily, name, out registration); | ||
155 | } | ||
156 | } | ||
157 | |||
121 | public BundleRegistration VerifyRegisteredAndInPackageCache(int? expectedSystemComponent = null) | 158 | public BundleRegistration VerifyRegisteredAndInPackageCache(int? expectedSystemComponent = null) |
122 | { | 159 | { |
123 | Assert.True(this.TryGetRegistration(out var registration)); | 160 | Assert.True(this.TryGetRegistration(out var registration)); |
diff --git a/src/test/burn/WixToolsetTest.BurnE2E/OptionalUpdateRegistrationTests.cs b/src/test/burn/WixToolsetTest.BurnE2E/OptionalUpdateRegistrationTests.cs new file mode 100644 index 00000000..632d18ec --- /dev/null +++ b/src/test/burn/WixToolsetTest.BurnE2E/OptionalUpdateRegistrationTests.cs | |||
@@ -0,0 +1,41 @@ | |||
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 | namespace WixToolsetTest.BurnE2E | ||
4 | { | ||
5 | using System; | ||
6 | using System.IO; | ||
7 | using WixTestTools; | ||
8 | using Xunit; | ||
9 | using Xunit.Abstractions; | ||
10 | |||
11 | public class OptionalUpdateRegistrationTests : BurnE2ETests | ||
12 | { | ||
13 | public OptionalUpdateRegistrationTests(ITestOutputHelper testOutputHelper) : base(testOutputHelper) { } | ||
14 | |||
15 | [RuntimeFact] | ||
16 | public void BundleUpdateRegistrationIsStickyAndAccurateAcrossUpgrades() | ||
17 | { | ||
18 | var packageAv1 = this.CreatePackageInstaller("PackageAv1"); | ||
19 | var packageAv2 = this.CreatePackageInstaller("PackageAv2"); | ||
20 | var bundleAv1 = this.CreateBundleInstaller("BundleAv1"); | ||
21 | var bundleAv2 = this.CreateBundleInstaller("BundleAv2"); | ||
22 | |||
23 | bundleAv1.Install(); | ||
24 | bundleAv1.VerifyRegisteredAndInPackageCache(); | ||
25 | bundleAv1.TryGetUpdateRegistration(out var v1Registration); | ||
26 | |||
27 | bundleAv2.Install(); | ||
28 | bundleAv2.VerifyRegisteredAndInPackageCache(); | ||
29 | bundleAv1.TryGetUpdateRegistration(out var v2Registration); | ||
30 | |||
31 | bundleAv1.VerifyUnregisteredAndRemovedFromPackageCache(); | ||
32 | |||
33 | Assert.NotNull(v1Registration); | ||
34 | Assert.NotNull(v2Registration); | ||
35 | Assert.Equal(v1Registration?.Publisher, v2Registration?.Publisher); | ||
36 | Assert.Equal(v1Registration?.PublishingGroup, v2Registration?.PublishingGroup); | ||
37 | Assert.Equal(v1Registration?.PackageName, v2Registration?.PackageName); | ||
38 | Assert.NotEqual(v1Registration?.PackageVersion, v2Registration?.PackageVersion); | ||
39 | } | ||
40 | } | ||
41 | } | ||