From 18752ee7da742d0219e7b882315e03ad888f5725 Mon Sep 17 00:00:00 2001 From: Sean Hall Date: Mon, 6 Apr 2020 12:30:56 +1000 Subject: Modernize BalCompiler and BalBurnBackendExtension. --- src/test/WixToolsetTest.Bal/BalExtensionFixture.cs | 5 + src/wixext/BalBurnBackendExtension.cs | 71 ++++--- src/wixext/BalCompiler.cs | 203 +++++++++++---------- 3 files changed, 150 insertions(+), 129 deletions(-) diff --git a/src/test/WixToolsetTest.Bal/BalExtensionFixture.cs b/src/test/WixToolsetTest.Bal/BalExtensionFixture.cs index 06727afd..e798063e 100644 --- a/src/test/WixToolsetTest.Bal/BalExtensionFixture.cs +++ b/src/test/WixToolsetTest.Bal/BalExtensionFixture.cs @@ -3,6 +3,7 @@ namespace WixToolsetTest.Bal { using System.IO; + using System.Linq; using WixBuildTools.TestSupport; using WixToolset.Core.TestPackage; using Xunit; @@ -29,6 +30,10 @@ namespace WixToolsetTest.Bal "-o", bundleFile, }); compileResult.AssertSuccess(); + Assert.Equal(new[] + { + "BurnBackend didn't provide Wixout so skipping BalExtension PostBind verification." + }, compileResult.Messages.Select(x => x.ToString()).ToArray()); Assert.True(File.Exists(bundleFile)); } diff --git a/src/wixext/BalBurnBackendExtension.cs b/src/wixext/BalBurnBackendExtension.cs index 20609964..e1082889 100644 --- a/src/wixext/BalBurnBackendExtension.cs +++ b/src/wixext/BalBurnBackendExtension.cs @@ -4,10 +4,10 @@ namespace WixToolset.Bal { using System; using System.Linq; + using WixToolset.Bal.Tuples; using WixToolset.Data; using WixToolset.Data.Burn; - using WixToolset.Data.WindowsInstaller; - using WixToolset.Data.WindowsInstaller.Rows; + using WixToolset.Data.Tuples; using WixToolset.Extensibility; using WixToolset.Extensibility.Data; @@ -17,17 +17,17 @@ namespace WixToolset.Bal { base.PostBackendBind(result); - var output = WindowsInstallerData.Load(result.Wixout, false); - - // Only process Bundles. - if (OutputType.Bundle != output.Type) + if (result.Wixout == null) { + this.Messaging.Write(new Message(null, MessageLevel.Warning, 1, "BurnBackend didn't provide Wixout so skipping BalExtension PostBind verification.")); return; } - var baTable = output.Tables["WixBootstrapperApplication"]; - var baRow = baTable.Rows[0]; - var baId = (string)baRow[0]; + var intermediate = Intermediate.Load(result.Wixout); + var section = intermediate.Sections.Single(); + + var baTuple = section.Tuples.OfType().SingleOrDefault(); + var baId = baTuple?.Id?.Id; if (null == baId) { return; @@ -38,60 +38,57 @@ namespace WixToolset.Bal if (isStdBA || isMBA) { - this.VerifyBAFunctions(output); + this.VerifyBAFunctions(section); } if (isMBA) { - this.VerifyPrereqPackages(output); + this.VerifyPrereqPackages(section); } } - private void VerifyBAFunctions(WindowsInstallerData output) + private void VerifyBAFunctions(IntermediateSection section) { - Row baFunctionsRow = null; - var baFunctionsTable = output.Tables["WixBalBAFunctions"]; - foreach (var row in baFunctionsTable.Rows) + WixBalBAFunctionsTuple baFunctionsTuple = null; + foreach (var tuple in section.Tuples.OfType()) { - if (null == baFunctionsRow) + if (null == baFunctionsTuple) { - baFunctionsRow = row; + baFunctionsTuple = tuple; } else { - this.Messaging.Write(BalErrors.MultipleBAFunctions(row.SourceLineNumbers)); + this.Messaging.Write(BalErrors.MultipleBAFunctions(tuple.SourceLineNumbers)); } } - var payloadPropertiesTable = output.Tables["WixPayloadProperties"]; - var payloadPropertiesRows = payloadPropertiesTable.Rows.Cast(); - if (null == baFunctionsRow) + var payloadPropertiesTuples = section.Tuples.OfType().ToList(); + if (null == baFunctionsTuple) { - foreach (var payloadPropertiesRow in payloadPropertiesRows) + foreach (var payloadPropertiesTuple in payloadPropertiesTuples) { // TODO: Make core WiX canonicalize Name (this won't catch '.\bafunctions.dll'). - if (string.Equals(payloadPropertiesRow.Name, "bafunctions.dll", StringComparison.OrdinalIgnoreCase)) + if (string.Equals(payloadPropertiesTuple.Name, "bafunctions.dll", StringComparison.OrdinalIgnoreCase)) { - this.Messaging.Write(BalWarnings.UnmarkedBAFunctionsDLL(payloadPropertiesRow.SourceLineNumbers)); + this.Messaging.Write(BalWarnings.UnmarkedBAFunctionsDLL(payloadPropertiesTuple.SourceLineNumbers)); } } } else { - // TODO: May need to revisit this depending on the outcome of #5273. - var payloadId = (string)baFunctionsRow[0]; - var bundlePayloadRow = payloadPropertiesRows.Single(x => payloadId == x.Id); - if (BurnConstants.BurnUXContainerName != bundlePayloadRow.Container) + var payloadId = baFunctionsTuple.Id; + var bundlePayloadTuple = payloadPropertiesTuples.Single(x => payloadId == x.Id); + if (BurnConstants.BurnUXContainerName != bundlePayloadTuple.ContainerRef) { - this.Messaging.Write(BalErrors.BAFunctionsPayloadRequiredInUXContainer(baFunctionsRow.SourceLineNumbers)); + this.Messaging.Write(BalErrors.BAFunctionsPayloadRequiredInUXContainer(baFunctionsTuple.SourceLineNumbers)); } } } - private void VerifyPrereqPackages(WindowsInstallerData output) + private void VerifyPrereqPackages(IntermediateSection section) { - var prereqInfoTable = output.Tables["WixMbaPrereqInformation"]; - if (null == prereqInfoTable || prereqInfoTable.Rows.Count == 0) + var prereqInfoTuples = section.Tuples.OfType().ToList(); + if (prereqInfoTuples.Count == 0) { this.Messaging.Write(BalErrors.MissingPrereq()); return; @@ -100,24 +97,24 @@ namespace WixToolset.Bal var foundLicenseFile = false; var foundLicenseUrl = false; - foreach (Row prereqInfoRow in prereqInfoTable.Rows) + foreach (var prereqInfoTuple in prereqInfoTuples) { - if (null != prereqInfoRow[1]) + if (null != prereqInfoTuple.LicenseFile) { if (foundLicenseFile || foundLicenseUrl) { - this.Messaging.Write(BalErrors.MultiplePrereqLicenses(prereqInfoRow.SourceLineNumbers)); + this.Messaging.Write(BalErrors.MultiplePrereqLicenses(prereqInfoTuple.SourceLineNumbers)); return; } foundLicenseFile = true; } - if (null != prereqInfoRow[2]) + if (null != prereqInfoTuple.LicenseUrl) { if (foundLicenseFile || foundLicenseUrl) { - this.Messaging.Write(BalErrors.MultiplePrereqLicenses(prereqInfoRow.SourceLineNumbers)); + this.Messaging.Write(BalErrors.MultiplePrereqLicenses(prereqInfoTuple.SourceLineNumbers)); return; } diff --git a/src/wixext/BalCompiler.cs b/src/wixext/BalCompiler.cs index c9b232ba..c291d41f 100644 --- a/src/wixext/BalCompiler.cs +++ b/src/wixext/BalCompiler.cs @@ -15,16 +15,14 @@ namespace WixToolset.Bal /// public sealed class BalCompiler : BaseCompilerExtension { - private SourceLineNumber addedConditionLineNumber; - private Dictionary prereqInfoRows; + private readonly Dictionary prereqInfoTuplesByPackageId; /// /// Instantiate a new BalCompiler. /// public BalCompiler() { - this.addedConditionLineNumber = null; - this.prereqInfoRows = new Dictionary(); + this.prereqInfoTuplesByPackageId = new Dictionary(); } public override XNamespace Namespace => "http://wixtoolset.org/schemas/v4/wxs/bal"; @@ -82,7 +80,7 @@ namespace WixToolset.Bal /// Extra information about the context in which this element is being parsed. public override void ParseAttribute(Intermediate intermediate, IntermediateSection section, XElement parentElement, XAttribute attribute, IDictionary context) { - SourceLineNumber sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(parentElement); + var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(parentElement); WixMbaPrereqInformationTuple prereqInfo; switch (parentElement.Name.LocalName) @@ -102,18 +100,20 @@ namespace WixToolset.Bal { case "PrereqLicenseFile": - if (!this.prereqInfoRows.TryGetValue(packageId, out prereqInfo)) + if (!this.prereqInfoTuplesByPackageId.TryGetValue(packageId, out prereqInfo)) { // at the time the extension attribute is parsed, the compiler might not yet have // parsed the PrereqPackage attribute, so we need to get it directly from the parent element. - XAttribute prereqPackage = parentElement.Attribute(this.Namespace + "PrereqPackage"); + var prereqPackage = parentElement.Attribute(this.Namespace + "PrereqPackage"); if (null != prereqPackage && YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, prereqPackage)) { - prereqInfo = (WixMbaPrereqInformationTuple)this.ParseHelper.CreateTuple(section, sourceLineNumbers, "WixMbaPrereqInformation"); - prereqInfo.PackageId = packageId; + prereqInfo = section.AddTuple(new WixMbaPrereqInformationTuple(sourceLineNumbers) + { + PackageId = packageId, + }); - this.prereqInfoRows.Add(packageId, prereqInfo); + this.prereqInfoTuplesByPackageId.Add(packageId, prereqInfo); } else { @@ -133,18 +133,20 @@ namespace WixToolset.Bal break; case "PrereqLicenseUrl": - if (!this.prereqInfoRows.TryGetValue(packageId, out prereqInfo)) + if (!this.prereqInfoTuplesByPackageId.TryGetValue(packageId, out prereqInfo)) { // at the time the extension attribute is parsed, the compiler might not yet have // parsed the PrereqPackage attribute, so we need to get it directly from the parent element. - XAttribute prereqPackage = parentElement.Attribute(this.Namespace + "PrereqPackage"); + var prereqPackage = parentElement.Attribute(this.Namespace + "PrereqPackage"); if (null != prereqPackage && YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, prereqPackage)) { - prereqInfo = (WixMbaPrereqInformationTuple)this.ParseHelper.CreateTuple(section, sourceLineNumbers, "WixMbaPrereqInformation"); - prereqInfo.PackageId = packageId; + prereqInfo = section.AddTuple(new WixMbaPrereqInformationTuple(sourceLineNumbers) + { + PackageId = packageId, + }); - this.prereqInfoRows.Add(packageId, prereqInfo); + this.prereqInfoTuplesByPackageId.Add(packageId, prereqInfo); } else { @@ -165,12 +167,14 @@ namespace WixToolset.Bal case "PrereqPackage": if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attribute)) { - if (!this.prereqInfoRows.TryGetValue(packageId, out prereqInfo)) + if (!this.prereqInfoTuplesByPackageId.TryGetValue(packageId, out prereqInfo)) { - prereqInfo = (WixMbaPrereqInformationTuple)this.ParseHelper.CreateTuple(section, sourceLineNumbers, "WixMbaPrereqInformation"); - prereqInfo.PackageId = packageId; + prereqInfo = section.AddTuple(new WixMbaPrereqInformationTuple(sourceLineNumbers) + { + PackageId = packageId, + }); - this.prereqInfoRows.Add(packageId, prereqInfo); + this.prereqInfoTuplesByPackageId.Add(packageId, prereqInfo); } } break; @@ -193,8 +197,10 @@ namespace WixToolset.Bal case "BAFunctions": if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attribute)) { - var tuple = (WixBalBAFunctionsTuple)this.ParseHelper.CreateTuple(section, sourceLineNumbers, "WixBalBAFunctions"); - tuple.PayloadId = payloadId; + section.AddTuple(new WixBalBAFunctionsTuple(sourceLineNumbers) + { + PayloadId = payloadId, + }); } break; default: @@ -206,7 +212,7 @@ namespace WixToolset.Bal case "Variable": // at the time the extension attribute is parsed, the compiler might not yet have // parsed the Name attribute, so we need to get it directly from the parent element. - XAttribute variableName = parentElement.Attribute("Name"); + var variableName = parentElement.Attribute("Name"); if (null == variableName) { this.Messaging.Write(ErrorMessages.ExpectedParentWithAttribute(sourceLineNumbers, "Variable", "Overridable", "Name")); @@ -218,8 +224,10 @@ namespace WixToolset.Bal case "Overridable": if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attribute)) { - var tuple = (WixStdbaOverridableVariableTuple)this.ParseHelper.CreateTuple(section, sourceLineNumbers, "WixStdbaOverridableVariable"); - tuple.Name = variableName.Value; + section.AddTuple(new WixStdbaOverridableVariableTuple(sourceLineNumbers) + { + Name = variableName.Value, + }); } break; default: @@ -237,11 +245,11 @@ namespace WixToolset.Bal /// The element to parse. private void ParseConditionElement(Intermediate intermediate, IntermediateSection section, XElement node) { - SourceLineNumber sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node); - string condition = this.ParseHelper.GetConditionInnerText(node); // condition is the inner text of the element. + var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node); + var condition = this.ParseHelper.GetConditionInnerText(node); // condition is the inner text of the element. string message = null; - foreach (XAttribute attrib in node.Attributes()) + foreach (var attrib in node.Attributes()) { if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace) { @@ -276,14 +284,11 @@ namespace WixToolset.Bal if (!this.Messaging.EncounteredError) { - var tuple = (WixBalConditionTuple)this.ParseHelper.CreateTuple(section, sourceLineNumbers, "WixBalCondition"); - tuple.Condition = condition; - tuple.Message = message; - - if (null == this.addedConditionLineNumber) + section.AddTuple(new WixBalConditionTuple(sourceLineNumbers) { - this.addedConditionLineNumber = sourceLineNumbers; - } + Condition = condition, + Message = message, + }); } } @@ -293,11 +298,11 @@ namespace WixToolset.Bal /// The element to parse. private void ParseWixStandardBootstrapperApplicationElement(Intermediate intermediate, IntermediateSection section, XElement node) { - SourceLineNumber sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node); + var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node); string launchTarget = null; string launchTargetElevatedId = null; string launchArguments = null; - YesNoType launchHidden = YesNoType.NotSet; + var launchHidden = YesNoType.NotSet; string launchWorkingDir = null; string licenseFile = null; string licenseUrl = null; @@ -305,13 +310,13 @@ namespace WixToolset.Bal string logoSideFile = null; string themeFile = null; string localizationFile = null; - YesNoType suppressOptionsUI = YesNoType.NotSet; - YesNoType suppressDowngradeFailure = YesNoType.NotSet; - YesNoType suppressRepair = YesNoType.NotSet; - YesNoType showVersion = YesNoType.NotSet; - YesNoType supportCacheOnly = YesNoType.NotSet; + var suppressOptionsUI = YesNoType.NotSet; + var suppressDowngradeFailure = YesNoType.NotSet; + var suppressRepair = YesNoType.NotSet; + var showVersion = YesNoType.NotSet; + var supportCacheOnly = YesNoType.NotSet; - foreach (XAttribute attrib in node.Attributes()) + foreach (var attrib in node.Attributes()) { if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace) { @@ -387,90 +392,101 @@ namespace WixToolset.Bal { if (!String.IsNullOrEmpty(launchTarget)) { - var row = (WixBundleVariableTuple)this.ParseHelper.CreateTuple(section, sourceLineNumbers, "WixBundleVariable"); - row.Id = new Identifier(AccessModifier.Public, "LaunchTarget"); - row.Value = launchTarget; - row.Type = "string"; + section.AddTuple(new WixBundleVariableTuple(sourceLineNumbers, new Identifier(AccessModifier.Public, "LaunchTarget")) + { + Value = launchTarget, + Type = "string", + }); } if (!String.IsNullOrEmpty(launchTargetElevatedId)) { - var row = (WixBundleVariableTuple)this.ParseHelper.CreateTuple(section, sourceLineNumbers, "WixBundleVariable"); - row.Id = new Identifier(AccessModifier.Public, "LaunchTargetElevatedId"); - row.Value = launchTargetElevatedId; - row.Type = "string"; + section.AddTuple(new WixBundleVariableTuple(sourceLineNumbers, new Identifier(AccessModifier.Public, "LaunchTargetElevatedId")) + { + Value = launchTargetElevatedId, + Type = "string", + }); } if (!String.IsNullOrEmpty(launchArguments)) { - var row = (WixBundleVariableTuple)this.ParseHelper.CreateTuple(section, sourceLineNumbers, "WixBundleVariable"); - row.Id = new Identifier(AccessModifier.Public, "LaunchArguments"); - row.Value = launchArguments; - row.Type = "string"; + section.AddTuple(new WixBundleVariableTuple(sourceLineNumbers, new Identifier(AccessModifier.Public, "LaunchArguments")) + { + Value = launchArguments, + Type = "string", + }); } if (YesNoType.Yes == launchHidden) { - var row = (WixBundleVariableTuple)this.ParseHelper.CreateTuple(section, sourceLineNumbers, "WixBundleVariable"); - row.Id = new Identifier(AccessModifier.Public, "LaunchHidden"); - row.Value = "yes"; - row.Type = "string"; + section.AddTuple(new WixBundleVariableTuple(sourceLineNumbers, new Identifier(AccessModifier.Public, "LaunchHidden")) + { + Value = "yes", + Type = "string", + }); } if (!String.IsNullOrEmpty(launchWorkingDir)) { - var row = (WixBundleVariableTuple)this.ParseHelper.CreateTuple(section, sourceLineNumbers, "Variable"); - row.Id = new Identifier(AccessModifier.Public, "LaunchWorkingFolder"); - row.Value = launchWorkingDir; - row.Type = "string"; + section.AddTuple(new WixBundleVariableTuple(sourceLineNumbers, new Identifier(AccessModifier.Public, "LaunchWorkingFolder")) + { + Value = launchWorkingDir, + Type = "string", + }); } if (!String.IsNullOrEmpty(licenseFile)) { - var wixVariableRow = (WixVariableTuple)this.ParseHelper.CreateTuple(section, sourceLineNumbers, "WixVariable"); - wixVariableRow.Id = new Identifier(AccessModifier.Public, "WixStdbaLicenseRtf"); - wixVariableRow.Value = licenseFile; + section.AddTuple(new WixVariableTuple(sourceLineNumbers, new Identifier(AccessModifier.Public, "WixStdbaLicenseRtf")) + { + Value = licenseFile, + }); } if (null != licenseUrl) { - var wixVariableRow = (WixVariableTuple)this.ParseHelper.CreateTuple(section, sourceLineNumbers, "WixVariable"); - wixVariableRow.Id = new Identifier(AccessModifier.Public, "WixStdbaLicenseUrl"); - wixVariableRow.Value = licenseUrl; + section.AddTuple(new WixVariableTuple(sourceLineNumbers, new Identifier(AccessModifier.Public, "WixStdbaLicenseUrl")) + { + Value = licenseUrl, + }); } if (!String.IsNullOrEmpty(logoFile)) { - var wixVariableRow = (WixVariableTuple)this.ParseHelper.CreateTuple(section, sourceLineNumbers, "WixVariable"); - wixVariableRow.Id = new Identifier(AccessModifier.Public, "WixStdbaLogo"); - wixVariableRow.Value = logoFile; + section.AddTuple(new WixVariableTuple(sourceLineNumbers, new Identifier(AccessModifier.Public, "WixStdbaLogo")) + { + Value = logoFile, + }); } if (!String.IsNullOrEmpty(logoSideFile)) { - var wixVariableRow = (WixVariableTuple)this.ParseHelper.CreateTuple(section, sourceLineNumbers, "WixVariable"); - wixVariableRow.Id = new Identifier(AccessModifier.Public, "WixStdbaLogoSide"); - wixVariableRow.Value = logoSideFile; + section.AddTuple(new WixVariableTuple(sourceLineNumbers, new Identifier(AccessModifier.Public, "WixStdbaLogoSide")) + { + Value = logoSideFile, + }); } if (!String.IsNullOrEmpty(themeFile)) { - var wixVariableRow = (WixVariableTuple)this.ParseHelper.CreateTuple(section, sourceLineNumbers, "WixVariable"); - wixVariableRow.Id = new Identifier(AccessModifier.Public, "WixStdbaThemeXml"); - wixVariableRow.Value = themeFile; + section.AddTuple(new WixVariableTuple(sourceLineNumbers, new Identifier(AccessModifier.Public, "WixStdbaThemeXml")) + { + Value = themeFile, + }); } if (!String.IsNullOrEmpty(localizationFile)) { - var wixVariableRow = (WixVariableTuple)this.ParseHelper.CreateTuple(section, sourceLineNumbers, "WixVariable"); - wixVariableRow.Id = new Identifier(AccessModifier.Public, "WixStdbaThemeWxl"); - wixVariableRow.Value = localizationFile; + section.AddTuple(new WixVariableTuple(sourceLineNumbers, new Identifier(AccessModifier.Public, "WixStdbaThemeWxl")) + { + Value = localizationFile, + }); } if (YesNoType.Yes == suppressOptionsUI || YesNoType.Yes == suppressDowngradeFailure || YesNoType.Yes == suppressRepair || YesNoType.Yes == showVersion || YesNoType.Yes == supportCacheOnly) { - var tuple = (WixStdbaOptionsTuple)this.ParseHelper.CreateTuple(section, sourceLineNumbers, "WixStdbaOptions"); + var tuple = section.AddTuple(new WixStdbaOptionsTuple(sourceLineNumbers)); if (YesNoType.Yes == suppressOptionsUI) { tuple.SuppressOptionsUI = 1; @@ -505,12 +521,12 @@ namespace WixToolset.Bal /// The element to parse. private void ParseWixManagedBootstrapperApplicationHostElement(Intermediate intermediate, IntermediateSection section, XElement node) { - SourceLineNumber sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node); + var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node); string logoFile = null; string themeFile = null; string localizationFile = null; - foreach (XAttribute attrib in node.Attributes()) + foreach (var attrib in node.Attributes()) { if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace) { @@ -542,23 +558,26 @@ namespace WixToolset.Bal { if (!String.IsNullOrEmpty(logoFile)) { - var wixVariableRow = (WixVariableTuple)this.ParseHelper.CreateTuple(section, sourceLineNumbers, "WixVariable"); - wixVariableRow.Id = new Identifier(AccessModifier.Public, "PreqbaLogo"); - wixVariableRow.Value = logoFile; + section.AddTuple(new WixVariableTuple(sourceLineNumbers, new Identifier(AccessModifier.Public, "PreqbaLogo")) + { + Value = logoFile, + }); } if (!String.IsNullOrEmpty(themeFile)) { - var wixVariableRow = (WixVariableTuple)this.ParseHelper.CreateTuple(section, sourceLineNumbers, "WixVariable"); - wixVariableRow.Id = new Identifier(AccessModifier.Public, "PreqbaThemeXml"); - wixVariableRow.Value = themeFile; + section.AddTuple(new WixVariableTuple(sourceLineNumbers, new Identifier(AccessModifier.Public, "PreqbaThemeXml")) + { + Value = themeFile, + }); } if (!String.IsNullOrEmpty(localizationFile)) { - var wixVariableRow = (WixVariableTuple)this.ParseHelper.CreateTuple(section, sourceLineNumbers, "WixVariable"); - wixVariableRow.Id = new Identifier(AccessModifier.Public, "PreqbaThemeWxl"); - wixVariableRow.Value = localizationFile; + section.AddTuple(new WixVariableTuple(sourceLineNumbers, new Identifier(AccessModifier.Public, "PreqbaThemeWxl")) + { + Value = localizationFile, + }); } } } -- cgit v1.2.3-55-g6feb