public void CanTrack1ForwardCompatibleDependentThroughMajorUpgrade() { string providerId = BundleAProviderId; string parent = "~BundleAv1"; string parentSwitch = String.Concat("-parent ", parent); var packageAv1 = this.CreatePackageInstaller("PackageAv1"); var packageAv2 = this.CreatePackageInstaller("PackageAv2"); var bundleAv1 = this.CreateBundleInstaller("BundleAv1"); var bundleAv2 = this.CreateBundleInstaller("BundleAv2"); packageAv1.VerifyInstalled(false); packageAv2.VerifyInstalled(false); // Install the v1 bundle with a parent. bundleAv1.Install(arguments: parentSwitch); bundleAv1.VerifyRegisteredAndInPackageCache(); packageAv1.VerifyInstalled(true); packageAv2.VerifyInstalled(false); Assert.True(BundleRegistration.TryGetDependencyProviderValue(providerId, "Version", out var actualProviderVersion)); Assert.Equal(V100, actualProviderVersion); Assert.True(BundleRegistration.DependencyDependentExists(providerId, parent)); // Upgrade with the v2 bundle. bundleAv2.Install(); bundleAv2.VerifyRegisteredAndInPackageCache(); bundleAv1.VerifyUnregisteredAndRemovedFromPackageCache(); packageAv1.VerifyInstalled(false); packageAv2.VerifyInstalled(true); Assert.True(BundleRegistration.TryGetDependencyProviderValue(providerId, "Version", out actualProviderVersion)); Assert.Equal(V200, actualProviderVersion); Assert.True(BundleRegistration.DependencyDependentExists(providerId, parent)); // Uninstall the v2 bundle and nothing should happen because there is still a parent. bundleAv2.Uninstall(); bundleAv2.VerifyRegisteredAndInPackageCache(); packageAv1.VerifyInstalled(false); packageAv2.VerifyInstalled(true); Assert.True(BundleRegistration.TryGetDependencyProviderValue(providerId, "Version", out actualProviderVersion)); Assert.Equal(V200, actualProviderVersion); Assert.True(BundleRegistration.DependencyDependentExists(providerId, parent)); // Uninstall the v1 bundle with passthrough and all should be removed. bundleAv1.Uninstall(arguments: parentSwitch); bundleAv1.VerifyUnregisteredAndRemovedFromPackageCache(); bundleAv2.VerifyUnregisteredAndRemovedFromPackageCache(); packageAv1.VerifyInstalled(false); packageAv2.VerifyInstalled(false); Assert.False(BundleRegistration.TryGetDependencyProviderValue(providerId, "Version", out actualProviderVersion)); }
public void CanUninstallForwardCompatibleWithBundlesUninstalledInReverseOrder() { string providerId = BundleAProviderId; string parent = "~BundleAv1"; string parentSwitch = String.Concat("-parent ", parent); var packageAv1 = this.CreatePackageInstaller("PackageAv1"); var packageAv2 = this.CreatePackageInstaller("PackageAv2"); var bundleAv1 = this.CreateBundleInstaller("BundleAv1"); var bundleAv2 = this.CreateBundleInstaller("BundleAv2"); packageAv1.VerifyInstalled(false); packageAv2.VerifyInstalled(false); bundleAv2.Install(); bundleAv2.VerifyRegisteredAndInPackageCache(); packageAv1.VerifyInstalled(false); packageAv2.VerifyInstalled(true); Assert.True(BundleRegistration.TryGetDependencyProviderValue(providerId, "Version", out var actualProviderVersion)); Assert.Equal(V200, actualProviderVersion); // Install the v1 bundle with a parent which should passthrough to v2. bundleAv1.Install(arguments: parentSwitch); bundleAv1.VerifyUnregisteredAndRemovedFromPackageCache(); packageAv1.VerifyInstalled(false); packageAv2.VerifyInstalled(true); Assert.True(BundleRegistration.DependencyDependentExists(providerId, parent)); // Uninstall the v1 bundle with the same parent which should passthrough to v2 and remove parent. bundleAv1.Uninstall(arguments: parentSwitch); bundleAv1.VerifyUnregisteredAndRemovedFromPackageCache(); bundleAv2.VerifyRegisteredAndInPackageCache(); packageAv1.VerifyInstalled(false); packageAv2.VerifyInstalled(true); Assert.False(BundleRegistration.DependencyDependentExists(providerId, parent)); // Uninstall the v2 bundle and all should be removed. bundleAv2.Uninstall(); bundleAv2.VerifyUnregisteredAndRemovedFromPackageCache(); packageAv1.VerifyInstalled(false); packageAv2.VerifyInstalled(false); Assert.False(BundleRegistration.TryGetDependencyProviderValue(providerId, "Version", out actualProviderVersion)); }
public void Burn_InstallLockUninstallInstallUninstall() { // Build. string packageA = this.GetPackageA().Output; string bundleA = this.GetBundleA().Output; BundleRegistration registration = null; // Install. BundleInstaller installerA = new BundleInstaller(this, bundleA).Install(); Assert.True(MsiVerifier.IsPackageInstalled(packageA)); Assert.True(this.TryGetBundleRegistration("5802E2D0-AC39-4486-86FF-D4B7AD012EB5", out registration)); Assert.Equal("~Burn_InstallLockUninstallInstallUninstall - Bundle A", registration.DisplayName); Assert.Equal(1, registration.Installed); Assert.Equal("1.0.0.0", registration.Version); // Uninstall while the file is locked. BundleInstaller uninstallerA = new BundleInstaller(this, registration.UninstallCommand); using (FileStream lockBundle = File.Open(registration.UninstallCommand, FileMode.Open, FileAccess.Read, FileShare.Read)) { uninstallerA.Uninstall(); Assert.False(MsiVerifier.IsPackageInstalled(packageA)); Assert.False(this.TryGetBundleRegistration("5802E2D0-AC39-4486-86FF-D4B7AD012EB5", out registration)); Assert.Null(registration); } // Install again. installerA = new BundleInstaller(this, bundleA).Install(); Assert.True(MsiVerifier.IsPackageInstalled(packageA)); Assert.True(this.TryGetBundleRegistration("5802E2D0-AC39-4486-86FF-D4B7AD012EB5", out registration)); Assert.Equal("~Burn_InstallLockUninstallInstallUninstall - Bundle A", registration.DisplayName); Assert.Equal(1, registration.Installed); Assert.Equal("1.0.0.0", registration.Version); // Uninstall again. uninstallerA.Uninstall(); Assert.False(MsiVerifier.IsPackageInstalled(packageA)); Assert.False(this.TryGetBundleRegistration("5802E2D0-AC39-4486-86FF-D4B7AD012EB5", out registration)); Assert.Null(registration); this.Complete(); }
/// <summary> /// Tries to load the bundle registration using the upgrade code. /// </summary> /// <param name="bundleUpgradeCode">Upgrade code of the bundle's registration to find.</param> /// <param name="registration">Registration for the bundle if found.</param> /// <returns>True if bundle is found, otherwise false.</returns> protected bool TryGetBundleRegistration(string bundleUpgradeCode, out BundleRegistration registration) { registration = null; if (!bundleUpgradeCode.StartsWith("{")) { bundleUpgradeCode = String.Concat("{", bundleUpgradeCode); } if (!bundleUpgradeCode.EndsWith("}")) { bundleUpgradeCode = String.Concat(bundleUpgradeCode, "}"); } foreach (string uninstallSubKeyPath in new string[] { "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall", "SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall" }) { using (RegistryKey uninstallSubKey = Registry.LocalMachine.OpenSubKey(uninstallSubKeyPath)) { if (null == uninstallSubKey) { continue; } foreach (string bundleId in uninstallSubKey.GetSubKeyNames()) { using (RegistryKey idKey = uninstallSubKey.OpenSubKey(bundleId)) { if (null == idKey) { continue; } string[] upgradeCodes = idKey.GetValue("BundleUpgradeCode") as string[]; if (null != upgradeCodes && upgradeCodes.Contains(bundleUpgradeCode, StringComparer.InvariantCultureIgnoreCase)) { registration = new BundleRegistration(); registration.AddonCodes = idKey.GetValue("BundleAddonCode") as string[]; registration.CachePath = idKey.GetValue("BundleCachePath") as string; registration.DetectCodes = idKey.GetValue("BundleDetectCode") as string[]; registration.PatchCodes = idKey.GetValue("BundlePatchCode") as string[]; registration.ProviderKey = idKey.GetValue("BundleProviderKey") as string; registration.Tag = idKey.GetValue("BundleTag") as string; registration.UpgradeCodes = idKey.GetValue("BundleUpgradeCode") as string[]; registration.Version = idKey.GetValue("BundleVersion") as string; registration.DisplayName = idKey.GetValue("DisplayName") as string; registration.EngineVersion = idKey.GetValue("EngineVersion") as string; registration.EstimatedSize = idKey.GetValue("EstimatedSize") as int?; registration.Installed = idKey.GetValue("Installed") as int?; registration.ModifyPath = idKey.GetValue("ModifyPath") as string; registration.Publisher = idKey.GetValue("Publisher") as string; registration.UrlInfoAbout = idKey.GetValue("URLInfoAbout") as string; registration.UrlUpdateInfo = idKey.GetValue("URLUpdateInfo") as string; registration.QuietUninstallString = idKey.GetValue("QuietUninstallString") as string; if (!String.IsNullOrEmpty(registration.QuietUninstallString)) { int closeQuote = registration.QuietUninstallString.IndexOf("\"", 1); registration.QuietUninstallCommand = registration.QuietUninstallString.Substring(1, closeQuote - 1).Trim(); registration.QuietUninstallCommandArguments = registration.QuietUninstallString.Substring(closeQuote + 1).Trim(); } registration.UninstallString = idKey.GetValue("UninstallString") as string; if (!String.IsNullOrEmpty(registration.UninstallString)) { int closeQuote = registration.UninstallString.IndexOf("\"", 1); registration.UninstallCommand = registration.UninstallString.Substring(1, closeQuote - 1).Trim(); registration.UninstallCommandArguments = registration.UninstallString.Substring(closeQuote + 1).Trim(); } break; } } } } if (null != registration) { break; } } return null != registration; }
/// <summary> /// Tries to load the bundle registration using the upgrade code. /// </summary> /// <param name="bundleUpgradeCode">Upgrade code of the bundle's registration to find.</param> /// <param name="registration">Registration for the bundle if found.</param> /// <returns>True if bundle is found, otherwise false.</returns> protected bool TryGetBundleRegistration(string bundleUpgradeCode, out BundleRegistration registration) { registration = null; if (!bundleUpgradeCode.StartsWith("{")) { bundleUpgradeCode = String.Concat("{", bundleUpgradeCode); } if (!bundleUpgradeCode.EndsWith("}")) { bundleUpgradeCode = String.Concat(bundleUpgradeCode, "}"); } foreach (string uninstallSubKeyPath in new string[] { "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall", "SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall" }) { using (RegistryKey uninstallSubKey = Registry.LocalMachine.OpenSubKey(uninstallSubKeyPath)) { if (null == uninstallSubKey) { continue; } foreach (string bundleId in uninstallSubKey.GetSubKeyNames()) { using (RegistryKey idKey = uninstallSubKey.OpenSubKey(bundleId)) { if (null == idKey) { continue; } string[] upgradeCodes = idKey.GetValue("BundleUpgradeCode") as string[]; if (null != upgradeCodes && upgradeCodes.Contains(bundleUpgradeCode, StringComparer.InvariantCultureIgnoreCase)) { registration = new BundleRegistration(); registration.AddonCodes = idKey.GetValue("BundleAddonCode") as string[]; registration.CachePath = idKey.GetValue("BundleCachePath") as string; registration.DetectCodes = idKey.GetValue("BundleDetectCode") as string[]; registration.PatchCodes = idKey.GetValue("BundlePatchCode") as string[]; registration.ProviderKey = idKey.GetValue("BundleProviderKey") as string; registration.Tag = idKey.GetValue("BundleTag") as string; registration.UpgradeCodes = idKey.GetValue("BundleUpgradeCode") as string[]; registration.Version = idKey.GetValue("BundleVersion") as string; registration.DisplayName = idKey.GetValue("DisplayName") as string; registration.EngineVersion = idKey.GetValue("EngineVersion") as string; registration.EstimatedSize = idKey.GetValue("EstimatedSize") as int?; registration.Installed = idKey.GetValue("Installed") as int?; registration.ModifyPath = idKey.GetValue("ModifyPath") as string; registration.Publisher = idKey.GetValue("Publisher") as string; registration.UrlInfoAbout = idKey.GetValue("URLInfoAbout") as string; registration.UrlUpdateInfo = idKey.GetValue("URLUpdateInfo") as string; registration.QuietUninstallString = idKey.GetValue("QuietUninstallString") as string; if (!String.IsNullOrEmpty(registration.QuietUninstallString)) { int closeQuote = registration.QuietUninstallString.IndexOf("\"", 1); registration.QuietUninstallCommand = registration.QuietUninstallString.Substring(1, closeQuote - 1).Trim(); registration.QuietUninstallCommandArguments = registration.QuietUninstallString.Substring(closeQuote + 1).Trim(); } registration.UninstallString = idKey.GetValue("UninstallString") as string; if (!String.IsNullOrEmpty(registration.UninstallString)) { int closeQuote = registration.UninstallString.IndexOf("\"", 1); registration.UninstallCommand = registration.UninstallString.Substring(1, closeQuote - 1).Trim(); registration.UninstallCommandArguments = registration.UninstallString.Substring(closeQuote + 1).Trim(); } break; } } } } if (null != registration) { break; } } return(null != registration); }
/// <summary> /// Register bundles /// </summary> private void RegisterBundles() { BundleRegistration.RegisterBundles(BundleTable.Bundles); }