public void CreateProtectedDirectoryFromInlineSyntax() { XDocument doc = XDocument.Parse("<Wix xmlns='http://wixtoolset.org/schemas/v4/wxs'><Product Id='*' Language='1033' Manufacturer='WixTests' Name='CreateProtectedDirectoryFromInlineSyntax' Version='1.0.0' UpgradeCode='12345678-1234-1234-1234-1234567890AB'><DirectoryRef Id='BinFolder'/></Product>" + @"<Fragment><Directory Id='protected BinFolder' Name='TARGETDIR:\foo\bar\bin\' /></Fragment>" + "<Fragment><Directory Id='TARGETDIR' Name='SourceDir' /></Fragment></Wix>"); XDocument src = new Preprocessor().Process(doc.CreateReader(), new Dictionary <string, string>()); Compiler compiler = new Compiler(); Linker linker = new Linker(); Intermediate intermediate = compiler.Compile(src); Output output = linker.Link(intermediate.Sections, OutputType.Product); RowIndexedList <Row> directoryRows = new RowIndexedList <Row>(output.Sections.SelectMany(sec => sec.Tables).Where(t => t.Name.Equals("Directory")).SelectMany(d => d.Rows)); Assert.Equal(4, directoryRows.Count); Row binFolder = directoryRows.Get("BinFolder"); Row barFolder = directoryRows.Get((string)binFolder[1]); Row fooFolder = directoryRows.Get((string)barFolder[1]); Row targetDir = directoryRows.Get((string)fooFolder[1]); Assert.Equal(AccessModifier.Protected, binFolder.Access); Assert.Equal(AccessModifier.Private, barFolder.Access); Assert.Equal(AccessModifier.Private, fooFolder.Access); Assert.Equal(AccessModifier.Public, targetDir.Access); Assert.Equal("bin", binFolder[2]); Assert.Equal("bar", barFolder[2]); Assert.Equal("foo", fooFolder[2]); Assert.Equal("SourceDir", targetDir[2]); }
public void InlineDirectorySyntaxCollapses() { XDocument doc = XDocument.Parse("<Wix xmlns='http://wixtoolset.org/schemas/v4/wxs'><Product Id='*' Language='1033' Manufacturer='WixTests' Name='InlineDirectorySyntaxCollapses' Version='1.0.0' UpgradeCode='12345678-1234-1234-1234-1234567890AB'><DirectoryRef Id='Bin1Folder'/><DirectoryRef Id='Bin2Folder'/></Product>" + @"<Fragment><Directory Id='protected Bin1Folder' Name='TARGETDIR:\foo\bar\bin1\' /></Fragment>" + @"<Fragment><Directory Id='internal Bin2Folder' Name='TARGETDIR:\foo\bar\bin2\' /></Fragment>" + "<Fragment><Directory Id='TARGETDIR' Name='SourceDir' /></Fragment></Wix>"); XDocument src = new Preprocessor().Process(doc.CreateReader(), new Dictionary <string, string>()); Compiler compiler = new Compiler(); Linker linker = new Linker(); Intermediate intermediate = compiler.Compile(src); Output output = linker.Link(intermediate.Sections, OutputType.Product); RowIndexedList <Row> directoryRows = new RowIndexedList <Row>(output.Sections.SelectMany(sec => sec.Tables).Where(t => t.Name.Equals("Directory")).SelectMany(d => d.Rows)); Assert.Equal(7, directoryRows.Count); Row bin1Folder = directoryRows.Get("Bin1Folder"); Row bar1Folder = directoryRows.Get((string)bin1Folder[1]); Row foo1Folder = directoryRows.Get((string)bar1Folder[1]); Row targetDir = directoryRows.Get((string)foo1Folder[1]); Row bin2Folder = directoryRows.Get("Bin2Folder"); Row bar2Folder = directoryRows.Get((string)bin2Folder[1]); Row foo2Folder = directoryRows.Get((string)bar2Folder[1]); Assert.Equal(AccessModifier.Protected, bin1Folder.Access); Assert.Equal(AccessModifier.Private, bar1Folder.Access); Assert.Equal(AccessModifier.Private, foo1Folder.Access); Assert.Equal(AccessModifier.Public, targetDir.Access); Assert.Equal(AccessModifier.Internal, bin2Folder.Access); Assert.Equal(AccessModifier.Private, bar2Folder.Access); Assert.Equal(AccessModifier.Private, foo2Folder.Access); Assert.Equal(targetDir, directoryRows.Get((string)foo2Folder[1])); // Primary keys should be the same for the inline directories. Assert.Equal(bar1Folder[0], bar2Folder[0]); Assert.Equal(foo1Folder[0], foo2Folder[0]); // One and only one of the same inline directories should be marked redundant. foreach (Row duplicate in directoryRows.Duplicates) { Row nonDupe = directoryRows.Get((string)duplicate[0]); Assert.True(nonDupe.Redundant ^ duplicate.Redundant); Assert.True(nonDupe.IsIdentical(duplicate)); } }
public void ComponentUsesInlineDirectorySyntax() { XDocument doc = XDocument.Parse("<Wix xmlns='http://wixtoolset.org/schemas/v4/wxs'><Product Id='*' Language='1033' Manufacturer='WixTests' Name='ComponentUsesInlineDirectorySyntax' Version='1.0.0' UpgradeCode='12345678-1234-1234-1234-1234567890AB'><Feature Id='Feature1'><ComponentRef Id='Component1'/></Feature></Product>" + @"<Fragment><Component Id='protected Component1' Directory='BinFolder:\comp\' /></Fragment>" + @"<Fragment><Directory Id='protected BinFolder' Name='TARGETDIR:\foo\bar\bin\' /></Fragment>" + "<Fragment><Directory Id='TARGETDIR' Name='SourceDir' /></Fragment></Wix>"); XDocument src = new Preprocessor().Process(doc.CreateReader(), new Dictionary <string, string>()); Compiler compiler = new Compiler(); Linker linker = new Linker(); Intermediate intermediate = compiler.Compile(src); Output output = linker.Link(intermediate.Sections, OutputType.Product); RowIndexedList <Row> directoryRows = new RowIndexedList <Row>(output.Sections.SelectMany(sec => sec.Tables).Where(t => t.Name.Equals("Directory")).SelectMany(d => d.Rows)); ComponentRow componentRow = output.Sections.SelectMany(sec => sec.Tables).Where(t => t.Name.Equals("Component")).SelectMany(c => c.Rows).Cast <ComponentRow>().Single(); Row compFolder = directoryRows.Get(componentRow.Directory); Assert.NotNull(compFolder); Assert.Equal(AccessModifier.Private, compFolder.Access); Assert.Equal("BinFolder", compFolder[1]); Assert.Equal("comp", compFolder[2]); }
public void Execute() { using (XmlTextWriter writer = new XmlTextWriter(this.OutputPath, Encoding.UTF8)) { writer.WriteStartDocument(); writer.WriteStartElement("BurnManifest", BurnCommon.BurnNamespace); // Write the condition, if there is one if (null != this.BundleInfo.Condition) { writer.WriteElementString("Condition", this.BundleInfo.Condition); } // Write the log element if default logging wasn't disabled. if (!String.IsNullOrEmpty(this.BundleInfo.LogPrefix)) { writer.WriteStartElement("Log"); if (!String.IsNullOrEmpty(this.BundleInfo.LogPathVariable)) { writer.WriteAttributeString("PathVariable", this.BundleInfo.LogPathVariable); } writer.WriteAttributeString("Prefix", this.BundleInfo.LogPrefix); writer.WriteAttributeString("Extension", this.BundleInfo.LogExtension); writer.WriteEndElement(); } // Get update if specified. WixBundleUpdateRow updateRow = this.Output.Tables["WixBundleUpdate"].RowsAs <WixBundleUpdateRow>().FirstOrDefault(); if (null != updateRow) { writer.WriteStartElement("Update"); writer.WriteAttributeString("Location", updateRow.Location); writer.WriteEndElement(); // </Update> } // Write the RelatedBundle elements // For the related bundles with duplicated identifiers the second instance is ignored (i.e. the Duplicates // enumeration in the index row list is not used). RowIndexedList <WixRelatedBundleRow> relatedBundles = new RowIndexedList <WixRelatedBundleRow>(this.Output.Tables["WixRelatedBundle"]); foreach (WixRelatedBundleRow relatedBundle in relatedBundles) { writer.WriteStartElement("RelatedBundle"); writer.WriteAttributeString("Id", relatedBundle.Id); writer.WriteAttributeString("Action", Convert.ToString(relatedBundle.Action, CultureInfo.InvariantCulture)); writer.WriteEndElement(); } // Write the variables IEnumerable <WixBundleVariableRow> variables = this.Output.Tables["WixBundleVariable"].RowsAs <WixBundleVariableRow>(); foreach (WixBundleVariableRow variable in variables) { writer.WriteStartElement("Variable"); writer.WriteAttributeString("Id", variable.Id); if (null != variable.Type) { writer.WriteAttributeString("Value", variable.Value); writer.WriteAttributeString("Type", variable.Type); } writer.WriteAttributeString("Hidden", variable.Hidden ? "yes" : "no"); writer.WriteAttributeString("Persisted", variable.Persisted ? "yes" : "no"); writer.WriteEndElement(); } // Write the searches foreach (WixSearchInfo searchinfo in this.OrderedSearches) { searchinfo.WriteXml(writer); } // write the UX element writer.WriteStartElement("UX"); if (!String.IsNullOrEmpty(this.BundleInfo.SplashScreenBitmapPath)) { writer.WriteAttributeString("SplashScreen", "yes"); } // write the UX allPayloads... foreach (WixBundlePayloadRow payload in this.UXContainerPayloads) { writer.WriteStartElement("Payload"); this.WriteBurnManifestPayloadAttributes(writer, payload, true, this.Payloads); writer.WriteEndElement(); } writer.WriteEndElement(); // </UX> // write the catalog elements if (this.Catalogs.Any()) { foreach (WixBundleCatalogRow catalog in this.Catalogs) { writer.WriteStartElement("Catalog"); writer.WriteAttributeString("Id", catalog.Id); writer.WriteAttributeString("Payload", catalog.Payload); writer.WriteEndElement(); } } foreach (WixBundleContainerRow container in this.Containers.Values) { if (!String.IsNullOrEmpty(container.WorkingPath) && Compiler.BurnUXContainerId != container.Id) { writer.WriteStartElement("Container"); this.WriteBurnManifestContainerAttributes(writer, this.ExecutableName, container); writer.WriteEndElement(); } } foreach (WixBundlePayloadRow payload in this.Payloads.Values) { if (PackagingType.Embedded == payload.Packaging && Compiler.BurnUXContainerId != payload.Container) { writer.WriteStartElement("Payload"); this.WriteBurnManifestPayloadAttributes(writer, payload, true, this.Payloads); writer.WriteEndElement(); } else if (PackagingType.External == payload.Packaging) { writer.WriteStartElement("Payload"); this.WriteBurnManifestPayloadAttributes(writer, payload, false, this.Payloads); writer.WriteEndElement(); } } foreach (WixBundleRollbackBoundaryRow rollbackBoundary in this.RollbackBoundaries) { writer.WriteStartElement("RollbackBoundary"); writer.WriteAttributeString("Id", rollbackBoundary.ChainPackageId); writer.WriteAttributeString("Vital", YesNoType.Yes == rollbackBoundary.Vital ? "yes" : "no"); writer.WriteAttributeString("Transaction", YesNoType.Yes == rollbackBoundary.Transaction ? "yes" : "no"); writer.WriteEndElement(); } // Write the registration information... writer.WriteStartElement("Registration"); writer.WriteAttributeString("Id", this.BundleInfo.BundleId.ToString("B")); writer.WriteAttributeString("ExecutableName", this.ExecutableName); writer.WriteAttributeString("PerMachine", this.BundleInfo.PerMachine ? "yes" : "no"); writer.WriteAttributeString("Tag", this.BundleInfo.Tag); writer.WriteAttributeString("Version", this.BundleInfo.Version); writer.WriteAttributeString("ProviderKey", this.BundleInfo.ProviderKey); writer.WriteStartElement("Arp"); writer.WriteAttributeString("Register", (0 < this.BundleInfo.DisableModify && this.BundleInfo.DisableRemove) ? "no" : "yes"); // do not register if disabled modify and remove. writer.WriteAttributeString("DisplayName", this.BundleInfo.Name); writer.WriteAttributeString("DisplayVersion", this.BundleInfo.Version); if (!String.IsNullOrEmpty(this.BundleInfo.Publisher)) { writer.WriteAttributeString("Publisher", this.BundleInfo.Publisher); } if (!String.IsNullOrEmpty(this.BundleInfo.HelpLink)) { writer.WriteAttributeString("HelpLink", this.BundleInfo.HelpLink); } if (!String.IsNullOrEmpty(this.BundleInfo.HelpTelephone)) { writer.WriteAttributeString("HelpTelephone", this.BundleInfo.HelpTelephone); } if (!String.IsNullOrEmpty(this.BundleInfo.AboutUrl)) { writer.WriteAttributeString("AboutUrl", this.BundleInfo.AboutUrl); } if (!String.IsNullOrEmpty(this.BundleInfo.UpdateUrl)) { writer.WriteAttributeString("UpdateUrl", this.BundleInfo.UpdateUrl); } if (!String.IsNullOrEmpty(this.BundleInfo.ParentName)) { writer.WriteAttributeString("ParentDisplayName", this.BundleInfo.ParentName); } if (1 == this.BundleInfo.DisableModify) { writer.WriteAttributeString("DisableModify", "yes"); } else if (2 == this.BundleInfo.DisableModify) { writer.WriteAttributeString("DisableModify", "button"); } if (this.BundleInfo.DisableRemove) { writer.WriteAttributeString("DisableRemove", "yes"); } writer.WriteEndElement(); // </Arp> // Get update registration if specified. WixUpdateRegistrationRow updateRegistrationInfo = this.Output.Tables["WixUpdateRegistration"].RowsAs <WixUpdateRegistrationRow>().FirstOrDefault(); if (null != updateRegistrationInfo) { writer.WriteStartElement("Update"); // <Update> writer.WriteAttributeString("Manufacturer", updateRegistrationInfo.Manufacturer); if (!String.IsNullOrEmpty(updateRegistrationInfo.Department)) { writer.WriteAttributeString("Department", updateRegistrationInfo.Department); } if (!String.IsNullOrEmpty(updateRegistrationInfo.ProductFamily)) { writer.WriteAttributeString("ProductFamily", updateRegistrationInfo.ProductFamily); } writer.WriteAttributeString("Name", updateRegistrationInfo.Name); writer.WriteAttributeString("Classification", updateRegistrationInfo.Classification); writer.WriteEndElement(); // </Update> } IEnumerable <Row> bundleTags = this.Output.Tables["WixBundleTag"].RowsAs <Row>(); foreach (Row row in bundleTags) { writer.WriteStartElement("SoftwareTag"); writer.WriteAttributeString("Filename", (string)row[0]); writer.WriteAttributeString("Regid", (string)row[1]); writer.WriteCData((string)row[4]); writer.WriteEndElement(); } writer.WriteEndElement(); // </Register> // write the Chain... writer.WriteStartElement("Chain"); if (this.Chain.DisableRollback) { writer.WriteAttributeString("DisableRollback", "yes"); } if (this.Chain.DisableSystemRestore) { writer.WriteAttributeString("DisableSystemRestore", "yes"); } if (this.Chain.ParallelCache) { writer.WriteAttributeString("ParallelCache", "yes"); } // Index a few tables by package. ILookup <string, WixBundlePatchTargetCodeRow> targetCodesByPatch = this.Output.Tables["WixBundlePatchTargetCode"].RowsAs <WixBundlePatchTargetCodeRow>().ToLookup(r => r.MspPackageId); ILookup <string, WixBundleMsiFeatureRow> msiFeaturesByPackage = this.Output.Tables["WixBundleMsiFeature"].RowsAs <WixBundleMsiFeatureRow>().ToLookup(r => r.ChainPackageId); ILookup <string, WixBundleMsiPropertyRow> msiPropertiesByPackage = this.Output.Tables["WixBundleMsiProperty"].RowsAs <WixBundleMsiPropertyRow>().ToLookup(r => r.ChainPackageId); ILookup <string, WixBundlePayloadRow> payloadsByPackage = this.Payloads.Values.ToLookup(p => p.Package); ILookup <string, WixBundleRelatedPackageRow> relatedPackagesByPackage = this.Output.Tables["WixBundleRelatedPackage"].RowsAs <WixBundleRelatedPackageRow>().ToLookup(r => r.ChainPackageId); ILookup <string, WixBundleSlipstreamMspRow> slipstreamMspsByPackage = this.Output.Tables["WixBundleSlipstreamMsp"].RowsAs <WixBundleSlipstreamMspRow>().ToLookup(r => r.ChainPackageId); ILookup <string, WixBundlePackageExitCodeRow> exitCodesByPackage = this.Output.Tables["WixBundlePackageExitCode"].RowsAs <WixBundlePackageExitCodeRow>().ToLookup(r => r.ChainPackageId); ILookup <string, WixBundlePackageCommandLineRow> commandLinesByPackage = this.Output.Tables["WixBundlePackageCommandLine"].RowsAs <WixBundlePackageCommandLineRow>().ToLookup(r => r.ChainPackageId); // Build up the list of target codes from all the MSPs in the chain. List <WixBundlePatchTargetCodeRow> targetCodes = new List <WixBundlePatchTargetCodeRow>(); foreach (PackageFacade package in this.OrderedPackages) { writer.WriteStartElement(String.Format(CultureInfo.InvariantCulture, "{0}Package", package.Package.Type)); writer.WriteAttributeString("Id", package.Package.WixChainItemId); switch (package.Package.Cache) { case YesNoAlwaysType.No: writer.WriteAttributeString("Cache", "no"); break; case YesNoAlwaysType.Yes: writer.WriteAttributeString("Cache", "yes"); break; case YesNoAlwaysType.Always: writer.WriteAttributeString("Cache", "always"); break; } writer.WriteAttributeString("CacheId", package.Package.CacheId); writer.WriteAttributeString("InstallSize", Convert.ToString(package.Package.InstallSize)); writer.WriteAttributeString("Size", Convert.ToString(package.Package.Size)); writer.WriteAttributeString("PerMachine", YesNoDefaultType.Yes == package.Package.PerMachine ? "yes" : "no"); writer.WriteAttributeString("Permanent", package.Package.Permanent ? "yes" : "no"); writer.WriteAttributeString("Vital", (YesNoType.Yes == package.Package.Vital) ? "yes" : "no"); if (null != package.Package.RollbackBoundary) { writer.WriteAttributeString("RollbackBoundaryForward", package.Package.RollbackBoundary); } if (!String.IsNullOrEmpty(package.Package.RollbackBoundaryBackward)) { writer.WriteAttributeString("RollbackBoundaryBackward", package.Package.RollbackBoundaryBackward); } if (!String.IsNullOrEmpty(package.Package.LogPathVariable)) { writer.WriteAttributeString("LogPathVariable", package.Package.LogPathVariable); } if (!String.IsNullOrEmpty(package.Package.RollbackLogPathVariable)) { writer.WriteAttributeString("RollbackLogPathVariable", package.Package.RollbackLogPathVariable); } if (!String.IsNullOrEmpty(package.Package.InstallCondition)) { writer.WriteAttributeString("InstallCondition", package.Package.InstallCondition); } if (WixBundlePackageType.Exe == package.Package.Type) { writer.WriteAttributeString("DetectCondition", package.ExePackage.DetectCondition); writer.WriteAttributeString("InstallArguments", package.ExePackage.InstallCommand); writer.WriteAttributeString("UninstallArguments", package.ExePackage.UninstallCommand); writer.WriteAttributeString("RepairArguments", package.ExePackage.RepairCommand); writer.WriteAttributeString("Repairable", package.ExePackage.Repairable ? "yes" : "no"); if (!String.IsNullOrEmpty(package.ExePackage.ExeProtocol)) { writer.WriteAttributeString("Protocol", package.ExePackage.ExeProtocol); } } else if (WixBundlePackageType.Msi == package.Package.Type) { writer.WriteAttributeString("ProductCode", package.MsiPackage.ProductCode); writer.WriteAttributeString("Language", package.MsiPackage.ProductLanguage.ToString(CultureInfo.InvariantCulture)); writer.WriteAttributeString("Version", package.MsiPackage.ProductVersion); writer.WriteAttributeString("DisplayInternalUI", package.MsiPackage.DisplayInternalUI ? "yes" : "no"); if (!String.IsNullOrEmpty(package.MsiPackage.UpgradeCode)) { writer.WriteAttributeString("UpgradeCode", package.MsiPackage.UpgradeCode); } } else if (WixBundlePackageType.Msp == package.Package.Type) { writer.WriteAttributeString("PatchCode", package.MspPackage.PatchCode); writer.WriteAttributeString("PatchXml", package.MspPackage.PatchXml); writer.WriteAttributeString("DisplayInternalUI", package.MspPackage.DisplayInternalUI ? "yes" : "no"); // If there is still a chance that all of our patches will target a narrow set of // product codes, add the patch list to the overall list. if (null != targetCodes) { if (!package.MspPackage.TargetUnspecified) { IEnumerable <WixBundlePatchTargetCodeRow> patchTargetCodes = targetCodesByPatch[package.MspPackage.ChainPackageId]; targetCodes.AddRange(patchTargetCodes); } else // we have a patch that targets the world, so throw the whole list away. { targetCodes = null; } } } else if (WixBundlePackageType.Msu == package.Package.Type) { writer.WriteAttributeString("DetectCondition", package.MsuPackage.DetectCondition); writer.WriteAttributeString("KB", package.MsuPackage.MsuKB); } IEnumerable <WixBundleMsiFeatureRow> packageMsiFeatures = msiFeaturesByPackage[package.Package.WixChainItemId]; foreach (WixBundleMsiFeatureRow feature in packageMsiFeatures) { writer.WriteStartElement("MsiFeature"); writer.WriteAttributeString("Id", feature.Name); writer.WriteEndElement(); } IEnumerable <WixBundleMsiPropertyRow> packageMsiProperties = msiPropertiesByPackage[package.Package.WixChainItemId]; foreach (WixBundleMsiPropertyRow msiProperty in packageMsiProperties) { writer.WriteStartElement("MsiProperty"); writer.WriteAttributeString("Id", msiProperty.Name); writer.WriteAttributeString("Value", msiProperty.Value); if (!String.IsNullOrEmpty(msiProperty.Condition)) { writer.WriteAttributeString("Condition", msiProperty.Condition); } writer.WriteEndElement(); } IEnumerable <WixBundleSlipstreamMspRow> packageSlipstreamMsps = slipstreamMspsByPackage[package.Package.WixChainItemId]; foreach (WixBundleSlipstreamMspRow slipstreamMsp in packageSlipstreamMsps) { writer.WriteStartElement("SlipstreamMsp"); writer.WriteAttributeString("Id", slipstreamMsp.MspPackageId); writer.WriteEndElement(); } IEnumerable <WixBundlePackageExitCodeRow> packageExitCodes = exitCodesByPackage[package.Package.WixChainItemId]; foreach (WixBundlePackageExitCodeRow exitCode in packageExitCodes) { writer.WriteStartElement("ExitCode"); if (exitCode.Code.HasValue) { writer.WriteAttributeString("Code", unchecked ((uint)exitCode.Code).ToString(CultureInfo.InvariantCulture)); } else { writer.WriteAttributeString("Code", "*"); } writer.WriteAttributeString("Type", ((int)exitCode.Behavior).ToString(CultureInfo.InvariantCulture)); writer.WriteEndElement(); } IEnumerable <WixBundlePackageCommandLineRow> packageCommandLines = commandLinesByPackage[package.Package.WixChainItemId]; foreach (WixBundlePackageCommandLineRow commandLine in packageCommandLines) { writer.WriteStartElement("CommandLine"); writer.WriteAttributeString("InstallArgument", commandLine.InstallArgument); writer.WriteAttributeString("UninstallArgument", commandLine.UninstallArgument); writer.WriteAttributeString("RepairArgument", commandLine.RepairArgument); writer.WriteAttributeString("Condition", commandLine.Condition); writer.WriteEndElement(); } // Output the dependency information. foreach (ProvidesDependency dependency in package.Provides) { // TODO: Add to wixpdb as an imported table, or link package wixpdbs to bundle wixpdbs. dependency.WriteXml(writer); } IEnumerable <WixBundleRelatedPackageRow> packageRelatedPackages = relatedPackagesByPackage[package.Package.WixChainItemId]; foreach (WixBundleRelatedPackageRow related in packageRelatedPackages) { writer.WriteStartElement("RelatedPackage"); writer.WriteAttributeString("Id", related.Id); if (!String.IsNullOrEmpty(related.MinVersion)) { writer.WriteAttributeString("MinVersion", related.MinVersion); writer.WriteAttributeString("MinInclusive", related.MinInclusive ? "yes" : "no"); } if (!String.IsNullOrEmpty(related.MaxVersion)) { writer.WriteAttributeString("MaxVersion", related.MaxVersion); writer.WriteAttributeString("MaxInclusive", related.MaxInclusive ? "yes" : "no"); } writer.WriteAttributeString("OnlyDetect", related.OnlyDetect ? "yes" : "no"); string[] relatedLanguages = related.Languages.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); if (0 < relatedLanguages.Length) { writer.WriteAttributeString("LangInclusive", related.LangInclusive ? "yes" : "no"); foreach (string language in relatedLanguages) { writer.WriteStartElement("Language"); writer.WriteAttributeString("Id", language); writer.WriteEndElement(); } } writer.WriteEndElement(); } // Write any contained Payloads with the PackagePayload being first writer.WriteStartElement("PayloadRef"); writer.WriteAttributeString("Id", package.Package.PackagePayload); writer.WriteEndElement(); IEnumerable <WixBundlePayloadRow> packagePayloads = payloadsByPackage[package.Package.WixChainItemId]; foreach (WixBundlePayloadRow payload in packagePayloads) { if (payload.Id != package.Package.PackagePayload) { writer.WriteStartElement("PayloadRef"); writer.WriteAttributeString("Id", payload.Id); writer.WriteEndElement(); } } writer.WriteEndElement(); // </XxxPackage> } writer.WriteEndElement(); // </Chain> if (null != targetCodes) { foreach (WixBundlePatchTargetCodeRow targetCode in targetCodes) { writer.WriteStartElement("PatchTargetCode"); writer.WriteAttributeString("TargetCode", targetCode.TargetCode); writer.WriteAttributeString("Product", targetCode.TargetsProductCode ? "yes" : "no"); writer.WriteEndElement(); } } // Write the ApprovedExeForElevation elements. IEnumerable <WixApprovedExeForElevationRow> approvedExesForElevation = this.Output.Tables["WixApprovedExeForElevation"].RowsAs <WixApprovedExeForElevationRow>(); foreach (WixApprovedExeForElevationRow approvedExeForElevation in approvedExesForElevation) { writer.WriteStartElement("ApprovedExeForElevation"); writer.WriteAttributeString("Id", approvedExeForElevation.Id); writer.WriteAttributeString("Key", approvedExeForElevation.Key); if (!String.IsNullOrEmpty(approvedExeForElevation.ValueName)) { writer.WriteAttributeString("ValueName", approvedExeForElevation.ValueName); } if (approvedExeForElevation.Win64) { writer.WriteAttributeString("Win64", "yes"); } writer.WriteEndElement(); } writer.WriteEndDocument(); // </BurnManifest> } }
public void Execute() { List <WixBundleMsiPackageRow> msiPackages = new List <WixBundleMsiPackageRow>(); Dictionary <string, List <WixBundlePatchTargetCodeRow> > targetsProductCode = new Dictionary <string, List <WixBundlePatchTargetCodeRow> >(); Dictionary <string, List <WixBundlePatchTargetCodeRow> > targetsUpgradeCode = new Dictionary <string, List <WixBundlePatchTargetCodeRow> >(); foreach (PackageFacade facade in this.PackageFacades) { if (WixBundlePackageType.Msi == facade.Package.Type) { // Keep track of all MSI packages. msiPackages.Add(facade.MsiPackage); } else if (WixBundlePackageType.Msp == facade.Package.Type && facade.MspPackage.Slipstream) { IEnumerable <WixBundlePatchTargetCodeRow> patchTargetCodeRows = this.WixBundlePatchTargetCodeTable.RowsAs <WixBundlePatchTargetCodeRow>().Where(r => r.MspPackageId == facade.Package.WixChainItemId); // Index target ProductCodes and UpgradeCodes for slipstreamed MSPs. foreach (WixBundlePatchTargetCodeRow row in patchTargetCodeRows) { if (row.TargetsProductCode) { List <WixBundlePatchTargetCodeRow> rows; if (!targetsProductCode.TryGetValue(row.TargetCode, out rows)) { rows = new List <WixBundlePatchTargetCodeRow>(); targetsProductCode.Add(row.TargetCode, rows); } rows.Add(row); } else if (row.TargetsUpgradeCode) { List <WixBundlePatchTargetCodeRow> rows; if (!targetsUpgradeCode.TryGetValue(row.TargetCode, out rows)) { rows = new List <WixBundlePatchTargetCodeRow>(); targetsUpgradeCode.Add(row.TargetCode, rows); } } } } } RowIndexedList <Row> slipstreamMspRows = new RowIndexedList <Row>(SlipstreamMspTable); // Loop through the MSI and slipstream patches targeting it. foreach (WixBundleMsiPackageRow msi in msiPackages) { List <WixBundlePatchTargetCodeRow> rows; if (targetsProductCode.TryGetValue(msi.ProductCode, out rows)) { foreach (WixBundlePatchTargetCodeRow row in rows) { Debug.Assert(row.TargetsProductCode); Debug.Assert(!row.TargetsUpgradeCode); Row slipstreamMspRow = SlipstreamMspTable.CreateRow(row.SourceLineNumbers, false); slipstreamMspRow[0] = msi.ChainPackageId; slipstreamMspRow[1] = row.MspPackageId; if (slipstreamMspRows.TryAdd(slipstreamMspRow)) { SlipstreamMspTable.Rows.Add(slipstreamMspRow); } } rows = null; } if (!String.IsNullOrEmpty(msi.UpgradeCode) && targetsUpgradeCode.TryGetValue(msi.UpgradeCode, out rows)) { foreach (WixBundlePatchTargetCodeRow row in rows) { Debug.Assert(!row.TargetsProductCode); Debug.Assert(row.TargetsUpgradeCode); Row slipstreamMspRow = SlipstreamMspTable.CreateRow(row.SourceLineNumbers, false); slipstreamMspRow[0] = msi.ChainPackageId; slipstreamMspRow[1] = row.MspPackageId; if (slipstreamMspRows.TryAdd(slipstreamMspRow)) { SlipstreamMspTable.Rows.Add(slipstreamMspRow); } } rows = null; } } }