public void Patching_Builder_LowInstallerHigherPatches() { var builder = new PatchBuilder(new TestComponent()); // ACTION builder .Install("1.0", "2020-10-20", "desc").Action() .Patch("1.0", "2.0", "2020-10-20", "desc").Action() .Patch("2.0", "3.0", "2020-10-21", "desc").Action(); // ASSERT Assert.AreEqual("MyComp: 1.0 | MyComp: 1.0 <= v < 2.0 --> 2.0 | MyComp: 2.0 <= v < 3.0 --> 3.0", PatchesToString(builder)); }
public void Patching_Builder_Installer_BeforeAfter() { var builder = new PatchBuilder(new TestComponent()); // ACTION builder.Install("1.0", "2020-10-20", "MyComp desc") .ActionOnBefore().Action(); // ASSERT var installers = builder.GetPatches() .Select(x => (ComponentInstaller)x).ToArray(); Assert.IsNull(installers[0].ActionBeforeStart); Assert.IsNull(installers[0].Action); }
private PatchBuilder GetPatchA() { if (null == this.patchA) { string packageA = this.GetPackageA().Output; string packageAUpdate = this.GetPackageAv101().Output; this.patchA = new PatchBuilder(this, "PatchA") { TargetPath = packageA, UpgradePath = packageAUpdate }.Build(); } return(this.patchA); }
public void PatchesDifferentType() { var model1 = new Model1 { Integer = 3 }; var model2 = new Model2 { Integer = 3 }; var patch1 = PatchBuilder.Build <Model1>(new { Integer = 5 }); patch1.ApplyToT(model2); Assert.Equal(5, model2.Integer); Assert.Throws <NotSupportedException>(() => patch1.ApplyTo(model1)); }
public void Patching_Builder_Dependency_Direct() { var builder = new PatchBuilder(new TestComponent()); // ACTION builder.Patch("1.0", "2.0", "2020-10-20", "desc") .DependsOn("C1", "1.0") .DependsOn("C2", "2.3.0.15") .Action(); // ASSERT var patch = builder.GetPatches()[0] as SnPatch; var actual = DependenciesToString(patch?.Dependencies ?? new Dependency[0]); Assert.AreEqual("C1: 1.0 <= v | C2: 2.3.0.15 <= v", actual); }
public void Burn_PatchInstallUninstall() { string originalVersion = "1.0.0.0"; string patchedVersion = "1.0.1.0"; // Build the packages. string packageA = new PackageBuilder(this, "A") { Extensions = WixTests.Extensions }.Build().Output; string packageAUpdate = new PackageBuilder(this, "A") { Extensions = WixTests.Extensions, PreprocessorVariables = new Dictionary<string, string>() { { "Version", patchedVersion } }, NeverGetsInstalled = true }.Build().Output; string patchA = new PatchBuilder(this, "PatchA") { Extensions = WixTests.Extensions, TargetPath = packageA, UpgradePath = packageAUpdate }.Build().Output; // Create the named bind paths to the packages. Dictionary<string, string> bindPaths = new Dictionary<string, string>(); bindPaths.Add("packageA", packageA); bindPaths.Add("patchA", patchA); string bundleA = new BundleBuilder(this, "BundleA") { BindPaths = bindPaths, Extensions = WixTests.Extensions }.Build().Output; string bundleAPatch = new BundleBuilder(this, "PatchBundleA") { BindPaths = bindPaths, Extensions = WixTests.Extensions }.Build().Output; // Install the unpatched bundle. BundleInstaller installA = new BundleInstaller(this, bundleA).Install(); using (RegistryKey root = this.GetTestRegistryRoot()) { string actualVersion = root.GetValue("A") as string; Assert.Equal(originalVersion, actualVersion); } // Install the patch bundle. BundleInstaller installAPatch = new BundleInstaller(this, bundleAPatch).Install(); using (RegistryKey root = this.GetTestRegistryRoot()) { string actualVersion = root.GetValue("A") as string; Assert.Equal(patchedVersion, actualVersion); } // Uninstall the patch bundle. installAPatch.Uninstall(); using (RegistryKey root = this.GetTestRegistryRoot()) { string actualVersion = root.GetValue("A") as string; Assert.Equal(originalVersion, actualVersion); } installA.Uninstall(); Assert.True(null == this.GetTestRegistryRoot(), "Test registry key should have been removed during uninstall."); this.Complete(); }
public override void Initialize() { base.Initialize(); var progress = new Progress <BuilderProgress>(); progress.ProgressChanged += ProgressChanged; _context = new AdminPatchContext(CurrentWindow.AdminSettings, progress); _context.Logger = new MHLab.Patch.Utilities.Logging.Logger(CurrentWindow.AdminSettings.GetLogsFilePath(), CurrentWindow.AdminSettings.DebugMode); _context.Serializer = new NewtonsoftSerializer(); _context.LocalizedMessages = CurrentWindow.Localization; _builder = new PatchBuilder(_context); InitializePatches(); }
public void Burn_AutomaticSlipstreamInstallUninstall() { const string originalVersion = "1.0.0.0"; const string patchedVersion = "1.0.1.0"; // Build the packages. string packageA = this.GetPackageA().Output; string packageAUpdate = this.GetPackageAv101().Output; string packageB = this.GetPackageB().Output; string packageBUpdate = new PackageBuilder(this, "B") { PreprocessorVariables = new Dictionary<string, string>() { { "Version", patchedVersion} }, NeverGetsInstalled = true }.Build().Output; string patchA = new PatchBuilder(this, "PatchA") { PreprocessorVariables = new Dictionary<string, string>() { { "Version", patchedVersion } }, TargetPaths = new string[] { packageA, packageB }, UpgradePaths = new string[] { packageAUpdate, packageBUpdate } }.Build().Output; string patchB = new PatchBuilder(this, "PatchB") { PreprocessorVariables = new Dictionary<string, string>() { { "Version", patchedVersion } }, TargetPaths = new string[] { packageA, packageB }, UpgradePaths = new string[] { packageAUpdate, packageBUpdate } }.Build().Output; // Create the named bind paths to the packages. Dictionary<string, string> bindPaths = new Dictionary<string, string>(); bindPaths.Add("packageA", packageA); bindPaths.Add("packageB", packageB); bindPaths.Add("patchA", patchA); bindPaths.Add("patchB", patchB); string bundleC = new BundleBuilder(this, "BundleC") { BindPaths = bindPaths, Extensions = Extensions }.Build().Output; BundleInstaller install = new BundleInstaller(this, bundleC).Install(); using (RegistryKey root = this.GetTestRegistryRoot()) { // Product A should've slipstreamed both patches. string actualVersion = root.GetValue("A") as string; Assert.Equal(patchedVersion, actualVersion); actualVersion = root.GetValue("A2") as string; Assert.Equal(patchedVersion, actualVersion); // Product B should've only slipstreamed patch B. actualVersion = root.GetValue("B") as string; Assert.Equal(originalVersion, actualVersion); actualVersion = root.GetValue("B2") as string; Assert.Equal(patchedVersion, actualVersion); } install.Uninstall(); Assert.True(null == this.GetTestRegistryRoot(), "Test registry key should have been removed during uninstall."); this.Complete(); }
public void Patching_Builder_Patch_TooSmallTargetVersion() { var builder = new PatchBuilder(new TestComponent()); try { // ACTION builder.Patch("1.0", "1.0", "2020-10-20", "MyComp desc"); Assert.Fail(); } catch (InvalidPatchException e) { // ASSERT Assert.AreEqual(PatchErrorCode.TooSmallTargetVersion, e.ErrorCode); Assert.AreEqual("MyComp: 1.0 <= v < 1.0 --> 1.0", e.Patch.ToString()); } }
public override void Initialize() { base.Initialize(); var progress = new Progress <BuilderProgress>(); progress.ProgressChanged += ProgressChanged; _context = new AdminPatchContext(CurrentWindow.AdminSettings, progress); _context.Logger = new SimpleLogger(_context.FileSystem, CurrentWindow.AdminSettings.GetLogsFilePath(), CurrentWindow.AdminSettings.DebugMode); _context.Serializer = new JsonSerializer(); _context.LocalizedMessages = CurrentWindow.Localization; _builder = new PatchBuilder(_context); InitializePatches(); }
public void Patching_Builder_Dependency_Shared() { var patchBuilder = new PatchBuilder(new TestComponent()); var depBuilder = new DependencyBuilder() .Dependency("C3", "3.0") .Dependency("C4", "4.0"); // ACTION patchBuilder.Patch("1.0", "2.0", "2020-10-20", "desc") .DependsOn(depBuilder) .Action(); // ASSERT var patch = patchBuilder.GetPatches()[0] as SnPatch; var actual = DependenciesToString(patch?.Dependencies ?? new Dependency[0]); Assert.AreEqual("C3: 3.0 <= v | C4: 4.0 <= v", actual); }
public override void AddPatches(PatchBuilder builder) { var dependencies = new DependencyBuilder(builder) .Dependency("SenseNet.Services", "7.7.9"); builder.Patch("1.0", "1.1", "2020-02-10", "Feature1's PATCH to v1.1 description") .DependsOn(dependencies) .Action(context => { var oldFolderName = "GyebiTesztel_v1.0"; var newFolderName = "GyebiTesztel_v1.1"; var newContent = Content.Load($"/Root/{newFolderName}"); if (newContent != null) { return; } var oldContent = Content.Load($"/Root/{oldFolderName}"); if (oldContent != null) { oldContent.ContentHandler.Name = newFolderName; oldContent.Save(); } else { var parent = Node.LoadNode("/Root"); newContent = Content.CreateNew("SystemFolder", parent, newFolderName); newContent.Save(); } }); builder.Install("1.1", "2020-02-10", "My feature Feature1 description") .DependsOn(dependencies) .Action((context) => { var folderName = "GyebiTesztel_v1.1"; var content = Content.Load($"/Root/{folderName}"); if (content == null) { var parent = Node.LoadNode("/Root"); content = Content.CreateNew("SystemFolder", parent, folderName); content.Save(); } }); }
public void Burn_BuildNonSpecificPatches() { string patchedVersion = "1.0.1.0"; string[] extensions = new string[] { "WixBalExtension", "WixTagExtension", }; // Build the packages. string packageA = new PackageBuilder(this, "A") { Extensions = extensions }.Build().Output; string packageAUpdate = new PackageBuilder(this, "A") { Extensions = extensions, PreprocessorVariables = new Dictionary<string, string>() { { "Version", patchedVersion } }, NeverGetsInstalled = true }.Build().Output; string patchA = new PatchBuilder(this, "PatchA") { Extensions = extensions, TargetPath = packageA, UpgradePath = packageAUpdate }.Build().Output; string patchB = new PatchBuilder(this, "PatchB") { Extensions = extensions, TargetPath = packageA, UpgradePath = packageAUpdate }.Build().Output; string patchC = new PatchBuilder(this, "PatchC") { Extensions = extensions, TargetPath = packageA, UpgradePath = packageAUpdate }.Build().Output; // Build the bundles. Dictionary<string, string> bindPaths = new Dictionary<string, string>(); bindPaths.Add("packageA", packageA); bindPaths.Add("patchA", patchA); bindPaths.Add("patchB", patchB); bindPaths.Add("patchC", patchC); string bundleA = new BundleBuilder(this, "BundleA") { BindPaths = bindPaths, Extensions = extensions }.Build().Output; WixTest.BundleBuilder bundleAPatch = new BundleBuilder(this, "PatchBundleA") { BindPaths = bindPaths, Extensions = extensions, PreprocessorVariables = new Dictionary<string, string>() { { "Version", patchedVersion } } }.Build(); WixTest.BundleBuilder bundleBPatch = new BundleBuilder(this, "PatchBundleB") { BindPaths = bindPaths, Extensions = extensions, PreprocessorVariables = new Dictionary<string, string>() { { "Version", patchedVersion } } }.Build(); WixTest.BundleBuilder bundleCPatch = new BundleBuilder(this, "PatchBundleC") { BindPaths = bindPaths, Extensions = extensions, PreprocessorVariables = new Dictionary<string, string>() { { "Version", patchedVersion } } }.Build(); // Disassemble the patch bundles and check for PatchTargetCode elements. XmlNodeList nodes = PatchTests.GetPatchTargetCodes(bundleAPatch); Assert.Equal(1, nodes.Count); Assert.True(nodes.OfType<XmlElement>().Any(elem => elem.HasAttribute("Product") && "yes".Equals(elem.Attributes["Product"].Value))); nodes = PatchTests.GetPatchTargetCodes(bundleBPatch); Assert.Equal(2, nodes.Count); Assert.True(nodes.OfType<XmlElement>().Any(elem => elem.HasAttribute("Product") && "yes".Equals(elem.Attributes["Product"].Value))); Assert.True(nodes.OfType<XmlElement>().Any(elem => elem.HasAttribute("Product") && "no".Equals(elem.Attributes["Product"].Value))); nodes = PatchTests.GetPatchTargetCodes(bundleCPatch); Assert.Equal(0, nodes.Count); this.Complete(); }
public void Patching_Builder_Dependency_Duplicated() { var patchBuilder = new PatchBuilder(new TestComponent()); var depBuilder = new DependencyBuilder() .Dependency("C3", "3.0") .Dependency("C2", "4.0"); try { // ACTION patchBuilder.Patch("1.0", "2.0", "2020-10-20", "desc") .DependsOn("C1", "1.0") .DependsOn("C2", "2.0") .DependsOn(depBuilder) .Action(); Assert.Fail(); } catch (InvalidPatchException e) { // ASSERT Assert.AreEqual(PatchErrorCode.DuplicatedDependency, e.ErrorCode); Assert.AreEqual("MyComp: 1.0 <= v < 2.0 --> 2.0", e.Patch.ToString()); } }
public override void AddPatches(PatchBuilder builder) { builder.Install("1.0.0", "2020-10-15", "MS SQL data provider extension for the Exclusive lock feature.") .ActionOnBefore(context => { if (!(DataStore.DataProvider is RelationalDataProviderBase dataProvider)) { throw new InvalidOperationException("Cannot install MsSqlExclusiveLockComponent because it is " + $"incompatible with Data provider {DataStore.DataProvider.GetType().FullName}."); } try { using var ctx = dataProvider.CreateDataContext(CancellationToken.None); ctx.ExecuteNonQueryAsync(MsSqlExclusiveLockDataProvider.CreationScript).GetAwaiter().GetResult(); } catch (Exception ex) { context.Log($"Error during installation of MsSqlExclusiveLockComponent: {ex.Message}"); throw; } }); }
private JsonMergePatchDocument <NewtonsoftTestModel> GetTestPatch(object patchObject, JsonMergePatchOptions options = null) => PatchBuilder.Build <NewtonsoftTestModel>(patchObject, options);
public void Burn_InstallUninstallPatchBundle() { const string patchVersion = "1.0.1.0"; // Build the packages. string packageA1 = new PackageBuilder(this, "A").Build().Output; string packageA2 = new PackageBuilder(this, "A") { PreprocessorVariables = new Dictionary<string, string>() { { "Version", patchVersion } }, NeverGetsInstalled = true }.Build().Output; string packageB1 = new PackageBuilder(this, "B").Build().Output; string packageB2 = new PackageBuilder(this, "B") { PreprocessorVariables = new Dictionary<string, string>() { { "Version", patchVersion } }, NeverGetsInstalled = true }.Build().Output; string patchB = new PatchBuilder(this, "PatchB") { PreprocessorVariables = new Dictionary<string, string>() { { "Version", patchVersion } }, TargetPath = packageB1, UpgradePath = packageB2 }.Build().Output; PatchBuilder patchBuilderAB = new PatchBuilder(this, "PatchAB") { PreprocessorVariables = new Dictionary<string, string>() { { "Version", patchVersion } } }; patchBuilderAB.TargetPaths = new string[] { packageA1, packageB1 }; patchBuilderAB.UpgradePaths = new string[] { packageA2, packageB2 }; string patchAB = patchBuilderAB.Build().Output; // Create the named bind paths to the packages. Dictionary<string, string> bindPaths = new Dictionary<string, string>(); bindPaths.Add("packageA", packageA1); bindPaths.Add("patchAB", patchAB); bindPaths.Add("packageB", packageB1); bindPaths.Add("patchB", patchB); // Build the bundles. string bundleA = new BundleBuilder(this, "BundleA") { BindPaths = bindPaths, Extensions = Extensions }.Build().Output; string bundleB = new BundleBuilder(this, "BundleB") { PreprocessorVariables = new Dictionary<string, string>() { { "Version", patchVersion } }, BindPaths = bindPaths, Extensions = Extensions }.Build().Output; // Install the msi bundles. BundleInstaller installerA = new BundleInstaller(this, bundleA).Install(); // Test both packages are installed. Assert.True(MsiVerifier.IsPackageInstalled(packageA1)); Assert.True(MsiVerifier.IsPackageInstalled(packageB1)); // Install the patch bundle. // Slow the caching of patchB to ensure that patchAB finishes caching and needs to wait for patchB to be cached. this.SetPackageSlowCache("patchB", 10000); BundleInstaller installerB = new BundleInstaller(this, bundleB).Install(); using (RegistryKey root = this.GetTestRegistryRoot()) { string actualVersion = root.GetValue("A2") as string; Assert.Equal(patchVersion, actualVersion); actualVersion = root.GetValue("B") as string; Assert.Equal(patchVersion, actualVersion); actualVersion = root.GetValue("B2") as string; Assert.Equal(patchVersion, actualVersion); } // Attempt to uninstall bundleA. installerA.Uninstall(); // Test that uninstalling bundle A detected and would remove bundle B. Assert.True(LogVerifier.MessageInLogFileRegex(installerA.LastLogFile, @"Detected related bundle: \{[0-9A-Za-z\-]{36}\}, type: Patch, scope: PerMachine, version: 1\.0\.1\.0, operation: Remove")); // Test both packages are uninstalled. Assert.False(MsiVerifier.IsPackageInstalled(packageA1)); Assert.Null(this.GetTestRegistryRoot()); this.Complete(); }
public void Burn_InstallPatchBundle() { const string expectedVersion = "1.0.1.0"; // Build the packages. string packageA1 = new PackageBuilder(this, "A") { Extensions = Extensions }.Build().Output; string packageA2 = new PackageBuilder(this, "A") { Extensions = Extensions, PreprocessorVariables = new Dictionary <string, string>() { { "Version", expectedVersion } }, NeverGetsInstalled = true }.Build().Output; string packageB = new PackageBuilder(this, "B") { Extensions = Extensions }.Build().Output; string patchA = new PatchBuilder(this, "PatchA") { PreprocessorVariables = new Dictionary <string, string>() { { "Version", expectedVersion } }, TargetPath = packageA1, UpgradePath = packageA2 }.Build().Output; // Create the named bind paths to the packages. Dictionary <string, string> bindPaths = new Dictionary <string, string>(); bindPaths.Add("packageA", packageA1); bindPaths.Add("packageB", packageB); bindPaths.Add("patchA", patchA); // Build the bundles. string bundleF = new BundleBuilder(this, "BundleF") { BindPaths = bindPaths, Extensions = Extensions }.Build().Output; string bundleG = new BundleBuilder(this, "BundleG") { BindPaths = bindPaths, Extensions = Extensions }.Build().Output; // Install the base bundle and make sure all packages are installed. BundleInstaller installerF = new BundleInstaller(this, bundleF).Install(); Assert.IsTrue(MsiVerifier.IsPackageInstalled(packageA1)); Assert.IsTrue(MsiVerifier.IsPackageInstalled(packageB)); // Install patch bundle and make sure all packages are installed. BundleInstaller installerG = new BundleInstaller(this, bundleG).Install(); Assert.IsTrue(MsiVerifier.IsPackageInstalled(packageA1)); Assert.IsTrue(MsiVerifier.IsPackageInstalled(packageB)); Assert.IsTrue(MsiUtils.IsPatchInstalled(patchA)); // Uninstall the base bundle and make sure all packages are uninstalled. installerF.Uninstall(); Assert.IsFalse(MsiVerifier.IsPackageInstalled(packageA1)); Assert.IsFalse(MsiVerifier.IsPackageInstalled(packageB)); Assert.IsFalse(MsiUtils.IsPatchInstalled(patchA)); this.CleanTestArtifacts = true; }
public void Burn_InstallUpgradeSlipstreamBundle() { const string expectedVersion1 = "1.0.0.0"; const string expectedVersion2 = "1.0.1.0"; // Build the packages. string packageA = new PackageBuilder(this, "A") { Extensions = Extensions }.Build().Output; string packageA1 = new PackageBuilder(this, "A") { Extensions = Extensions, PreprocessorVariables = new Dictionary <string, string>() { { "Version", expectedVersion2 } }, NeverGetsInstalled = true }.Build().Output; string patchA = new PatchBuilder(this, "PatchA") { PreprocessorVariables = new Dictionary <string, string>() { { "Version", expectedVersion2 } }, TargetPath = packageA, UpgradePath = packageA1 }.Build().Output; // Create the named bind paths to the packages. Dictionary <string, string> bindPaths = new Dictionary <string, string>(); bindPaths.Add("packageA", packageA); bindPaths.Add("patchA", patchA); // Build the bundles. string bundleA = new BundleBuilder(this, "BundleA") { BindPaths = bindPaths, Extensions = Extensions }.Build().Output; string bundleC = new BundleBuilder(this, "BundleC") { BindPaths = bindPaths, Extensions = Extensions, PreprocessorVariables = new Dictionary <string, string>() { { "Version", expectedVersion2 } } }.Build().Output; // Install the base bundle and make sure it's installed. BundleInstaller installerA = new BundleInstaller(this, bundleA).Install(); Assert.IsTrue(MsiVerifier.IsPackageInstalled(packageA)); using (RegistryKey root = this.GetTestRegistryRoot()) { string actualVersion = root.GetValue("Version") as string; Assert.AreEqual(expectedVersion1, actualVersion); } // Install the upgrade bundle with a slipstreamed patch and make sure the patch is installed. // SFBUG:3387046 - Uninstalling bundle registers a dependency on a package BundleInstaller installerC = new BundleInstaller(this, bundleC).Install(); Assert.IsTrue(MsiUtils.IsPatchInstalled(patchA)); // BundleC doesn't carry the EXE, so make sure it's removed. using (RegistryKey root = this.GetTestRegistryRoot()) { Assert.IsNull(root.GetValue("Version")); } // Repair the upgrade bundle to make sure it does not prompt for source. // SFBUG:3386927 - MSIs get removed from cache during upgrade installerC.Repair(); // Uninstall the slipstream bundle and make sure both packages are uninstalled. installerC.Uninstall(); Assert.IsFalse(MsiUtils.IsPatchInstalled(patchA)); Assert.IsFalse(MsiVerifier.IsPackageInstalled(packageA)); this.CleanTestArtifacts = true; }
public void Burn_PatchInstallUninstall() { string originalVersion = "1.0.0.0"; string patchedVersion = "1.0.1.0"; // Build the packages. string packageA = new PackageBuilder(this, "A") { Extensions = WixTests.Extensions }.Build().Output; string packageAUpdate = new PackageBuilder(this, "A") { Extensions = WixTests.Extensions, PreprocessorVariables = new Dictionary <string, string>() { { "Version", patchedVersion } }, NeverGetsInstalled = true }.Build().Output; string patchA = new PatchBuilder(this, "PatchA") { Extensions = WixTests.Extensions, TargetPath = packageA, UpgradePath = packageAUpdate }.Build().Output; // Create the named bind paths to the packages. Dictionary <string, string> bindPaths = new Dictionary <string, string>(); bindPaths.Add("packageA", packageA); bindPaths.Add("patchA", patchA); string bundleA = new BundleBuilder(this, "BundleA") { BindPaths = bindPaths, Extensions = Extensions }.Build().Output; string bundleAPatch = new BundleBuilder(this, "PatchBundleA") { BindPaths = bindPaths, Extensions = Extensions }.Build().Output; // Install the unpatched bundle. BundleInstaller installA = new BundleInstaller(this, bundleA).Install(); using (RegistryKey root = this.GetTestRegistryRoot()) { string actualVersion = root.GetValue("A") as string; Assert.AreEqual(originalVersion, actualVersion); } // Install the patch bundle. BundleInstaller installAPatch = new BundleInstaller(this, bundleAPatch).Install(); using (RegistryKey root = this.GetTestRegistryRoot()) { string actualVersion = root.GetValue("A") as string; Assert.AreEqual(patchedVersion, actualVersion); } // Uninstall the patch bundle. installAPatch.Uninstall(); using (RegistryKey root = this.GetTestRegistryRoot()) { string actualVersion = root.GetValue("A") as string; Assert.AreEqual(originalVersion, actualVersion); } installA.Uninstall(); Assert.IsNull(this.GetTestRegistryRoot(), "Test registry key should have been removed during uninstall."); this.CleanTestArtifacts = true; }
public void Burn_PatchTag() { string originalVersion = "1.0.0.0"; string patchedVersion = "1.0.1.0"; string actualVersion = null; // Build the packages. string packageA = new PackageBuilder(this, "A") { Extensions = WixTests.Extensions }.Build().Output; string packageAUpdate = new PackageBuilder(this, "A") { Extensions = WixTests.Extensions, PreprocessorVariables = new Dictionary <string, string>() { { "Version", patchedVersion } }, NeverGetsInstalled = true }.Build().Output; string patchA = new PatchBuilder(this, "PatchA") { Extensions = WixTests.Extensions, TargetPath = packageA, UpgradePath = packageAUpdate }.Build().Output; // Create the named bind paths to the packages. Dictionary <string, string> bindPaths = new Dictionary <string, string>(); bindPaths.Add("packageA", packageA); bindPaths.Add("patchA", patchA); string bundleA = new BundleBuilder(this, "BundleA") { BindPaths = bindPaths, Extensions = WixTests.Extensions }.Build().Output; string bundleAPatch = new BundleBuilder(this, "PatchBundleA") { BindPaths = bindPaths, Extensions = WixTests.Extensions, PreprocessorVariables = new Dictionary <string, string>() { { "Version", patchedVersion } } }.Build().Output; // Install the unpatched bundle. BundleInstaller installA = new BundleInstaller(this, bundleA).Install(); actualVersion = GetTagVersion("~Burn_PatchTag - Bundle A"); Assert.AreEqual(originalVersion, actualVersion); actualVersion = GetTagVersion("~Burn_PatchTag - A"); Assert.AreEqual(originalVersion, actualVersion); // Install the patch bundle. BundleInstaller installAPatch = new BundleInstaller(this, bundleAPatch).Install(); actualVersion = GetTagVersion("~Burn_PatchTag - Patch Bundle A"); Assert.AreEqual(patchedVersion, actualVersion); actualVersion = GetTagVersion("~Burn_PatchTag - A"); Assert.AreEqual(patchedVersion, actualVersion); // Uninstall the patch bundle. installAPatch.Uninstall(); actualVersion = GetTagVersion("~Burn_PatchTag - A"); Assert.AreEqual(originalVersion, actualVersion); // Uninstall the original bundle and ensure all the tags are gone. installA.Uninstall(); actualVersion = GetTagVersion("~Burn_PatchTag - Bundle A"); Assert.IsNull(actualVersion); actualVersion = GetTagVersion("~Burn_PatchTag - A"); Assert.IsNull(actualVersion); this.CleanTestArtifacts = true; }
public void Burn_InstallUninstallPatchBundle() { const string patchVersion = "1.0.1.0"; // Build the packages. string packageA1 = new PackageBuilder(this, "A").Build().Output; string packageA2 = new PackageBuilder(this, "A") { PreprocessorVariables = new Dictionary <string, string>() { { "Version", patchVersion } }, NeverGetsInstalled = true }.Build().Output; string packageB1 = new PackageBuilder(this, "B").Build().Output; string packageB2 = new PackageBuilder(this, "B") { PreprocessorVariables = new Dictionary <string, string>() { { "Version", patchVersion } }, NeverGetsInstalled = true }.Build().Output; string patchB = new PatchBuilder(this, "PatchB") { PreprocessorVariables = new Dictionary <string, string>() { { "Version", patchVersion } }, TargetPath = packageB1, UpgradePath = packageB2 }.Build().Output; PatchBuilder patchBuilderAB = new PatchBuilder(this, "PatchAB") { PreprocessorVariables = new Dictionary <string, string>() { { "Version", patchVersion } } }; patchBuilderAB.TargetPaths = new string[] { packageA1, packageB1 }; patchBuilderAB.UpgradePaths = new string[] { packageA2, packageB2 }; string patchAB = patchBuilderAB.Build().Output; // Create the named bind paths to the packages. Dictionary <string, string> bindPaths = new Dictionary <string, string>(); bindPaths.Add("packageA", packageA1); bindPaths.Add("patchAB", patchAB); bindPaths.Add("packageB", packageB1); bindPaths.Add("patchB", patchB); // Build the bundles. string bundleA = new BundleBuilder(this, "BundleA") { BindPaths = bindPaths, Extensions = Extensions }.Build().Output; string bundleB = new BundleBuilder(this, "BundleB") { PreprocessorVariables = new Dictionary <string, string>() { { "Version", patchVersion } }, BindPaths = bindPaths, Extensions = Extensions }.Build().Output; // Install the msi bundles. BundleInstaller installerA = new BundleInstaller(this, bundleA).Install(); // Test both packages are installed. Assert.True(MsiVerifier.IsPackageInstalled(packageA1)); Assert.True(MsiVerifier.IsPackageInstalled(packageB1)); // Install the patch bundle. // Slow the caching of patchB to ensure that patchAB finishes caching and needs to wait for patchB to be cached. this.SetPackageSlowCache("patchB", 10000); BundleInstaller installerB = new BundleInstaller(this, bundleB).Install(); using (RegistryKey root = this.GetTestRegistryRoot()) { string actualVersion = root.GetValue("A2") as string; Assert.Equal(patchVersion, actualVersion); actualVersion = root.GetValue("B") as string; Assert.Equal(patchVersion, actualVersion); actualVersion = root.GetValue("B2") as string; Assert.Equal(patchVersion, actualVersion); } // Attempt to uninstall bundleA. installerA.Uninstall(); // Test that uninstalling bundle A detected and would remove bundle B. Assert.True(LogVerifier.MessageInLogFileRegex(installerA.LastLogFile, @"Detected related bundle: \{[0-9A-Za-z\-]{36}\}, type: Patch, scope: PerMachine, version: 1\.0\.1\.0, operation: Remove")); // Test both packages are uninstalled. Assert.False(MsiVerifier.IsPackageInstalled(packageA1)); Assert.Null(this.GetTestRegistryRoot()); this.Complete(); }
public void Burn_AutomaticSlipstreamInstallUninstall() { const string originalVersion = "1.0.0.0"; const string patchedVersion = "1.0.1.0"; // Build the packages. string packageA = this.GetPackageA().Output; string packageAUpdate = this.GetPackageAv101().Output; string packageB = this.GetPackageB().Output; string packageBUpdate = new PackageBuilder(this, "B") { PreprocessorVariables = new Dictionary <string, string>() { { "Version", patchedVersion } }, NeverGetsInstalled = true }.Build().Output; string patchA = new PatchBuilder(this, "PatchA") { PreprocessorVariables = new Dictionary <string, string>() { { "Version", patchedVersion } }, TargetPaths = new string[] { packageA, packageB }, UpgradePaths = new string[] { packageAUpdate, packageBUpdate } }.Build().Output; string patchB = new PatchBuilder(this, "PatchB") { PreprocessorVariables = new Dictionary <string, string>() { { "Version", patchedVersion } }, TargetPaths = new string[] { packageA, packageB }, UpgradePaths = new string[] { packageAUpdate, packageBUpdate } }.Build().Output; // Create the named bind paths to the packages. Dictionary <string, string> bindPaths = new Dictionary <string, string>(); bindPaths.Add("packageA", packageA); bindPaths.Add("packageB", packageB); bindPaths.Add("patchA", patchA); bindPaths.Add("patchB", patchB); string bundleC = new BundleBuilder(this, "BundleC") { BindPaths = bindPaths, Extensions = Extensions }.Build().Output; BundleInstaller install = new BundleInstaller(this, bundleC).Install(); using (RegistryKey root = this.GetTestRegistryRoot()) { // Product A should've slipstreamed both patches. string actualVersion = root.GetValue("A") as string; Assert.Equal(patchedVersion, actualVersion); actualVersion = root.GetValue("A2") as string; Assert.Equal(patchedVersion, actualVersion); // Product B should've only slipstreamed patch B. actualVersion = root.GetValue("B") as string; Assert.Equal(originalVersion, actualVersion); actualVersion = root.GetValue("B2") as string; Assert.Equal(patchedVersion, actualVersion); } install.Uninstall(); Assert.True(null == this.GetTestRegistryRoot(), "Test registry key should have been removed during uninstall."); this.Complete(); }
public override void AddPatches(PatchBuilder builder) { builder.Patch("7.7.11", "7.7.12", "2020-09-7", "Upgrades sensenet content repository.") .Action(context => { #region CTD changes var cb = new ContentTypeBuilder(); cb.Type("Settings") .Field("Description", "LongText") .VisibleBrowse(FieldVisibility.Hide) .VisibleEdit(FieldVisibility.Show) .VisibleNew(FieldVisibility.Show); cb.Apply(); #endregion #region Settings Description field changes SetSettingsDescription("Indexing", "In this Settings file you can customize the indexing behavior (for example the text extractor used in case of different file types) of the system."); SetSettingsDescription("Logging", "Contains logging-related settings, for example which events are sent to the trace. You can control tracing by category: switch on or off writing messages in certain categories to the trace channel."); SetSettingsDescription("MailProcessor", "The content list Inbox feature requires an Exchange or POP3 server configuration and other settings related to connecting libraries to a mailbox."); SetSettingsDescription("OAuth", "When users log in using one of the configured OAuth providers (like Google or Facebook), these settings control the type and place of the newly created users."); SetSettingsDescription("OfficeOnline", "To open or edit Office documents in the browser, the system needs to know the address of the Office Online Server that provides the user interface for the feature. In this section you can configure that and other OOS-related settings."); SetSettingsDescription("Sharing", "Content sharing related options."); SetSettingsDescription("TaskManagement", "When the Task Management module is installed, this is the place where you can configure the connection to the central task management service."); SetSettingsDescription("UserProfile", "When a user is created, and the profile feature is enabled (in the app configuration), they automatically get a profile – a workspace dedicated to the user’s personal documents and tasks. In this setting section you can customize the content type and the place of this profile."); void SetSettingsDescription(string name, string description) { var settings = Content.Load("/Root/System/Settings/" + name + ".settings"); if (settings == null) { return; } settings["Description"] = description; settings.SaveSameVersion(); } #endregion #region App changes var app1 = Content.Load("/Root/(apps)/Folder/Add"); if (app1 != null) { app1["Scenario"] = string.Empty; app1.SaveSameVersion(); } var app2 = Content.Load("/Root/(apps)/ContentType/Edit"); if (app2 == null) { var parent = RepositoryTools.CreateStructure("/Root/(apps)/ContentType") ?? Content.Load("/Root/(apps)/ContentType"); app2 = Content.CreateNew("ClientApplication", parent.ContentHandler, "Edit"); app2["DisplayName"] = "$Action,Edit"; app2["Scenario"] = "ContextMenu"; app2["Icon"] = "edit"; app2["RequiredPermissions"] = "See;Open;OpenMinor;Save"; app2.Save(); // set app permissions var developersGroupId = NodeHead.Get("/Root/IMS/BuiltIn/Portal/Developers")?.Id ?? 0; var aclEditor = SecurityHandler.SecurityContext.CreateAclEditor(); aclEditor .Allow(app2.Id, Identifiers.AdministratorsGroupId, false, PermissionType.RunApplication); if (developersGroupId > 0) { aclEditor.Allow(app2.Id, developersGroupId, false, PermissionType.RunApplication); } aclEditor.Apply(); } #endregion }); builder.Patch("7.7.12", "7.7.13", "2020-09-23", "Upgrades sensenet content repository.") .Action(context => { #region String resources var rb = new ResourceBuilder(); rb.Content("CtdResourcesAB.xml") .Class("Ctd-BinaryFieldSetting") .Culture("en") .AddResource("DisplayName", "Binary field") .Culture("hu") .AddResource("DisplayName", "Bináris mezÅ‘"); rb.Content("CtdResourcesCD.xml") .Class("Ctd-ChoiceFieldSetting") .Culture("en") .AddResource("DisplayName", "Choice field") .Culture("hu") .AddResource("DisplayName", "Választó mezÅ‘") .Class("Ctd-CurrencyFieldSetting") .Culture("en") .AddResource("DisplayName", "Currency field") .Culture("hu") .AddResource("DisplayName", "Pénzérték mezÅ‘") .Class("Ctd-DateTimeFieldSetting") .Culture("en") .AddResource("DisplayName", "DateTime field") .Culture("hu") .AddResource("DisplayName", "Dátum mezÅ‘"); rb.Content("CtdResourcesEF.xml") .Class("Ctd-FieldControlTemplate") .Culture("en") .AddResource("DisplayName", "FieldControlTemplate") .AddResource("Description", "A type for FieldControl templates.") .Culture("hu") .AddResource("DisplayName", "MezÅ‘ vezérlÅ‘ sablon") .AddResource("Description", "MezÅ‘ vezérlÅ‘ sablont tároló fájl") .Class("Ctd-FieldControlTemplates") .Culture("en") .AddResource("DisplayName", "FieldControlTemplates") .AddResource("Description", "This is the container type for ContentViews. Instances are allowed only at /Root/Global/fieldcontroltemplates.") .Culture("hu") .AddResource("DisplayName", "MezÅ‘ vezérlÅ‘ sablonok") .AddResource("Description", "MezÅ‘ vezérlÅ‘ sablonokat tároló mappa. Csak egy lehet, itt: /Root/Global/fieldcontroltemplates."); rb.Content("CtdResourcesGH.xml") .Class("Ctd-HyperLinkFieldSetting") .Culture("en") .AddResource("DisplayName", "Hyperlink field") .Culture("hu") .AddResource("DisplayName", "Hivatkozás mezÅ‘"); rb.Content("CtdResourcesIJK.xml") .Class("Ctd-Image") .Culture("en") .AddResource("DisplayName", "Image") .AddResource("Name-DisplayName", "Name") .Culture("hu") .AddResource("DisplayName", "Kép") .AddResource("Name-DisplayName", "Név") .Class("Ctd-IntegerFieldSetting") .Culture("en") .AddResource("DisplayName", "Integer field") .Culture("hu") .AddResource("DisplayName", "Egész szám mezÅ‘"); rb.Content("CtdResourcesLM.xml") .Class("Ctd-LongTextFieldSetting") .Culture("en") .AddResource("DisplayName", "Longtext field") .Culture("hu") .AddResource("DisplayName", "Hosszú szöveges mezÅ‘"); rb.Content("CtdResourcesNOP.xml") .Class("Ctd-NullFieldSetting") .Culture("en") .AddResource("DisplayName", "Null field") .Culture("hu") .AddResource("DisplayName", "Null mezÅ‘") .Class("Ctd-NumberFieldSetting") .Culture("en") .AddResource("DisplayName", "Number field") .Culture("hu") .AddResource("DisplayName", "Szám mezÅ‘") .Class("Ctd-PasswordFieldSetting") .Culture("en") .AddResource("DisplayName", "Password field") .Culture("hu") .AddResource("DisplayName", "Jelszó mezÅ‘") .Class("Ctd-PermissionChoiceFieldSetting") .Culture("en") .AddResource("DisplayName", "Permission choice field") .Culture("hu") .AddResource("DisplayName", "Jogosultság választó mezÅ‘"); rb.Content("CtdResourcesRS.xml") .Class("Ctd-ReferenceFieldSetting") .Culture("en") .AddResource("DisplayName", "Reference field") .Culture("hu") .AddResource("DisplayName", "Referencia mezÅ‘") .Class("Ctd-ShortTextFieldSetting") .Culture("en") .AddResource("DisplayName", "ShortText field") .Culture("hu") .AddResource("DisplayName", "Rövid szöveges mezÅ‘"); rb.Content("CtdResourcesTZ.xml") .Class("Ctd-Workspace") .Culture("en") .AddResource("Name-DisplayName", "Name") .Culture("hu") .AddResource("Name-DisplayName", "Név") .Class("Ctd-TextFieldSetting") .Culture("en") .AddResource("DisplayName", "Text field") .Culture("hu") .AddResource("DisplayName", "Szöveges mezÅ‘") .Class("Ctd-UserControl") .Culture("en") .AddResource("DisplayName", "User control") .AddResource("Description", "A type for storing ASP.NET user controls.") .Culture("hu") .AddResource("DisplayName", "Egyéni vezérlÅ‘elem") .AddResource("Description", "ASP.NET user control tárolására.") .Class("Ctd-ViewBase") .Culture("en") .AddResource("DisplayName", "View base") .AddResource("Description", "An abstract type for ContentList views.") .AddResource("IsDefault-DisplayName", "Default") .AddResource("IsDefault-Description", "Whether this is the default view on the parent ContentList.") .AddResource("Template-DisplayName", "Markup template") .AddResource("Template-Description", "The Xslt template used to generate the view.") .AddResource("FilterXml-DisplayName", "Filtering") .AddResource("FilterXml-Description", "Define filtering rules for the view.") .AddResource("EnableAutofilters-DisplayName", "Enable autofilters") .AddResource("EnableAutofilters-Description", "If autofilters are enabled system content will be filtered from the query.") .AddResource("EnableLifespanFilter-DisplayName", "Enable lifespan filter") .AddResource("EnableLifespanFilter-Description", "If lifespan filter is enabled only valid content will be in the result.") .AddResource("Hidden-Description", "The view won't show in the selector menu if checked. (If unsure, leave unchecked).") .AddResource("QueryTop-DisplayName", "Top") .AddResource("QueryTop-Description", "If you do not want to display all content please specify here a value greater than 0.") .AddResource("QuerySkip-DisplayName", "Skip") .AddResource("QuerySkip-Description", "If you do not want to display the first several content please specify here a value greater than 0.") .AddResource("Icon-DisplayName", "Icon identifier") .AddResource("Icon-Description", "The string identifier of the View's icon.") .Culture("hu") .AddResource("DisplayName", "View base") .AddResource("Description", "Minden view (listanézet) Å‘se.") .AddResource("IsDefault-DisplayName", "Alapértelmezett") .AddResource("IsDefault-Description", "Legyen ez az alapértelmezett listanézet..") .AddResource("Template-DisplayName", "Sablon") .AddResource("Template-Description", "A listát generáló xslt sablon.") .AddResource("FilterXml-DisplayName", "Szűrés") .AddResource("FilterXml-Description", "A listanézet szűrési feltételei.") .AddResource("EnableAutofilters-DisplayName", "Automata szűrések bekapcsolása") .AddResource("EnableAutofilters-Description", "Ha be van kapcsolva, a rendszer fájlok kiszűrésre kerülnek.") .AddResource("EnableLifespanFilter-DisplayName", "Élettartam szűrés") .AddResource("EnableLifespanFilter-Description", "Ha be van kapcsolva, akkor csak az idÅ‘ben aktuális elemek jelennek meg.") .AddResource("Hidden-Description", "Ha be van pipálva, akkor a listanézet nem jelenik meg a választhatók között a felületen.") .AddResource("QueryTop-DisplayName", "Elemszám") .AddResource("QueryTop-Description", "Ha nem akarja az összes elemet megjelenÃteni, Ãrjon be egy nullánál nagyobb számot.") .AddResource("QuerySkip-DisplayName", "Kihagyott elemek") .AddResource("QuerySkip-Description", "Ha a lista elsÅ‘ valahány elemét ki szeretné hagyni a megjelenÃtésbÅ‘l, Ãrja be az elhagyni kÃvánt elemek számát.") .AddResource("Icon-DisplayName", "Ikon azonosÃtó") .AddResource("Icon-Description", "Név amely a listanézet ikonját azonosÃtja.") .Class("Ctd-WebContent") .Culture("en") .AddResource("DisplayName", "Web Content (structured web content)") .AddResource("Description", "Web Content is the base type for structured web content.") .AddResource("ReviewDate-DisplayName", "Review date") .AddResource("ReviewDate-Description", "") .AddResource("ArchiveDate-DisplayName", "Archive date") .AddResource("ArchiveDate-Description", "") .Culture("hu") .AddResource("DisplayName", "Webes tartalom") .AddResource("Description", "") .AddResource("ReviewDate-DisplayName", "EllenÅ‘rzés dátuma") .AddResource("ReviewDate-Description", "") .AddResource("ArchiveDate-DisplayName", "Archiválás dátuma") .AddResource("ArchiveDate-Description", "") .Class("Ctd-XmlFieldSetting") .Culture("en") .AddResource("DisplayName", "Xml field") .Culture("hu") .AddResource("DisplayName", "Xml mezÅ‘") .Class("Ctd-XsltApplication") .Culture("en") .AddResource("DisplayName", "Xslt application") .AddResource("Description", "Xslt rendering application.") .AddResource("Binary-DisplayName", "Xslt template") .AddResource("Binary-Description", "Upload or enter the Xslt template to be used in rendering.") .AddResource("MimeType-DisplayName", "MIME type") .AddResource("MimeType-Description", "Sets HTTP MIME type of the output stream. Default value: application/xml.") .AddResource("OmitXmlDeclaration-DisplayName", "OmitXmlDeclaration") .AddResource("OmitXmlDeclaration-Description", "Sets a value indicating whether to write XML declaration.") .AddResource("ResponseEncoding-DisplayName", "Response encoding") .AddResource("ResponseEncoding-Description", "Sets the text encoding to use. Default value: UTF-8.") .AddResource("WithChildren-DisplayName", "With children") .AddResource("WithChildren-Description", "Sets a value indicating whether to render content with all children Default value: true.") .AddResource("Cacheable-DisplayName", "Application is cached") .AddResource("Cacheable-Description", "If set the output of the application will be cached. <div class='ui-helper-clearfix sn-dialog-editportlet-warning'><img class='sn-icon sn-icon16 sn-floatleft' src='/Root/Global/images/icons/16/warning.png' /><i>Switching off application cache may cause performance issues!</i></div>") .AddResource("CacheableForLoggedInUser-DisplayName", "Application is cached for logged in users") .AddResource("CacheableForLoggedInUser-Description", "If set the output of the application will be cached for logged in users. <div class='ui-helper-clearfix sn-dialog-editportlet-warning'><img class='sn-icon sn-icon16 sn-floatleft' src='/Root/Global/images/icons/16/warning.png' /><i>Switching off application cache may cause performance issues!</i></div>") .AddResource("CacheByPath-DisplayName", "Request path influences caching") .AddResource("CacheByPath-Description", "Defines whether the requested content path is included in the cache key. When unchecked application output is preserved regardless of the page's current context content or request path. Check it if you want to cache application output depending on the requested context content.") .AddResource("CacheByParams-DisplayName", "Url query params influence caching") .AddResource("CacheByParams-Description", "Defines whether the url query params are also included in the cache key. When unchecked application output is preserved regardless of changing url params.") .AddResource("CacheByLanguage-DisplayName", "Language influences caching") .AddResource("CacheByLanguage-Description", "Defines whether the language code is also included in the cache key. When unchecked application output is preserved regardless of the language that the users use to browse the site.") .AddResource("CacheByHost-DisplayName", "Host influences caching") .AddResource("CacheByHost-Description", "Defines whether the URL-host (e.g. 'example.com') is also included in the cache key. When unchecked application output is preserved regardless of the host that the users use to browse the site.") .AddResource("AbsoluteExpiration-DisplayName", "Absolute expiration") .AddResource("AbsoluteExpiration-Description", "Given in seconds. The application will be refreshed periodically with the given time period. -1 means that the value is defined by 'AbsoluteExpirationSeconds' setting in the web.config.") .AddResource("SlidingExpirationMinutes-DisplayName", "Sliding expiration") .AddResource("SlidingExpirationMinutes-Description", "Given in seconds. The application is refreshed when it has not been accessed for the given seconds. -1 means that the value is defined by 'SlidingExpirationSeconds' setting in the web.config.") .AddResource("CustomCacheKey-DisplayName", "Custom cache key") .AddResource("CustomCacheKey-Description", "Defines a custom cache key independent of requested path and query params. Useful when the same static output is rendered at various pages. <div class='ui-helper-clearfix sn-dialog-editportlet-warning'><img class='sn-icon sn-icon16 sn-floatleft' src='/Root/Global/images/icons/16/warning.png' /><i>For experts only! Leave empty if unsure.</i></div>") .Culture("hu") .AddResource("DisplayName", "Xslt alkalmazás") .AddResource("Description", "Alkalmazás, amely XSLT segÃtségével jelenÃti meg az aktuális tartalmat.") .AddResource("Binary-DisplayName", "Xslt sablon") .AddResource("Binary-Description", "Adja meg az xslt sablont a megjelenÃtéshez.") .AddResource("MimeType-DisplayName", "MIME type") .AddResource("MimeType-Description", "BeállÃtja a kimeneti stream HTTP MIME type-ját. Alapértelmezett érték: <i>alkalmazás/xml</i>.") .AddResource("OmitXmlDeclaration-DisplayName", "Xml deklaráció kihagyása") .AddResource("OmitXmlDeclaration-Description", "Megadhatja, hogy kihagyjuk-e az xml deklarációt.") .AddResource("ResponseEncoding-DisplayName", "Kimeneti stream kódolás") .AddResource("ResponseEncoding-Description", "BeállÃtja a szöveg kódolását. Alapértelmezett érték: <i>UTF-8</i>.") .AddResource("WithChildren-DisplayName", "Gyermek tartalmak") .AddResource("WithChildren-Description", "Ha be van állÃtva, a gyermek elemek is szerepelni fognak az oldalon.") .AddResource("Cacheable-DisplayName", "Az oldal kerüljön be a gyorsÃtótárba") .AddResource("Cacheable-Description", "Ha be van állÃtva, az oldal kimenete bekerül a gyorsÃtótárba<div class='ui-helper-clearfix sn-dialog-editportlet-warning'><img class='sn-icon sn-icon16 sn-floatleft' src='/Root/Global/images/icons/16/warning.png' /><i>Ennek kikapcsolása nagy terhelés alatt sebesség-problémákat okozhat!</i></div>") .AddResource("CacheableForLoggedInUser-DisplayName", "Az oldal kerüljön be a gyorsÃtótárba belépett felhasználók számára.") .AddResource("CacheableForLoggedInUser-Description", "Ha be van állÃtva, az oldal kimenete bekerül a gyorsÃtótárba belépett felhasználók számára. <div class='ui-helper-clearfix sn-dialog-editportlet-warning'><img class='sn-icon sn-icon16 sn-floatleft' src='/Root/Global/images/icons/16/warning.png' /><i>Ennek kikapcsolása nagy terhelés alatt sebesség-problémákat okozhat!</i></div>") .AddResource("CacheByPath-DisplayName", "Az aktuális tartalom befolyásolja a cache-elést") .AddResource("CacheByPath-Description", "Ha be van állÃtva, a kért tartalom útvonala (Path) befolyásolja a gyorsÃtótárat. Ha nincs, az oldal kimenete ugyanaz lesz, függetlenül az aktuális tartalomtól.") .AddResource("CacheByParams-DisplayName", "URL paraméterek befolyásolják a gyorsÃtótárat") .AddResource("CacheByParams-Description", "Ha nincs bekapcsolva, az oldal kimenete ugyanaz lesz, függetlenül az URL paraméterektÅ‘l.") .AddResource("CacheByLanguage-DisplayName", "A nyelv befolyásolja a gyorsÃtótárat") .AddResource("CacheByLanguage-Description", "Ha nincs bekapcsolva, az oldal kimenete ugyanaz lesz, függetlenül attól, hogy a felhasználó milyen nyelven nézi az oldalt.") .AddResource("CacheByHost-DisplayName", "A host befolyásolja a gyorsÃtótárat") .AddResource("CacheByHost-Description", "Ha nincs bekapcsolva, az oldal kimenete ugyanaz lesz, függetlenül attól, hogy a felhasználó milyen url-host-ról nézi az oldalt.") .AddResource("AbsoluteExpiration-DisplayName", "Abszolút gyorsÃtótár lejárat") .AddResource("AbsoluteExpiration-Description", "Másodpercben megadott lejárat. Az oldal rendszeresen frissülni fog a megadott idÅ‘ után. <br />-1 azt jelenti, hogy az értéket az <i>AbsoluteExpirationSeconds</i> web.config beállÃtás határozza meg.") .AddResource("SlidingExpirationMinutes-DisplayName", "Csúszó gyorsÃtótár lejárat") .AddResource("SlidingExpirationMinutes-Description", "Másodpercben megadott lejárat. Az oldal frissülni fog, ha nem érkezett rá kérés a megadott idÅ‘n belül. <br />-1 azt jelenti, hogy az értéket az <i>SlidingExpirationSeconds</i> web.config beállÃtás határozza meg.") .AddResource("CustomCacheKey-DisplayName", "Egyedi gyorsÃtótár (cache) kulcs") .AddResource("CustomCacheKey-Description", "Megadhat egyedi gyorsÃtótár kulcsot, függetlenül az aktuális tartalomtól és URL paraméterektÅ‘l. Akkor érdemes használni, ha ugyanazt a statikus tartalmat szeretné megjelenÃteni több különbözÅ‘ oldalon. <div class='ui-helper-clearfix sn-dialog-editportlet-warning'><img class='sn-icon sn-icon16 sn-floatleft' src='/Root/Global/images/icons/16/warning.png' /><i>Csak adminisztrátoroknak. Hagyja üresen, ha nem biztos a dologban.</i></div>") .Class("Ctd-YesNoFieldSetting") .Culture("en") .AddResource("DisplayName", "Yes/No field") .Culture("hu") .AddResource("DisplayName", "Igen/nem mezÅ‘"); rb.Apply(); #endregion #region CTD changes var cb = new ContentTypeBuilder(); cb.Type("CalendarEvent") .Field("StartDate") .DefaultValue("@@currenttime@@") .Field("EndDate") .DefaultValue("@@currenttime@@"); cb.Type("GenericContent") .Field("ValidFrom") .DefaultValue("@@currenttime@@") .Field("ValidTill") .DefaultValue("@@currenttime@@"); cb.Type("Link") .Field("Url") .DefaultValue("https://"); cb.Type("User") .Field("LoginName") .VisibleEdit(FieldVisibility.Hide) .Field("Email") .VisibleBrowse(FieldVisibility.Show) .VisibleEdit(FieldVisibility.Hide) .VisibleNew(FieldVisibility.Show) .Field("BirthDate") .DefaultValue("@@currenttime@@"); cb.Type("Group") .Field("AllRoles") .VisibleBrowse(FieldVisibility.Hide) .VisibleEdit(FieldVisibility.Hide) .VisibleNew(FieldVisibility.Hide) .Field("DirectRoles") .VisibleBrowse(FieldVisibility.Hide) .VisibleEdit(FieldVisibility.Hide) .VisibleNew(FieldVisibility.Hide); cb.Apply(); #endregion #region Permission changes SecurityHandler.SecurityContext.CreateAclEditor() .Allow(NodeHead.Get("/Root/Localization").Id, Identifiers.OwnersGroupId, false, PermissionType.Save, PermissionType.Delete) .Apply(); #endregion }); builder.Patch("7.7.13", "7.7.14", "2020-11-19", "Upgrades sensenet content repository.") .Action(context => { #region CTD changes var cb = new ContentTypeBuilder(); cb.Type("ListItem") .Field("ModifiedBy") .VisibleEdit(FieldVisibility.Hide); cb.Type("User") .Field("BirthDate") .DefaultValue(""); cb.Apply(); #endregion }); builder.Patch("7.7.14", "7.7.16", "2020-12-08", "Upgrades sensenet content repository.") .Action(context => { #region CTD changes var cb = new ContentTypeBuilder(); // We can set the new regex only if the current regex is the old default // (otherwise we do not want to overwrite a custom regex). // NOTE: in the old regex below the & character appears as is (in the middle // of the first line), but in the new const we had to replace it with & // to let the patch algorithm set the correct value in the XML. const string oldUrlRegex = "^(http|https)\\://([a-zA-Z0-9\\.\\-]+(\\:[a-zA-Z0-9\\.&%\\$\\-]+)*@)*((25[0-5]|" + "2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9])\\.(25[0-5]|2[0-4][0-9]|[0-1]{1}" + "[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}" + "[0-9]{1}|[1-9]|0)\\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9])|" + "localhost|([a-zA-Z0-9\\-]+\\.)*[a-zA-Z0-9\\-]+(\\.(com|edu|gov|int|mil|net|org|biz|" + "arpa|info|name|pro|aero|coop|museum|hu|[a-zA-Z]{2})){0,1})(\\:[0-9]+)*((\\#|/)($|" + "[a-zA-Z0-9\\.\\,\\?\\'\\\\\\+&%\\$#\\=~_\\-]+))*$"; const string newUrlRegex = "^(https?|ftp)\\://([a-zA-Z0-9\\.\\-]+(\\:[a-zA-Z0-9\\.&%\\$\\-]+)*@)*((25[0-5]|" + "2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9])\\.(25[0-5]|2[0-4][0-9]|[0-1]{1}" + "[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}" + "[0-9]{1}|[1-9]|0)\\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9])|" + "localhost|([a-zA-Z0-9\\-]+\\.)*[a-zA-Z0-9\\-]+(\\.(com|edu|gov|int|mil|net|org|biz|" + "arpa|info|name|pro|aero|coop|museum|hu|[a-zA-Z]{2})){0,1})(\\:[0-9]+)*" + "(\\/[\\w\\-\\@\\/\\(\\)]*){0,1}((\\?|\\#)(($|[\\w\\.\\,\\'\\\\\\+&" + "%\\$#\\=~_\\-\\(\\)]+)*)){0,1}$"; var currentRegex = ((ShortTextFieldSetting)ContentType.GetByName("Link").GetFieldSettingByName("Url")).Regex; // replace the regex only if it was the original default if (string.Equals(oldUrlRegex, currentRegex, StringComparison.Ordinal)) { cb.Type("Link") .Field("Url") .Configure("Regex", newUrlRegex); } cb.Apply(); #endregion #region Content changes // create the new public admin user if (User.PublicAdministrator == null) { var publicAdmin = Content.CreateNew("User", OrganizationalUnit.Portal, "PublicAdmin"); publicAdmin["Enabled"] = true; publicAdmin["FullName"] = "PublicAdmin"; publicAdmin["LoginName"] = "PublicAdmin"; publicAdmin.Save(); } #endregion }); builder.Patch("7.7.16", "7.7.17", "2021-01-25", "Upgrades sensenet content repository.") .Action(context => { #region CTD changes const string ctDefaultValue = @"<?xml version=""1.0"" encoding=""utf-8""?> <ContentType name=""MyType"" parentType=""GenericContent"" handler=""SenseNet.ContentRepository.GenericContent"" xmlns=""http://schemas.sensenet.com/SenseNet/ContentRepository/ContentTypeDefinition""> <DisplayName>MyType</DisplayName> <Description></Description> <Icon>Content</Icon> <AllowIncrementalNaming>true</AllowIncrementalNaming> <AllowedChildTypes>ContentTypeName1,ContentTypeName2</AllowedChildTypes> <Fields> <Field name=""ShortTextField"" type=""ShortText""> <DisplayName>ShortTextField</DisplayName> <Description></Description> <Configuration> <MaxLength>100</MaxLength> <MinLength>0</MinLength> <Regex>[a-zA-Z0-9]*$</Regex> <ReadOnly>false</ReadOnly> <Compulsory>false</Compulsory> <DefaultValue></DefaultValue> <VisibleBrowse>Show|Hide</VisibleBrowse> <VisibleEdit>Show|Hide</VisibleEdit> <VisibleNew>Show|Hide</VisibleNew> </Configuration> </Field> <Field name=""LongTextField"" type=""LongText""> <DisplayName>LongTextField</DisplayName> <Description></Description> <Configuration> <MaxLength>100</MaxLength> <MinLength>0</MinLength> <TextType>LongText|RichText</TextType> <ReadOnly>false</ReadOnly> <Compulsory>false</Compulsory> <DefaultValue></DefaultValue> <VisibleBrowse>Show|Hide</VisibleBrowse> <VisibleEdit>Show|Hide</VisibleEdit> <VisibleNew>Show|Hide</VisibleNew> </Configuration> </Field> <Field name=""NumberField"" type=""Number""> <DisplayName>NumberField</DisplayName> <Description></Description> <Configuration> <MinValue>0</MinValue> <MaxValue>100.5</MaxValue> <Digits>2</Digits> <ReadOnly>false</ReadOnly> <Compulsory>false</Compulsory> <DefaultValue></DefaultValue> <VisibleBrowse>Show|Hide</VisibleBrowse> <VisibleEdit>Show|Hide</VisibleEdit> <VisibleNew>Show|Hide</VisibleNew> </Configuration> </Field> <Field name=""IntegerField"" type=""Integer""> <DisplayName>IntegerField</DisplayName> <Description></Description> <Configuration> <MinValue>0</MinValue> <MaxValue>100</MaxValue> <ReadOnly>false</ReadOnly> <Compulsory>false</Compulsory> <DefaultValue></DefaultValue> <VisibleBrowse>Show|Hide</VisibleBrowse> <VisibleEdit>Show|Hide</VisibleEdit> <VisibleNew>Show|Hide</VisibleNew> </Configuration> </Field> <Field name=""BooleanField"" type=""Boolean""> <DisplayName>BooleanField</DisplayName> <Description></Description> <Configuration> <ReadOnly>false</ReadOnly> <Compulsory>false</Compulsory> <DefaultValue></DefaultValue> <VisibleBrowse>Show|Hide</VisibleBrowse> <VisibleEdit>Show|Hide</VisibleEdit> <VisibleNew>Show|Hide</VisibleNew> </Configuration> </Field> <Field name=""ChoiceField"" type=""Choice""> <DisplayName>ChoiceField</DisplayName> <Description></Description> <Configuration> <AllowMultiple>false</AllowMultiple> <AllowExtraValue>false</AllowExtraValue> <Options> <Option selected=""true"">1</Option> <Option>2</Option> </Options> <ReadOnly>false</ReadOnly> <Compulsory>false</Compulsory> <DefaultValue></DefaultValue> <VisibleBrowse>Show|Hide</VisibleBrowse> <VisibleEdit>Show|Hide</VisibleEdit> <VisibleNew>Show|Hide</VisibleNew> </Configuration> </Field> <Field name=""DateTimeField"" type=""DateTime""> <DisplayName>DateTimeField</DisplayName> <Description></Description> <Configuration> <DateTimeMode>DateAndTime</DateTimeMode> <Precision>Second</Precision> <ReadOnly>false</ReadOnly> <Compulsory>false</Compulsory> <DefaultValue></DefaultValue> <VisibleBrowse>Show|Hide</VisibleBrowse> <VisibleEdit>Show|Hide</VisibleEdit> <VisibleNew>Show|Hide</VisibleNew> </Configuration> </Field> <Field name=""ReferenceField"" type=""Reference""> <DisplayName>ReferenceField</DisplayName> <Description></Description> <Configuration> <AllowMultiple>true</AllowMultiple> <AllowedTypes> <Type>Type1</Type> <Type>Type2</Type> </AllowedTypes> <SelectionRoot> <Path>/Root/Path1</Path> <Path>/Root/Path2</Path> </SelectionRoot> <DefaultValue>/Root/Path1,/Root/Path2</DefaultValue> <ReadOnly>false</ReadOnly> <Compulsory>false</Compulsory> <VisibleBrowse>Show|Hide</VisibleBrowse> <VisibleEdit>Show|Hide</VisibleEdit> <VisibleNew>Show|Hide</VisibleNew> </Configuration> </Field> <Field name=""BinaryField"" type=""Binary""> <DisplayName>BinaryField</DisplayName> <Description></Description> <Configuration> <IsText>true</IsText> <ReadOnly>false</ReadOnly> <Compulsory>false</Compulsory> <DefaultValue></DefaultValue> <VisibleBrowse>Show|Hide</VisibleBrowse> <VisibleEdit>Show|Hide</VisibleEdit> <VisibleNew>Show|Hide</VisibleNew> </Configuration> </Field> </Fields> </ContentType>"; var cb = new ContentTypeBuilder(); cb.Type("ContentType") .Field("Binary") .DefaultValue(ctDefaultValue); cb.Apply(); #endregion }); builder.Patch("7.7.17", "7.7.18", "2021-02-17", "Upgrades sensenet content repository.") .Action(context => { #region String resources var rb = new ResourceBuilder(); rb.Content("CtdResourcesQ.xml") .Class("Ctd-Query") .Culture("en") .AddResource("UiFilters-DisplayName", "UI filters") .AddResource("UiFilters-Description", "Technical field for filter data.") .Culture("hu") .AddResource("UiFilters-DisplayName", "UI szűrÅ‘k") .AddResource("UiFilters-Description", "Technikai mezÅ‘ szűrÅ‘ adatoknak."); rb.Content("ActionResources.xml") .Class("Action") .Culture("en") .AddResource("Browse", "Details"); rb.Apply(); #endregion #region CTD changes var cb = new ContentTypeBuilder(); cb.Type("Query") .Field("UiFilters", "LongText") .DisplayName("$Ctd-Query,UiFilters-DisplayName") .Description("$Ctd-Query,UiFilters-Description") .VisibleBrowse(FieldVisibility.Hide) .VisibleEdit(FieldVisibility.Hide) .VisibleNew(FieldVisibility.Hide); cb.Type("File") .Field("Size") .ControlHint("sn:FileSize"); cb.Apply(); #endregion }); }
public void Burn_PatchOnePackageTwoPatches() { string originalVersion = "1.0.0.0"; string patchedVersion = "1.0.1.0"; // Build the packages. string packageA = new PackageBuilder(this, "A") { Extensions = WixTests.Extensions }.Build().Output; string packageAUpdate = new PackageBuilder(this, "A") { Extensions = WixTests.Extensions, PreprocessorVariables = new Dictionary<string, string>() { { "Version", patchedVersion } }, NeverGetsInstalled = true }.Build().Output; string patchA = new PatchBuilder(this, "PatchA") { Extensions = WixTests.Extensions, TargetPath = packageA, UpgradePath = packageAUpdate }.Build().Output; string patchA2 = new PatchBuilder(this, "PatchA2") { Extensions = WixTests.Extensions, TargetPath = packageA, UpgradePath = packageAUpdate }.Build().Output; // Create the named bind paths to the packages. Dictionary<string, string> bindPaths = new Dictionary<string, string>(); bindPaths.Add("patchA", patchA); bindPaths.Add("patchA2", patchA2); string bundlePatch = new BundleBuilder(this, "PatchBundleA2") { BindPaths = bindPaths, Extensions = WixTests.Extensions, SuppressPatchSequenceData = true }.Build().Output; // Install the original MSI and ensure the registry keys that get patched are as expected. MSIExec.InstallProduct(packageA, MSIExec.MSIExecReturnCode.SUCCESS); using (RegistryKey root = this.GetTestRegistryRoot()) { string actualVersion = root.GetValue("A") as string; Assert.Equal(originalVersion, actualVersion); actualVersion = root.GetValue("A2") as string; Assert.Equal(originalVersion, actualVersion); } // Install the bundle of patches and ensure all the registry keys are updated. BundleInstaller installPatches = new BundleInstaller(this, bundlePatch).Install(); using (RegistryKey root = this.GetTestRegistryRoot()) { string actualVersion = root.GetValue("A") as string; Assert.Equal(patchedVersion, actualVersion); actualVersion = root.GetValue("A2") as string; Assert.Equal(patchedVersion, actualVersion); } // Uninstall the patch bundle and verify the keys go back to original values. installPatches.Uninstall(); using (RegistryKey root = this.GetTestRegistryRoot()) { string actualVersion = root.GetValue("A") as string; Assert.Equal(originalVersion, actualVersion); actualVersion = root.GetValue("A2") as string; Assert.Equal(originalVersion, actualVersion); } this.Complete(); }
/* ============================================================ TOOLS */ private string PatchesToString(PatchBuilder builder) { return(string.Join(" | ", builder.GetPatches())); }
public override void AddPatches(PatchBuilder builder) { builder .Install("0.0.4", "2021-06-09", "sensenet WebHooks") .DependsOn("SenseNet.Services", "7.7.22") .Action(context => { #region String resource InstallStringResource("CtdResourcesWebHookSubscription.xml"); #endregion #region Install CTD InstallCtd("WebHookSubscriptionCtd.xml"); #endregion #region Content items CreateWebHooksContainer(); #endregion }); builder.Patch("0.0.1", "0.0.3", "2021-03-17", "Upgrades the WebHook component") .DependsOn("SenseNet.Services", "7.7.19") .Action(context => { #region String resources var rb = new ResourceBuilder(); rb.Content("CtdResourcesWebHookSubscription.xml") .Class("Ctd-WebHookSubscription") .Culture("en") .AddResource("DisplayName", "Webhook") .Culture("hu") .AddResource("DisplayName", "Webhook"); rb.Apply(); #endregion #region CTD changes var cb = new ContentTypeBuilder(context.GetService <ILogger <ContentTypeBuilder> >()); cb.Type("WebHookSubscription") .Icon("Settings") .Field("WebHookPayload", "LongText") .DisplayName("$Ctd-WebHookSubscription,WebHookPayload-DisplayName") .Description("$Ctd-WebHookSubscription,WebHookPayload-Description") .VisibleBrowse(FieldVisibility.Show) .VisibleEdit(FieldVisibility.Show) .VisibleNew(FieldVisibility.Show) .FieldIndex(10) .ControlHint("sn:WebhookPayload") .Field("WebHookFilter") .FieldIndex(50) .Field("WebHookHeaders") .FieldIndex(40) .Field("Enabled") .FieldIndex(90) .Field("IsValid") .FieldIndex(30) .VisibleBrowse(FieldVisibility.Hide) .Field("InvalidFields") .RemoveConfiguration("FieldIndex") .VisibleBrowse(FieldVisibility.Hide) .VisibleEdit(FieldVisibility.Hide) .VisibleNew(FieldVisibility.Hide) .Field("SuccessfulCalls") .FieldIndex(20) .Field("WebHookHttpMethod") .DefaultValue("POST"); cb.Apply(); #endregion #region Content items CreateWebHooksContainer(); #endregion }); builder.Patch("0.0.3", "0.0.4", "2021-06-09", "Upgrades the WebHook component") .DependsOn("SenseNet.Services", "7.7.22") .Action(context => { // Do nothing, this is just a version update, because the CTD change (richtext type // change of the Description field) is already handled by the Services component patch. }); }
private IInternalJsonMergePatchDocument CreatePatchDocument(Type jsonMergePatchType, Type modelType, JsonElement jsonElement) { var jsonMergePatchDocument = PatchBuilder.CreatePatchDocument(modelType, jsonElement, base.SerializerOptions, this._jsonMergePatchOptions); return(jsonMergePatchDocument); }
private PatchBuilder GetPatchA() { if (null == this.patchA) { string packageA = this.GetPackageA().Output; string packageAUpdate = this.GetPackageAv101().Output; this.patchA = new PatchBuilder(this, "PatchA") { TargetPath = packageA, UpgradePath = packageAUpdate }.Build(); } return this.patchA; }
public void Burn_PatchTag() { string originalVersion = "1.0.0.0"; string patchedVersion = "1.0.1.0"; string actualVersion = null; // Build the packages. string packageA = new PackageBuilder(this, "A") { Extensions = WixTests.Extensions }.Build().Output; string packageAUpdate = new PackageBuilder(this, "A") { Extensions = WixTests.Extensions, PreprocessorVariables = new Dictionary<string, string>() { { "Version", patchedVersion } }, NeverGetsInstalled = true }.Build().Output; string patchA = new PatchBuilder(this, "PatchA") { Extensions = WixTests.Extensions, TargetPath = packageA, UpgradePath = packageAUpdate }.Build().Output; // Create the named bind paths to the packages. Dictionary<string, string> bindPaths = new Dictionary<string, string>(); bindPaths.Add("packageA", packageA); bindPaths.Add("patchA", patchA); string bundleA = new BundleBuilder(this, "BundleA") { BindPaths = bindPaths, Extensions = WixTests.Extensions }.Build().Output; string bundleAPatch = new BundleBuilder(this, "PatchBundleA") { BindPaths = bindPaths, Extensions = WixTests.Extensions, PreprocessorVariables = new Dictionary<string, string>() { { "Version", patchedVersion } } }.Build().Output; // Install the unpatched bundle. BundleInstaller installA = new BundleInstaller(this, bundleA).Install(); actualVersion = GetTagVersion("~Burn_PatchTag - Bundle A"); Assert.Equal(originalVersion, actualVersion); actualVersion = GetTagVersion("~Burn_PatchTag - A"); Assert.Equal(originalVersion, actualVersion); // Install the patch bundle. BundleInstaller installAPatch = new BundleInstaller(this, bundleAPatch).Install(); actualVersion = GetTagVersion("~Burn_PatchTag - Patch Bundle A"); Assert.Equal(patchedVersion, actualVersion); actualVersion = GetTagVersion("~Burn_PatchTag - A"); Assert.Equal(patchedVersion, actualVersion); // Uninstall the patch bundle. installAPatch.Uninstall(); actualVersion = GetTagVersion("~Burn_PatchTag - A"); Assert.Equal(originalVersion, actualVersion); // Uninstall the original bundle and ensure all the tags are gone. installA.Uninstall(); actualVersion = GetTagVersion("~Burn_PatchTag - Bundle A"); Assert.Null(actualVersion); actualVersion = GetTagVersion("~Burn_PatchTag - A"); Assert.Null(actualVersion); this.Complete(); }
public void Burn_MajorUpgradeWithSlipstream() { const string originalVersion = "1.0.0.0"; const string upgradeVersion = "2.0.0.0"; const string patchedVersion = "2.0.1.0"; // Build the packages. string originalPackageA = this.GetPackageA().Output; string upgradePackageA = new PackageBuilder(this, "A") { PreprocessorVariables = new Dictionary<string, string>() { { "Version", upgradeVersion } }, }.Build().Output; string packageAUpdate = new PackageBuilder(this, "A") { PreprocessorVariables = new Dictionary<string, string>() { { "Version", patchedVersion } }, NeverGetsInstalled = true }.Build().Output; string patchA = new PatchBuilder(this, "PatchA") { PreprocessorVariables = new Dictionary<string, string>() { { "Version", patchedVersion } }, TargetPaths = new string[] { upgradePackageA }, UpgradePaths = new string[] { packageAUpdate } }.Build().Output; // Create the named bind paths to the packages in the bundle. Dictionary<string, string> bindPaths = new Dictionary<string, string>(); bindPaths.Add("packageA", upgradePackageA); bindPaths.Add("patchA", patchA); string bundleA = new BundleBuilder(this, "BundleA") { BindPaths = bindPaths, Extensions = Extensions }.Build().Output; // Install the original MSI. MSIExec.InstallProduct(originalPackageA, MSIExec.MSIExecReturnCode.SUCCESS); Assert.True(MsiVerifier.IsPackageInstalled(originalPackageA)); using (RegistryKey root = this.GetTestRegistryRoot()) { // Original Product A should be present. string actualVersion = root.GetValue("A") as string; Assert.Equal(originalVersion, actualVersion); } // Now install the bundle that should upgrade the MSI and apply the patch. BundleInstaller install = new BundleInstaller(this, bundleA).Install(); Assert.False(MsiVerifier.IsPackageInstalled(originalPackageA)); Assert.True(MsiVerifier.IsPackageInstalled(upgradePackageA)); using (RegistryKey root = this.GetTestRegistryRoot()) { // Product A should've slipstreamed with its patch. string actualVersion = root.GetValue("A") as string; Assert.Equal(patchedVersion, actualVersion); } install.Uninstall(); Assert.True(null == this.GetTestRegistryRoot(), "Test registry key should have been removed during uninstall."); this.Complete(); }
public void Burn_InstallUninstallStickyPatchRelatedBundle() { const string patchVersion = "1.0.1.0"; // Build the packages. string packageA1 = new PackageBuilder(this, "A").Build().Output; string packageA2 = new PackageBuilder(this, "A") { PreprocessorVariables = new Dictionary<string, string>() { { "Version", patchVersion } }, NeverGetsInstalled = true }.Build().Output; string packageB1 = new PackageBuilder(this, "B").Build().Output; string packageB2 = new PackageBuilder(this, "B") { PreprocessorVariables = new Dictionary<string, string>() { { "Version", patchVersion } }, NeverGetsInstalled = true }.Build().Output; string patchA = new PatchBuilder(this, "PatchA") { PreprocessorVariables = new Dictionary<string, string>() { { "Version", patchVersion } }, TargetPaths = new string[] { packageA1, packageB1 }, UpgradePaths = new string[] { packageA2, packageB2 } }.Build().Output; // Create the named bind paths to the packages. Dictionary<string, string> bindPaths = new Dictionary<string, string>(); bindPaths.Add("packageA", packageA1); bindPaths.Add("packageB", packageB1); bindPaths.Add("patchA", patchA); // Build the bundles. string bundleA = new BundleBuilder(this, "BundleA") { BindPaths = bindPaths, Extensions = Extensions }.Build().Output; string bundleB = new BundleBuilder(this, "BundleB") { BindPaths = bindPaths, Extensions = Extensions }.Build().Output; string bundleD = new BundleBuilder(this, "BundleD") { PreprocessorVariables = new Dictionary<string, string>() { { "Version", patchVersion } }, BindPaths = bindPaths, Extensions = Extensions }.Build().Output; // Install the bundles. BundleInstaller installerA = new BundleInstaller(this, bundleA).Install(); BundleInstaller installerD = new BundleInstaller(this, bundleD).Install(); // Make sure that bundle D detected dependent bundle A. Assert.IsTrue(LogVerifier.MessageInLogFileRegex(installerD.LastLogFile, @"Detected related bundle: \{[0-9A-Za-z\-]{36}\}, type: Dependent, scope: PerMachine, version: 1\.0\.0\.0, operation: None")); // Test that packageA1 and patchA are installed. Assert.IsTrue(MsiVerifier.IsPackageInstalled(packageA1)); using (RegistryKey root = this.GetTestRegistryRoot()) { string actualVersion = root.GetValue("A") as string; Assert.AreEqual(patchVersion, actualVersion); } // Install bundle B (tests sticky patching). BundleInstaller installerB = new BundleInstaller(this, bundleB).Install(); Assert.IsTrue(LogVerifier.MessageInLogFileRegex(installerB.LastLogFile, @"Detected related bundle: \{[0-9A-Za-z\-]{36}\}, type: Patch, scope: PerMachine, version: 1\.0\.1\.0, operation: Install")); Assert.IsTrue(LogVerifier.MessageInLogFileRegex(installerB.LastLogFile, @"Detected related bundle: \{[0-9A-Za-z\-]{36}\}, type: Detect, scope: PerMachine, version: 1\.0\.0\.0, operation: None")); // Test that packageB and patchA are installed. Assert.IsTrue(MsiVerifier.IsPackageInstalled(packageB1)); using (RegistryKey root = this.GetTestRegistryRoot()) { string actualVersion = root.GetValue("B") as string; Assert.AreEqual(patchVersion, actualVersion); } // Attempt to uninstall bundleA. installerA.Uninstall(); // Test that packageA is still installed (ref-counted). Assert.IsTrue(MsiVerifier.IsPackageInstalled(packageA1)); // Test that uninstalling bundle A detected bundle D (ref-counted). Assert.IsTrue(LogVerifier.MessageInLogFileRegex(installerA.LastLogFile, @"Detected related bundle: \{[0-9A-Za-z\-]{36}\}, type: Patch, scope: PerMachine, version: 1\.0\.1\.0, operation: Remove")); Assert.IsTrue(LogVerifier.MessageInLogFileRegex(installerA.LastLogFile, @"Will not uninstall package: \{[0-9A-Za-z\-]{36}\}, found dependents: 1")); // Attempt to uninstall bundleB. installerB.Uninstall(); // Test that all packages are uninstalled. Assert.IsFalse(MsiVerifier.IsPackageInstalled(packageA1)); Assert.IsFalse(MsiVerifier.IsPackageInstalled(packageB1)); Assert.IsNull(this.GetTestRegistryRoot()); // Test that uninstalling bundle B detected and removed bundle D (ref-counted). Assert.IsTrue(LogVerifier.MessageInLogFileRegex(installerB.LastLogFile, @"Detected related bundle: \{[0-9A-Za-z\-]{36}\}, type: Patch, scope: PerMachine, version: 1\.0\.1\.0, operation: Remove")); this.CleanTestArtifacts = true; }
public void Burn_MajorUpgradeWithSlipstream() { const string originalVersion = "1.0.0.0"; const string upgradeVersion = "2.0.0.0"; const string patchedVersion = "2.0.1.0"; // Build the packages. string originalPackageA = this.GetPackageA().Output; string upgradePackageA = new PackageBuilder(this, "A") { PreprocessorVariables = new Dictionary <string, string>() { { "Version", upgradeVersion } }, }.Build().Output; string packageAUpdate = new PackageBuilder(this, "A") { PreprocessorVariables = new Dictionary <string, string>() { { "Version", patchedVersion } }, NeverGetsInstalled = true }.Build().Output; string patchA = new PatchBuilder(this, "PatchA") { PreprocessorVariables = new Dictionary <string, string>() { { "Version", patchedVersion } }, TargetPaths = new string[] { upgradePackageA }, UpgradePaths = new string[] { packageAUpdate } }.Build().Output; // Create the named bind paths to the packages in the bundle. Dictionary <string, string> bindPaths = new Dictionary <string, string>(); bindPaths.Add("packageA", upgradePackageA); bindPaths.Add("patchA", patchA); string bundleA = new BundleBuilder(this, "BundleA") { BindPaths = bindPaths, Extensions = Extensions }.Build().Output; // Install the original MSI. MSIExec.InstallProduct(originalPackageA, MSIExec.MSIExecReturnCode.SUCCESS); Assert.True(MsiVerifier.IsPackageInstalled(originalPackageA)); using (RegistryKey root = this.GetTestRegistryRoot()) { // Original Product A should be present. string actualVersion = root.GetValue("A") as string; Assert.Equal(originalVersion, actualVersion); } // Now install the bundle that should upgrade the MSI and apply the patch. BundleInstaller install = new BundleInstaller(this, bundleA).Install(); Assert.False(MsiVerifier.IsPackageInstalled(originalPackageA)); Assert.True(MsiVerifier.IsPackageInstalled(upgradePackageA)); using (RegistryKey root = this.GetTestRegistryRoot()) { // Product A should've slipstreamed with its patch. string actualVersion = root.GetValue("A") as string; Assert.Equal(patchedVersion, actualVersion); } install.Uninstall(); Assert.True(null == this.GetTestRegistryRoot(), "Test registry key should have been removed during uninstall."); this.Complete(); }
public void Burn_BuildNonSpecificPatches() { string patchedVersion = "1.0.1.0"; string[] extensions = new string[] { "WixBalExtension", "WixTagExtension", }; // Build the packages. string packageA = new PackageBuilder(this, "A") { Extensions = extensions }.Build().Output; string packageAUpdate = new PackageBuilder(this, "A") { Extensions = extensions, PreprocessorVariables = new Dictionary <string, string>() { { "Version", patchedVersion } }, NeverGetsInstalled = true }.Build().Output; string patchA = new PatchBuilder(this, "PatchA") { Extensions = extensions, TargetPath = packageA, UpgradePath = packageAUpdate }.Build().Output; string patchB = new PatchBuilder(this, "PatchB") { Extensions = extensions, TargetPath = packageA, UpgradePath = packageAUpdate }.Build().Output; string patchC = new PatchBuilder(this, "PatchC") { Extensions = extensions, TargetPath = packageA, UpgradePath = packageAUpdate }.Build().Output; // Build the bundles. Dictionary <string, string> bindPaths = new Dictionary <string, string>(); bindPaths.Add("packageA", packageA); bindPaths.Add("patchA", patchA); bindPaths.Add("patchB", patchB); bindPaths.Add("patchC", patchC); string bundleA = new BundleBuilder(this, "BundleA") { BindPaths = bindPaths, Extensions = extensions }.Build().Output; WixTest.BundleBuilder bundleAPatch = new BundleBuilder(this, "PatchBundleA") { BindPaths = bindPaths, Extensions = extensions, PreprocessorVariables = new Dictionary <string, string>() { { "Version", patchedVersion } } }.Build(); WixTest.BundleBuilder bundleBPatch = new BundleBuilder(this, "PatchBundleB") { BindPaths = bindPaths, Extensions = extensions, PreprocessorVariables = new Dictionary <string, string>() { { "Version", patchedVersion } } }.Build(); WixTest.BundleBuilder bundleCPatch = new BundleBuilder(this, "PatchBundleC") { BindPaths = bindPaths, Extensions = extensions, PreprocessorVariables = new Dictionary <string, string>() { { "Version", patchedVersion } } }.Build(); // Disassemble the patch bundles and check for PatchTargetCode elements. XmlNodeList nodes = PatchTests.GetPatchTargetCodes(bundleAPatch); Assert.Equal(1, nodes.Count); Assert.True(nodes.OfType <XmlElement>().Any(elem => elem.HasAttribute("Product") && "yes".Equals(elem.Attributes["Product"].Value))); nodes = PatchTests.GetPatchTargetCodes(bundleBPatch); Assert.Equal(2, nodes.Count); Assert.True(nodes.OfType <XmlElement>().Any(elem => elem.HasAttribute("Product") && "yes".Equals(elem.Attributes["Product"].Value))); Assert.True(nodes.OfType <XmlElement>().Any(elem => elem.HasAttribute("Product") && "no".Equals(elem.Attributes["Product"].Value))); nodes = PatchTests.GetPatchTargetCodes(bundleCPatch); Assert.Equal(0, nodes.Count); this.Complete(); }
public void Burn_InstallUpgradeSlipstreamBundle() { const string expectedVersion1 = "1.0.0.0"; const string expectedVersion2 = "1.0.1.0"; // Build the packages. string packageA = new PackageBuilder(this, "A") { Extensions = Extensions }.Build().Output; string packageA1 = new PackageBuilder(this, "A") { Extensions = Extensions, PreprocessorVariables = new Dictionary<string, string>() { { "Version", expectedVersion2 } }, NeverGetsInstalled = true }.Build().Output; string patchA = new PatchBuilder(this, "PatchA") { PreprocessorVariables = new Dictionary<string, string>() { { "Version", expectedVersion2 } }, TargetPath = packageA, UpgradePath = packageA1 }.Build().Output; // Create the named bind paths to the packages. Dictionary<string, string> bindPaths = new Dictionary<string, string>(); bindPaths.Add("packageA", packageA); bindPaths.Add("patchA", patchA); // Build the bundles. string bundleA = new BundleBuilder(this, "BundleA") { BindPaths = bindPaths, Extensions = Extensions }.Build().Output; string bundleC = new BundleBuilder(this, "BundleC") { BindPaths = bindPaths, Extensions = Extensions, PreprocessorVariables = new Dictionary<string, string>() { { "Version", expectedVersion2 } } }.Build().Output; // Install the base bundle and make sure it's installed. BundleInstaller installerA = new BundleInstaller(this, bundleA).Install(); Assert.IsTrue(MsiVerifier.IsPackageInstalled(packageA)); using (RegistryKey root = this.GetTestRegistryRoot()) { string actualVersion = root.GetValue("Version") as string; Assert.AreEqual(expectedVersion1, actualVersion); } // Install the upgrade bundle with a slipstreamed patch and make sure the patch is installed. // SFBUG:3387046 - Uninstalling bundle registers a dependency on a package BundleInstaller installerC = new BundleInstaller(this, bundleC).Install(); Assert.IsTrue(MsiUtils.IsPatchInstalled(patchA)); // BundleC doesn't carry the EXE, so make sure it's removed. using (RegistryKey root = this.GetTestRegistryRoot()) { Assert.IsNull(root.GetValue("Version")); } // Repair the upgrade bundle to make sure it does not prompt for source. // SFBUG:3386927 - MSIs get removed from cache during upgrade installerC.Repair(); // Uninstall the slipstream bundle and make sure both packages are uninstalled. installerC.Uninstall(); Assert.IsFalse(MsiUtils.IsPatchInstalled(patchA)); Assert.IsFalse(MsiVerifier.IsPackageInstalled(packageA)); this.CleanTestArtifacts = true; }
public void Burn_PatchOnePackageTwoPatches() { string originalVersion = "1.0.0.0"; string patchedVersion = "1.0.1.0"; // Build the packages. string packageA = new PackageBuilder(this, "A") { Extensions = WixTests.Extensions }.Build().Output; string packageAUpdate = new PackageBuilder(this, "A") { Extensions = WixTests.Extensions, PreprocessorVariables = new Dictionary <string, string>() { { "Version", patchedVersion } }, NeverGetsInstalled = true }.Build().Output; string patchA = new PatchBuilder(this, "PatchA") { Extensions = WixTests.Extensions, TargetPath = packageA, UpgradePath = packageAUpdate }.Build().Output; string patchA2 = new PatchBuilder(this, "PatchA2") { Extensions = WixTests.Extensions, TargetPath = packageA, UpgradePath = packageAUpdate }.Build().Output; // Create the named bind paths to the packages. Dictionary <string, string> bindPaths = new Dictionary <string, string>(); bindPaths.Add("patchA", patchA); bindPaths.Add("patchA2", patchA2); string bundlePatch = new BundleBuilder(this, "PatchBundleA2") { BindPaths = bindPaths, Extensions = Extensions }.Build().Output; // Install the original MSI and ensure the registry keys that get patched are as expected. MSIExec.InstallProduct(packageA, MSIExec.MSIExecReturnCode.SUCCESS); using (RegistryKey root = this.GetTestRegistryRoot()) { string actualVersion = root.GetValue("A") as string; Assert.AreEqual(originalVersion, actualVersion); actualVersion = root.GetValue("A2") as string; Assert.AreEqual(originalVersion, actualVersion); } // Install the bundle of patches and ensure all the registry keys are updated. BundleInstaller installPatches = new BundleInstaller(this, bundlePatch).Install(); using (RegistryKey root = this.GetTestRegistryRoot()) { string actualVersion = root.GetValue("A") as string; Assert.AreEqual(patchedVersion, actualVersion); actualVersion = root.GetValue("A2") as string; Assert.AreEqual(patchedVersion, actualVersion); } // Uninstall the patch bundle and verify the keys go back to original values. installPatches.Uninstall(); using (RegistryKey root = this.GetTestRegistryRoot()) { string actualVersion = root.GetValue("A") as string; Assert.AreEqual(originalVersion, actualVersion); actualVersion = root.GetValue("A2") as string; Assert.AreEqual(originalVersion, actualVersion); } this.CleanTestArtifacts = true; }
public virtual void AddPatches(PatchBuilder builder) { // do nothing }
public void Burn_InstallUninstallUpgradePatchRelatedBundleWithAddon() { const string patchVersion1 = "1.0.1.0"; const string patchVersion2 = "1.0.2.0"; // Build the packages. string packageA1 = new PackageBuilder(this, "A").Build().Output; string packageA2 = new PackageBuilder(this, "A") { PreprocessorVariables = new Dictionary<string, string>() { { "Version", patchVersion1 } }, NeverGetsInstalled = true }.Build().Output; string packageA3 = new PackageBuilder(this, "A") { PreprocessorVariables = new Dictionary<string, string>() { { "Version", patchVersion2 } }, NeverGetsInstalled = true }.Build().Output; string packageC = new PackageBuilder(this, "C").Build().Output; string packageD = new PackageBuilder(this, "D").Build().Output; string patchA1 = new PatchBuilder(this, "PatchA") { PreprocessorVariables = new Dictionary<string, string>() { { "Version", patchVersion1 } }, TargetPath = packageA1, UpgradePath = packageA2 }.Build().Output; string patchA2 = new PatchBuilder(this, "PatchA") { PreprocessorVariables = new Dictionary<string, string>() { { "Version", patchVersion2 } }, TargetPath = packageA1, UpgradePath = packageA3 }.Build().Output; // Create the named bind paths to the packages. Dictionary<string, string> bindPaths = new Dictionary<string, string>(); bindPaths.Add("packageA", packageA1); bindPaths.Add("packageC", packageC); bindPaths.Add("packageD", packageD); bindPaths.Add("patchA", patchA1); // Build the bundles. string bundleA = new BundleBuilder(this, "BundleA") { BindPaths = bindPaths, Extensions = Extensions }.Build().Output; string bundleC = new BundleBuilder(this, "BundleC") { BindPaths = bindPaths, Extensions = Extensions }.Build().Output; string bundleD1 = new BundleBuilder(this, "BundleD") { PreprocessorVariables = new Dictionary<string, string>() { { "Version", patchVersion1 } }, BindPaths = bindPaths, Extensions = Extensions }.Build().Output; // Build the v2 patch bundle. bindPaths["patchA"] = patchA2; string bundleD2 = new BundleBuilder(this, "BundleD") { PreprocessorVariables = new Dictionary<string, string>() { { "Version", patchVersion2 } }, BindPaths = bindPaths, Extensions = Extensions }.Build().Output; // Install the bundles. BundleInstaller installerA = new BundleInstaller(this, bundleA).Install(); BundleInstaller installerD1 = new BundleInstaller(this, bundleD1).Install(); // Test both packages are installed. Assert.IsTrue(MsiVerifier.IsPackageInstalled(packageA1)); using (RegistryKey root = this.GetTestRegistryRoot()) { string actualVersion = root.GetValue("A") as string; Assert.AreEqual(patchVersion1, actualVersion); } // Install the addon bundle. BundleInstaller installerC = new BundleInstaller(this, bundleC).Install(); // Test that package C but not D is installed. Assert.IsTrue(MsiVerifier.IsPackageInstalled(packageC)); Assert.IsFalse(MsiVerifier.IsPackageInstalled(packageD)); // Install the v2 patch bundles. BundleInstaller installerD2 = new BundleInstaller(this, bundleD2).Install(); // Test that all packages but D are installed. Assert.IsTrue(MsiVerifier.IsPackageInstalled(packageA1)); Assert.IsTrue(MsiVerifier.IsPackageInstalled(packageC)); Assert.IsFalse(MsiVerifier.IsPackageInstalled(packageD)); using (RegistryKey root = this.GetTestRegistryRoot()) { string actualVersion = root.GetValue("A") as string; Assert.AreEqual(patchVersion2, actualVersion); } // Test that installing D2 upgrades D1. Assert.IsTrue(LogVerifier.MessageInLogFileRegex(installerD2.LastLogFile, @"Detected related bundle: \{[0-9A-Za-z\-]{36}\}, type: Upgrade, scope: PerMachine, version: 1\.0\.1\.0, operation: MajorUpgrade")); // Attempt to uninstall bundleA. installerA.Uninstall(); // Test that uninstalling bundle A detected and would remove bundles C and D. Assert.IsTrue(LogVerifier.MessageInLogFileRegex(installerA.LastLogFile, @"Detected related bundle: \{[0-9A-Za-z\-]{36}\}, type: Addon, scope: PerMachine, version: 1\.0\.0\.0, operation: Remove")); Assert.IsTrue(LogVerifier.MessageInLogFileRegex(installerA.LastLogFile, @"Detected related bundle: \{[0-9A-Za-z\-]{36}\}, type: Patch, scope: PerMachine, version: 1\.0\.2\.0, operation: Remove")); // Test all packages are uninstalled. Assert.IsFalse(MsiVerifier.IsPackageInstalled(packageA1)); Assert.IsFalse(MsiVerifier.IsPackageInstalled(packageC)); Assert.IsFalse(MsiVerifier.IsPackageInstalled(packageD)); Assert.IsNull(this.GetTestRegistryRoot()); this.CleanTestArtifacts = true; }
public void Burn_InstallPatchBundle() { const string expectedVersion = "1.0.1.0"; // Build the packages. string packageA1 = new PackageBuilder(this, "A") { Extensions = Extensions }.Build().Output; string packageA2 = new PackageBuilder(this, "A") { Extensions = Extensions, PreprocessorVariables = new Dictionary<string, string>() { { "Version", expectedVersion } }, NeverGetsInstalled = true }.Build().Output; string packageB = new PackageBuilder(this, "B") { Extensions = Extensions }.Build().Output; string patchA = new PatchBuilder(this, "PatchA") { PreprocessorVariables = new Dictionary<string, string>() { { "Version", expectedVersion } }, TargetPath = packageA1, UpgradePath = packageA2 }.Build().Output; // Create the named bind paths to the packages. Dictionary<string, string> bindPaths = new Dictionary<string, string>(); bindPaths.Add("packageA", packageA1); bindPaths.Add("packageB", packageB); bindPaths.Add("patchA", patchA); // Build the bundles. string bundleF = new BundleBuilder(this, "BundleF") { BindPaths = bindPaths, Extensions = Extensions }.Build().Output; string bundleG = new BundleBuilder(this, "BundleG") { BindPaths = bindPaths, Extensions = Extensions }.Build().Output; // Install the base bundle and make sure all packages are installed. BundleInstaller installerF = new BundleInstaller(this, bundleF).Install(); Assert.IsTrue(MsiVerifier.IsPackageInstalled(packageA1)); Assert.IsTrue(MsiVerifier.IsPackageInstalled(packageB)); // Install patch bundle and make sure all packages are installed. BundleInstaller installerG = new BundleInstaller(this, bundleG).Install(); Assert.IsTrue(MsiVerifier.IsPackageInstalled(packageA1)); Assert.IsTrue(MsiVerifier.IsPackageInstalled(packageB)); Assert.IsTrue(MsiUtils.IsPatchInstalled(patchA)); // Uninstall the base bundle and make sure all packages are uninstalled. installerF.Uninstall(); Assert.IsFalse(MsiVerifier.IsPackageInstalled(packageA1)); Assert.IsFalse(MsiVerifier.IsPackageInstalled(packageB)); Assert.IsFalse(MsiUtils.IsPatchInstalled(patchA)); this.CleanTestArtifacts = true; }
public void Burn_InstallUninstallStickyPatchRelatedBundle() { const string patchVersion = "1.0.1.0"; // Build the packages. string packageA1 = new PackageBuilder(this, "A").Build().Output; string packageA2 = new PackageBuilder(this, "A") { PreprocessorVariables = new Dictionary <string, string>() { { "Version", patchVersion } }, NeverGetsInstalled = true }.Build().Output; string packageB1 = new PackageBuilder(this, "B").Build().Output; string packageB2 = new PackageBuilder(this, "B") { PreprocessorVariables = new Dictionary <string, string>() { { "Version", patchVersion } }, NeverGetsInstalled = true }.Build().Output; string patchA = new PatchBuilder(this, "PatchA") { PreprocessorVariables = new Dictionary <string, string>() { { "Version", patchVersion } }, TargetPaths = new string[] { packageA1, packageB1 }, UpgradePaths = new string[] { packageA2, packageB2 } }.Build().Output; // Create the named bind paths to the packages. Dictionary <string, string> bindPaths = new Dictionary <string, string>(); bindPaths.Add("packageA", packageA1); bindPaths.Add("packageB", packageB1); bindPaths.Add("patchA", patchA); // Build the bundles. string bundleA = new BundleBuilder(this, "BundleA") { BindPaths = bindPaths, Extensions = Extensions }.Build().Output; string bundleB = new BundleBuilder(this, "BundleB") { BindPaths = bindPaths, Extensions = Extensions }.Build().Output; string bundleD = new BundleBuilder(this, "BundleD") { PreprocessorVariables = new Dictionary <string, string>() { { "Version", patchVersion } }, BindPaths = bindPaths, Extensions = Extensions }.Build().Output; // Install the bundles. BundleInstaller installerA = new BundleInstaller(this, bundleA).Install(); BundleInstaller installerD = new BundleInstaller(this, bundleD).Install(); // Make sure that bundle D detected dependent bundle A. Assert.True(LogVerifier.MessageInLogFileRegex(installerD.LastLogFile, @"Detected related bundle: \{[0-9A-Za-z\-]{36}\}, type: Dependent, scope: PerMachine, version: 1\.0\.0\.0, operation: None")); // Test that packageA1 and patchA are installed. Assert.True(MsiVerifier.IsPackageInstalled(packageA1)); using (RegistryKey root = this.GetTestRegistryRoot()) { string actualVersion = root.GetValue("A") as string; Assert.Equal(patchVersion, actualVersion); } // Install bundle B (tests sticky patching). BundleInstaller installerB = new BundleInstaller(this, bundleB).Install(); Assert.True(LogVerifier.MessageInLogFileRegex(installerB.LastLogFile, @"Detected related bundle: \{[0-9A-Za-z\-]{36}\}, type: Patch, scope: PerMachine, version: 1\.0\.1\.0, operation: Install")); Assert.True(LogVerifier.MessageInLogFileRegex(installerB.LastLogFile, @"Detected related bundle: \{[0-9A-Za-z\-]{36}\}, type: Detect, scope: PerMachine, version: 1\.0\.0\.0, operation: None")); // Test that packageB and patchA are installed. Assert.True(MsiVerifier.IsPackageInstalled(packageB1)); using (RegistryKey root = this.GetTestRegistryRoot()) { string actualVersion = root.GetValue("B") as string; Assert.Equal(patchVersion, actualVersion); } // Attempt to uninstall bundleA. installerA.Uninstall(); // Test that packageA is still installed (ref-counted). Assert.True(MsiVerifier.IsPackageInstalled(packageA1)); // Test that uninstalling bundle A detected bundle D (ref-counted). Assert.True(LogVerifier.MessageInLogFileRegex(installerA.LastLogFile, @"Detected related bundle: \{[0-9A-Za-z\-]{36}\}, type: Patch, scope: PerMachine, version: 1\.0\.1\.0, operation: Remove")); Assert.True(LogVerifier.MessageInLogFileRegex(installerA.LastLogFile, @"Will not uninstall package: \{[0-9A-Za-z\-]{36}\}, found dependents: 1")); // Attempt to uninstall bundleB. installerB.Uninstall(); // Test that all packages are uninstalled. Assert.False(MsiVerifier.IsPackageInstalled(packageA1)); Assert.False(MsiVerifier.IsPackageInstalled(packageB1)); Assert.Null(this.GetTestRegistryRoot()); // Test that uninstalling bundle B detected and removed bundle D (ref-counted). Assert.True(LogVerifier.MessageInLogFileRegex(installerB.LastLogFile, @"Detected related bundle: \{[0-9A-Za-z\-]{36}\}, type: Patch, scope: PerMachine, version: 1\.0\.1\.0, operation: Remove")); this.Complete(); }
// Patch Creation private void btnCreatePatch_Click(object sender, RoutedEventArgs e) { try { // Check the user isn't completly retarded if (!CheckAllCreateMandatoryFields()) { return; } // Check the user isn't a skid if (!CheckAllCreateMetaFilesExists()) { return; } // Paths string cleanMapPath = txtCreatePatchUnModifiedMap.Text; string moddedMapPath = txtCreatePatchModifiedMap.Text; string outputPath = txtCreatePatchOutputPatch.Text; string previewImage = txtCreatePatchPreviewImage.Text; // Details string author = txtCreatePatchContentAuthor.Text; string desc = txtCreatePatchContentDescription.Text; string name = txtCreatePatchContentName.Text; string outputName = txtCreatePatchOutputName.Text; // Make dat patch var patch = new Patch { Author = author, Description = desc, Name = name, OutputName = outputName, Screenshot = String.IsNullOrEmpty(previewImage) ? null : File.ReadAllBytes(previewImage), BuildString = _buildInfo.Version, PC = String.IsNullOrEmpty(_buildInfo.GameExecutable) ? false : true }; EndianReader originalReader = null; EndianReader newReader = null; try { originalReader = new EndianReader(File.OpenRead(cleanMapPath), Endian.BigEndian); newReader = new EndianReader(File.OpenRead(moddedMapPath), Endian.BigEndian); ICacheFile originalFile = CacheFileLoader.LoadCacheFile(originalReader, cleanMapPath, App.AssemblyStorage.AssemblySettings.DefaultDatabase); ICacheFile newFile = CacheFileLoader.LoadCacheFile(newReader, moddedMapPath, App.AssemblyStorage.AssemblySettings.DefaultDatabase); if (cbCreatePatchHasCustomMeta.IsChecked != null && (bool)cbCreatePatchHasCustomMeta.IsChecked && cboxCreatePatchTargetGame.SelectedIndex < 4) { var targetGame = (TargetGame)cboxCreatePatchTargetGame.SelectedIndex; byte[] mapInfo = File.ReadAllBytes(txtCreatePatchMapInfo.Text); var mapInfoFileInfo = new FileInfo(txtCreatePatchMapInfo.Text); FileInfo blfFileInfo; patch.CustomBlfContent = new BlfContent(mapInfoFileInfo.FullName, mapInfo, targetGame); #region Blf Data if (PatchCreationBlfOption0.Visibility == Visibility.Visible) { blfFileInfo = new FileInfo(txtCreatePatchblf0.Text); patch.CustomBlfContent.BlfContainerEntries.Add(new BlfContainerEntry(blfFileInfo.Name, File.ReadAllBytes(blfFileInfo.FullName))); } if (PatchCreationBlfOption1.Visibility == Visibility.Visible) { blfFileInfo = new FileInfo(txtCreatePatchblf1.Text); patch.CustomBlfContent.BlfContainerEntries.Add(new BlfContainerEntry(blfFileInfo.Name, File.ReadAllBytes(blfFileInfo.FullName))); } if (PatchCreationBlfOption2.Visibility == Visibility.Visible) { blfFileInfo = new FileInfo(txtCreatePatchblf2.Text); patch.CustomBlfContent.BlfContainerEntries.Add(new BlfContainerEntry(blfFileInfo.Name, File.ReadAllBytes(blfFileInfo.FullName))); } if (PatchCreationBlfOption3.Visibility == Visibility.Visible) { blfFileInfo = new FileInfo(txtCreatePatchblf3.Text); patch.CustomBlfContent.BlfContainerEntries.Add(new BlfContainerEntry(blfFileInfo.Name, File.ReadAllBytes(blfFileInfo.FullName))); } #endregion } PatchBuilder.BuildPatch(originalFile, originalReader, newFile, newReader, patch); } finally { if (originalReader != null) { originalReader.Dispose(); } if (newReader != null) { newReader.Dispose(); } } IWriter output = new EndianWriter(File.Open(outputPath, FileMode.Create, FileAccess.Write), Endian.BigEndian); AssemblyPatchWriter.WritePatch(patch, output); output.Dispose(); MetroMessageBox.Show("Patch Created!", "Your patch has been created in the designated location. Happy sailing, modder!"); } catch (Exception ex) { MetroException.Show(ex); } }
public void Burn_InstallUninstallUpgradePatchRelatedBundleWithAddon() { const string patchVersion1 = "1.0.1.0"; const string patchVersion2 = "1.0.2.0"; // Build the packages. string packageA1 = new PackageBuilder(this, "A").Build().Output; string packageA2 = new PackageBuilder(this, "A") { PreprocessorVariables = new Dictionary <string, string>() { { "Version", patchVersion1 } }, NeverGetsInstalled = true }.Build().Output; string packageA3 = new PackageBuilder(this, "A") { PreprocessorVariables = new Dictionary <string, string>() { { "Version", patchVersion2 } }, NeverGetsInstalled = true }.Build().Output; string packageC = new PackageBuilder(this, "C").Build().Output; string packageD = new PackageBuilder(this, "D").Build().Output; string patchA1 = new PatchBuilder(this, "PatchA") { PreprocessorVariables = new Dictionary <string, string>() { { "Version", patchVersion1 } }, TargetPath = packageA1, UpgradePath = packageA2 }.Build().Output; string patchA2 = new PatchBuilder(this, "PatchA") { PreprocessorVariables = new Dictionary <string, string>() { { "Version", patchVersion2 } }, TargetPath = packageA1, UpgradePath = packageA3 }.Build().Output; // Create the named bind paths to the packages. Dictionary <string, string> bindPaths = new Dictionary <string, string>(); bindPaths.Add("packageA", packageA1); bindPaths.Add("packageC", packageC); bindPaths.Add("packageD", packageD); bindPaths.Add("patchA", patchA1); // Build the bundles. string bundleA = new BundleBuilder(this, "BundleA") { BindPaths = bindPaths, Extensions = Extensions }.Build().Output; string bundleC = new BundleBuilder(this, "BundleC") { BindPaths = bindPaths, Extensions = Extensions }.Build().Output; string bundleD1 = new BundleBuilder(this, "BundleD") { PreprocessorVariables = new Dictionary <string, string>() { { "Version", patchVersion1 } }, BindPaths = bindPaths, Extensions = Extensions }.Build().Output; // Build the v2 patch bundle. bindPaths["patchA"] = patchA2; string bundleD2 = new BundleBuilder(this, "BundleD") { PreprocessorVariables = new Dictionary <string, string>() { { "Version", patchVersion2 } }, BindPaths = bindPaths, Extensions = Extensions }.Build().Output; // Install the bundles. BundleInstaller installerA = new BundleInstaller(this, bundleA).Install(); BundleInstaller installerD1 = new BundleInstaller(this, bundleD1).Install(); // Test both packages are installed. Assert.True(MsiVerifier.IsPackageInstalled(packageA1)); using (RegistryKey root = this.GetTestRegistryRoot()) { string actualVersion = root.GetValue("A") as string; Assert.Equal(patchVersion1, actualVersion); } // Install the addon bundle. BundleInstaller installerC = new BundleInstaller(this, bundleC).Install(); // Test that package C but not D is installed. Assert.True(MsiVerifier.IsPackageInstalled(packageC)); Assert.False(MsiVerifier.IsPackageInstalled(packageD)); // Install the v2 patch bundles. BundleInstaller installerD2 = new BundleInstaller(this, bundleD2).Install(); // Test that all packages but D are installed. Assert.True(MsiVerifier.IsPackageInstalled(packageA1)); Assert.True(MsiVerifier.IsPackageInstalled(packageC)); Assert.False(MsiVerifier.IsPackageInstalled(packageD)); using (RegistryKey root = this.GetTestRegistryRoot()) { string actualVersion = root.GetValue("A") as string; Assert.Equal(patchVersion2, actualVersion); } // Test that installing D2 upgrades D1. Assert.True(LogVerifier.MessageInLogFileRegex(installerD2.LastLogFile, @"Detected related bundle: \{[0-9A-Za-z\-]{36}\}, type: Upgrade, scope: PerMachine, version: 1\.0\.1\.0, operation: MajorUpgrade")); // Attempt to uninstall bundleA. installerA.Uninstall(); // Test that uninstalling bundle A detected and would remove bundles C and D. Assert.True(LogVerifier.MessageInLogFileRegex(installerA.LastLogFile, @"Detected related bundle: \{[0-9A-Za-z\-]{36}\}, type: Addon, scope: PerMachine, version: 1\.0\.0\.0, operation: Remove")); Assert.True(LogVerifier.MessageInLogFileRegex(installerA.LastLogFile, @"Detected related bundle: \{[0-9A-Za-z\-]{36}\}, type: Patch, scope: PerMachine, version: 1\.0\.2\.0, operation: Remove")); // Test all packages are uninstalled. Assert.False(MsiVerifier.IsPackageInstalled(packageA1)); Assert.False(MsiVerifier.IsPackageInstalled(packageC)); Assert.False(MsiVerifier.IsPackageInstalled(packageD)); Assert.Null(this.GetTestRegistryRoot()); this.Complete(); }