From 6f6e4ced9f398ff37a44b91fdba62479cde29d06 Mon Sep 17 00:00:00 2001 From: Sean Hall Date: Thu, 9 Jun 2022 15:30:48 -0500 Subject: Implement ArpEntry flavored ExePackage. 6772 --- src/test/burn/WixTestTools/ArpEntryInstaller.cs | 43 +++++++ src/test/burn/WixTestTools/ArpEntryVerifier.cs | 24 ++++ src/test/burn/WixTestTools/BundleRegistration.cs | 121 +++-------------- src/test/burn/WixTestTools/BundleVerifier.cs | 23 ++++ .../burn/WixTestTools/GenericArpRegistration.cs | 143 +++++++++++++++++++++ 5 files changed, 250 insertions(+), 104 deletions(-) create mode 100644 src/test/burn/WixTestTools/ArpEntryInstaller.cs create mode 100644 src/test/burn/WixTestTools/ArpEntryVerifier.cs create mode 100644 src/test/burn/WixTestTools/GenericArpRegistration.cs (limited to 'src/test/burn/WixTestTools') diff --git a/src/test/burn/WixTestTools/ArpEntryInstaller.cs b/src/test/burn/WixTestTools/ArpEntryInstaller.cs new file mode 100644 index 00000000..96d9fab9 --- /dev/null +++ b/src/test/burn/WixTestTools/ArpEntryInstaller.cs @@ -0,0 +1,43 @@ +// 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. + +namespace WixTestTools +{ + using System; + using Xunit; + + public partial class ArpEntryInstaller : IDisposable + { + public ArpEntryInstaller(WixTestContext testContext, string id, bool perMachine = true, bool x64 = false) + { + this.ArpId = id; + this.PerMachine = perMachine; + this.X64 = x64; + this.TestContext = testContext; + } + + public string ArpId { get; } + + public bool PerMachine { get; } + + public bool X64 { get; } + + private WixTestContext TestContext { get; } + + public void Unregister(bool assertIfMissing = true) + { + if (this.TryGetRegistration(out var registration)) + { + registration.Delete(); + } + else + { + Assert.True(false, "Tried to unregister when not registered."); + } + } + + public void Dispose() + { + this.Unregister(false); + } + } +} diff --git a/src/test/burn/WixTestTools/ArpEntryVerifier.cs b/src/test/burn/WixTestTools/ArpEntryVerifier.cs new file mode 100644 index 00000000..b3c70337 --- /dev/null +++ b/src/test/burn/WixTestTools/ArpEntryVerifier.cs @@ -0,0 +1,24 @@ +// 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. + +namespace WixTestTools +{ + using Xunit; + + public partial class ArpEntryInstaller + { + public bool TryGetRegistration(out GenericArpRegistration registration) + { + bool success = !this.PerMachine ? GenericArpRegistration.TryGetPerUserRegistrationById(this.ArpId, out registration) + : GenericArpRegistration.TryGetPerMachineRegistrationById(this.ArpId, this.X64, out registration); + + return success; + } + + public void VerifyRegistered(bool registered) + { + bool success = this.TryGetRegistration(out _); + + Assert.Equal(registered, success); + } + } +} diff --git a/src/test/burn/WixTestTools/BundleRegistration.cs b/src/test/burn/WixTestTools/BundleRegistration.cs index 3541e7ea..524d4616 100644 --- a/src/test/burn/WixTestTools/BundleRegistration.cs +++ b/src/test/burn/WixTestTools/BundleRegistration.cs @@ -5,108 +5,51 @@ namespace WixTestTools using System; using Microsoft.Win32; - public class BundleRegistration + public class BundleRegistration : GenericArpRegistration { - public const string BURN_REGISTRATION_REGISTRY_UNINSTALL_KEY = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall"; - public const string BURN_REGISTRATION_REGISTRY_UNINSTALL_KEY_WOW6432NODE = "SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall"; - public const string BURN_REGISTRATION_REGISTRY_BUNDLE_CACHE_PATH = "BundleCachePath"; public const string BURN_REGISTRATION_REGISTRY_BUNDLE_ADDON_CODE = "BundleAddonCode"; + public const string BURN_REGISTRATION_REGISTRY_BUNDLE_CACHE_PATH = "BundleCachePath"; public const string BURN_REGISTRATION_REGISTRY_BUNDLE_DETECT_CODE = "BundleDetectCode"; public const string BURN_REGISTRATION_REGISTRY_BUNDLE_PATCH_CODE = "BundlePatchCode"; + public const string BURN_REGISTRATION_REGISTRY_BUNDLE_PROVIDER_KEY = "BundleProviderKey"; + public const string BURN_REGISTRATION_REGISTRY_BUNDLE_RESUME_COMMAND_LINE = "BundleResumeCommandLine"; + public const string BURN_REGISTRATION_REGISTRY_BUNDLE_TAG = "BundleTag"; public const string BURN_REGISTRATION_REGISTRY_BUNDLE_UPGRADE_CODE = "BundleUpgradeCode"; - public const string BURN_REGISTRATION_REGISTRY_BUNDLE_DISPLAY_NAME = "DisplayName"; public const string BURN_REGISTRATION_REGISTRY_BUNDLE_VERSION = "BundleVersion"; public const string BURN_REGISTRATION_REGISTRY_ENGINE_VERSION = "EngineVersion"; - public const string BURN_REGISTRATION_REGISTRY_BUNDLE_PROVIDER_KEY = "BundleProviderKey"; - public const string BURN_REGISTRATION_REGISTRY_BUNDLE_TAG = "BundleTag"; - public const string REGISTRY_REBOOT_PENDING_FORMAT = "{0}.RebootRequired"; - public const string REGISTRY_BUNDLE_INSTALLED = "Installed"; - public const string REGISTRY_BUNDLE_DISPLAY_ICON = "DisplayIcon"; - public const string REGISTRY_BUNDLE_DISPLAY_VERSION = "DisplayVersion"; - public const string REGISTRY_BUNDLE_ESTIMATED_SIZE = "EstimatedSize"; - public const string REGISTRY_BUNDLE_PUBLISHER = "Publisher"; - public const string REGISTRY_BUNDLE_HELP_LINK = "HelpLink"; - public const string REGISTRY_BUNDLE_HELP_TELEPHONE = "HelpTelephone"; - public const string REGISTRY_BUNDLE_URL_INFO_ABOUT = "URLInfoAbout"; - public const string REGISTRY_BUNDLE_URL_UPDATE_INFO = "URLUpdateInfo"; - public const string REGISTRY_BUNDLE_PARENT_DISPLAY_NAME = "ParentDisplayName"; - public const string REGISTRY_BUNDLE_PARENT_KEY_NAME = "ParentKeyName"; - public const string REGISTRY_BUNDLE_COMMENTS = "Comments"; - public const string REGISTRY_BUNDLE_CONTACT = "Contact"; - public const string REGISTRY_BUNDLE_NO_MODIFY = "NoModify"; - public const string REGISTRY_BUNDLE_MODIFY_PATH = "ModifyPath"; - public const string REGISTRY_BUNDLE_NO_ELEVATE_ON_MODIFY = "NoElevateOnModify"; - public const string REGISTRY_BUNDLE_NO_REMOVE = "NoRemove"; - public const string REGISTRY_BUNDLE_SYSTEM_COMPONENT = "SystemComponent"; - public const string REGISTRY_BUNDLE_QUIET_UNINSTALL_STRING = "QuietUninstallString"; - public const string REGISTRY_BUNDLE_UNINSTALL_STRING = "UninstallString"; - public const string REGISTRY_BUNDLE_RESUME_COMMAND_LINE = "BundleResumeCommandLine"; - public const string REGISTRY_BUNDLE_VERSION_MAJOR = "VersionMajor"; - public const string REGISTRY_BUNDLE_VERSION_MINOR = "VersionMinor"; public string[] AddonCodes { get; set; } - public string CachePath { get; set; } + public string BundleVersion { get; set; } - public string DisplayName { get; set; } + public string CachePath { get; set; } public string[] DetectCodes { get; set; } public string EngineVersion { get; set; } - public int? EstimatedSize { get; set; } - - public int? Installed { get; set; } - - public string ModifyPath { get; set; } - public string[] PatchCodes { get; set; } public string ProviderKey { get; set; } - public string Publisher { get; set; } - - public int? SystemComponent { get; set; } - - public string QuietUninstallString { get; set; } - - public string QuietUninstallCommand { get; set; } - - public string QuietUninstallCommandArguments { get; set; } - public string Tag { get; set; } - public string UninstallCommand { get; set; } - - public string UninstallCommandArguments { get; set; } - - public string UninstallString { get; set; } - public string[] UpgradeCodes { get; set; } - public string UrlInfoAbout { get; set; } - - public string UrlUpdateInfo { get; set; } - - public string Version { get; set; } + public static bool TryGetPerMachineBundleRegistrationById(string id, bool x64, out BundleRegistration registration) + { + return TryGetRegistrationById(id, x64, false, out registration); + } - public static bool TryGetPerMachineBundleRegistrationById(string bundleId, bool x64, out BundleRegistration registration) + public static bool TryGetPerUserBundleRegistrationById(string id, out BundleRegistration registration) { - var baseKeyPath = x64 ? BURN_REGISTRATION_REGISTRY_UNINSTALL_KEY : BURN_REGISTRATION_REGISTRY_UNINSTALL_KEY_WOW6432NODE; - var registrationKeyPath = $"{baseKeyPath}\\{bundleId}"; - using var registrationKey = Registry.LocalMachine.OpenSubKey(registrationKeyPath); - var success = registrationKey != null; - registration = success ? GetBundleRegistration(registrationKey) : null; - return success; + return TryGetRegistrationById(id, true, true, out registration); } - public static bool TryGetPerUserBundleRegistrationById(string bundleId, out BundleRegistration registration) + private static bool TryGetRegistrationById(string id, bool x64, bool perUser, out BundleRegistration registration) { - var registrationKeyPath = $"{BURN_REGISTRATION_REGISTRY_UNINSTALL_KEY}\\{bundleId}"; - using var registrationKey = Registry.CurrentUser.OpenSubKey(registrationKeyPath); - var success = registrationKey != null; - registration = success ? GetBundleRegistration(registrationKey) : null; - return success; + registration = GetGenericArpRegistration(id, x64, perUser, key => GetBundleRegistration(key)); + return registration != null; } private static BundleRegistration GetBundleRegistration(RegistryKey idKey) @@ -120,38 +63,8 @@ namespace WixTestTools registration.ProviderKey = idKey.GetValue(BURN_REGISTRATION_REGISTRY_BUNDLE_PROVIDER_KEY) as string; registration.Tag = idKey.GetValue(BURN_REGISTRATION_REGISTRY_BUNDLE_TAG) as string; registration.UpgradeCodes = idKey.GetValue(BURN_REGISTRATION_REGISTRY_BUNDLE_UPGRADE_CODE) as string[]; - registration.Version = idKey.GetValue(BURN_REGISTRATION_REGISTRY_BUNDLE_VERSION) as string; - registration.DisplayName = idKey.GetValue(BURN_REGISTRATION_REGISTRY_BUNDLE_DISPLAY_NAME) as string; + registration.BundleVersion = idKey.GetValue(BURN_REGISTRATION_REGISTRY_BUNDLE_VERSION) as string; registration.EngineVersion = idKey.GetValue(BURN_REGISTRATION_REGISTRY_ENGINE_VERSION) as string; - registration.EstimatedSize = idKey.GetValue(REGISTRY_BUNDLE_ESTIMATED_SIZE) as int?; - registration.Installed = idKey.GetValue(REGISTRY_BUNDLE_INSTALLED) as int?; - registration.ModifyPath = idKey.GetValue(REGISTRY_BUNDLE_MODIFY_PATH) as string; - registration.Publisher = idKey.GetValue(REGISTRY_BUNDLE_PUBLISHER) as string; - registration.SystemComponent = idKey.GetValue(REGISTRY_BUNDLE_SYSTEM_COMPONENT) as int?; - registration.UrlInfoAbout = idKey.GetValue(REGISTRY_BUNDLE_URL_INFO_ABOUT) as string; - registration.UrlUpdateInfo = idKey.GetValue(REGISTRY_BUNDLE_URL_UPDATE_INFO) as string; - - registration.QuietUninstallString = idKey.GetValue(REGISTRY_BUNDLE_QUIET_UNINSTALL_STRING) as string; - if (!String.IsNullOrEmpty(registration.QuietUninstallString)) - { - var closeQuote = registration.QuietUninstallString.IndexOf("\"", 1); - if (closeQuote > 0) - { - registration.QuietUninstallCommand = registration.QuietUninstallString.Substring(1, closeQuote - 1).Trim(); - registration.QuietUninstallCommandArguments = registration.QuietUninstallString.Substring(closeQuote + 1).Trim(); - } - } - - registration.UninstallString = idKey.GetValue(REGISTRY_BUNDLE_UNINSTALL_STRING) as string; - if (!String.IsNullOrEmpty(registration.UninstallString)) - { - var closeQuote = registration.UninstallString.IndexOf("\"", 1); - if (closeQuote > 0) - { - registration.UninstallCommand = registration.UninstallString.Substring(1, closeQuote - 1).Trim(); - registration.UninstallCommandArguments = registration.UninstallString.Substring(closeQuote + 1).Trim(); - } - } return registration; } diff --git a/src/test/burn/WixTestTools/BundleVerifier.cs b/src/test/burn/WixTestTools/BundleVerifier.cs index 103171cd..ff45a291 100644 --- a/src/test/burn/WixTestTools/BundleVerifier.cs +++ b/src/test/burn/WixTestTools/BundleVerifier.cs @@ -80,6 +80,29 @@ namespace WixTestTools File.Delete(expectedCachePath); } + public bool TryGetArpEntryExePackageConfiguration(string packageId, out string arpId, out string arpVersion, out bool arpWin64, out bool perMachine) + { + using var wixOutput = WixOutput.Read(this.BundlePdb); + var intermediate = Intermediate.Load(wixOutput); + var section = intermediate.Sections.Single(); + var packageSymbol = section.Symbols.OfType().SingleOrDefault(p => p.Id.Id == packageId); + var exePackageSymbol = section.Symbols.OfType().SingleOrDefault(p => p.Id.Id == packageId); + if (packageSymbol == null || exePackageSymbol == null || exePackageSymbol.DetectionType != WixBundleExePackageDetectionType.Arp) + { + arpId = null; + arpVersion = null; + arpWin64 = false; + perMachine = false; + return false; + } + + arpId = exePackageSymbol.ArpId; + arpVersion = exePackageSymbol.ArpDisplayVersion; + arpWin64 = exePackageSymbol.ArpWin64; + perMachine = packageSymbol.PerMachine == true; + return true; + } + public bool TryGetRegistration(out BundleRegistration registration) { var bundleSymbol = this.GetBundleSymbol(); diff --git a/src/test/burn/WixTestTools/GenericArpRegistration.cs b/src/test/burn/WixTestTools/GenericArpRegistration.cs new file mode 100644 index 00000000..d87c4feb --- /dev/null +++ b/src/test/burn/WixTestTools/GenericArpRegistration.cs @@ -0,0 +1,143 @@ +// 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. + +namespace WixTestTools +{ + using System; + using Microsoft.Win32; + + public class GenericArpRegistration + { + public const string UNINSTALL_KEY = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall"; + public const string UNINSTALL_KEY_WOW6432NODE = "SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall"; + + public const string REGISTRY_ARP_INSTALLED = "Installed"; + public const string REGISTRY_ARP_DISPLAY_ICON = "DisplayIcon"; + public const string REGISTRY_ARP_DISPLAY_NAME = "DisplayName"; + public const string REGISTRY_ARP_DISPLAY_VERSION = "DisplayVersion"; + public const string REGISTRY_ARP_ESTIMATED_SIZE = "EstimatedSize"; + public const string REGISTRY_ARP_PUBLISHER = "Publisher"; + public const string REGISTRY_ARP_HELP_LINK = "HelpLink"; + public const string REGISTRY_ARP_HELP_TELEPHONE = "HelpTelephone"; + public const string REGISTRY_ARP_URL_INFO_ABOUT = "URLInfoAbout"; + public const string REGISTRY_ARP_URL_UPDATE_INFO = "URLUpdateInfo"; + public const string REGISTRY_ARP_COMMENTS = "Comments"; + public const string REGISTRY_ARP_CONTACT = "Contact"; + public const string REGISTRY_ARP_NO_MODIFY = "NoModify"; + public const string REGISTRY_ARP_MODIFY_PATH = "ModifyPath"; + public const string REGISTRY_ARP_NO_ELEVATE_ON_MODIFY = "NoElevateOnModify"; + public const string REGISTRY_ARP_NO_REMOVE = "NoRemove"; + public const string REGISTRY_ARP_SYSTEM_COMPONENT = "SystemComponent"; + public const string REGISTRY_ARP_QUIET_UNINSTALL_STRING = "QuietUninstallString"; + public const string REGISTRY_ARP_UNINSTALL_STRING = "UninstallString"; + public const string REGISTRY_ARP_VERSION_MAJOR = "VersionMajor"; + public const string REGISTRY_ARP_VERSION_MINOR = "VersionMinor"; + + public RegistryKey BaseKey { get; set; } + + public string KeyPath { get; set; } + + public string DisplayName { get; set; } + + public string DisplayVersion { get; set; } + + public int? EstimatedSize { get; set; } + + public int? Installed { get; set; } + + public string ModifyPath { get; set; } + + public string Publisher { get; set; } + + public int? SystemComponent { get; set; } + + public string QuietUninstallString { get; set; } + + public string QuietUninstallCommand { get; set; } + + public string QuietUninstallCommandArguments { get; set; } + + public string UninstallCommand { get; set; } + + public string UninstallCommandArguments { get; set; } + + public string UninstallString { get; set; } + + public string UrlInfoAbout { get; set; } + + public string UrlUpdateInfo { get; set; } + + public static bool TryGetPerMachineRegistrationById(string id, bool x64, out GenericArpRegistration registration) + { + return TryGetRegistrationById(id, x64, false, out registration); + } + + public static bool TryGetPerUserRegistrationById(string id, out GenericArpRegistration registration) + { + return TryGetRegistrationById(id, true, true, out registration); + } + + private static bool TryGetRegistrationById(string id, bool x64, bool perUser, out GenericArpRegistration registration) + { + registration = GetGenericArpRegistration(id, x64, perUser, key => new GenericArpRegistration()); + return registration != null; + } + + protected static T GetGenericArpRegistration(string id, bool x64, bool perUser, Func fnCreate) + where T : GenericArpRegistration + { + var baseKey = perUser ? Registry.CurrentUser : Registry.LocalMachine; + var baseKeyPath = x64 ? UNINSTALL_KEY : UNINSTALL_KEY_WOW6432NODE; + var registrationKeyPath = $"{baseKeyPath}\\{id}"; + using var idKey = baseKey.OpenSubKey(registrationKeyPath); + + if (idKey == null) + { + return null; + } + + var registration = fnCreate(idKey); + + registration.BaseKey = baseKey; + registration.KeyPath = registrationKeyPath; + + registration.DisplayName = idKey.GetValue(REGISTRY_ARP_DISPLAY_NAME) as string; + registration.DisplayVersion = idKey.GetValue(REGISTRY_ARP_DISPLAY_VERSION) as string; + registration.EstimatedSize = idKey.GetValue(REGISTRY_ARP_ESTIMATED_SIZE) as int?; + registration.Installed = idKey.GetValue(REGISTRY_ARP_INSTALLED) as int?; + registration.ModifyPath = idKey.GetValue(REGISTRY_ARP_MODIFY_PATH) as string; + registration.Publisher = idKey.GetValue(REGISTRY_ARP_PUBLISHER) as string; + registration.SystemComponent = idKey.GetValue(REGISTRY_ARP_SYSTEM_COMPONENT) as int?; + registration.UrlInfoAbout = idKey.GetValue(REGISTRY_ARP_URL_INFO_ABOUT) as string; + registration.UrlUpdateInfo = idKey.GetValue(REGISTRY_ARP_URL_UPDATE_INFO) as string; + + registration.QuietUninstallString = idKey.GetValue(REGISTRY_ARP_QUIET_UNINSTALL_STRING) as string; + if (!String.IsNullOrEmpty(registration.QuietUninstallString)) + { + var closeQuote = registration.QuietUninstallString.IndexOf("\"", 1); + if (closeQuote > 0) + { + registration.QuietUninstallCommand = registration.QuietUninstallString.Substring(1, closeQuote - 1).Trim(); + registration.QuietUninstallCommandArguments = registration.QuietUninstallString.Substring(closeQuote + 1).Trim(); + } + } + + registration.UninstallString = idKey.GetValue(REGISTRY_ARP_UNINSTALL_STRING) as string; + if (!String.IsNullOrEmpty(registration.UninstallString)) + { + var closeQuote = registration.UninstallString.IndexOf("\"", 1); + if (closeQuote > 0) + { + registration.UninstallCommand = registration.UninstallString.Substring(1, closeQuote - 1).Trim(); + registration.UninstallCommandArguments = registration.UninstallString.Substring(closeQuote + 1).Trim(); + } + } + + return registration; + } + + public void Delete() + { + this.BaseKey.DeleteSubKeyTree(this.KeyPath); + } + } +} -- cgit v1.2.3-55-g6feb