aboutsummaryrefslogtreecommitdiff
path: root/src/WixToolset.Core.Burn
diff options
context:
space:
mode:
Diffstat (limited to 'src/WixToolset.Core.Burn')
-rw-r--r--src/WixToolset.Core.Burn/Bind/BindBundleCommand.cs7
-rw-r--r--src/WixToolset.Core.Burn/Bind/GenerateManifestDataFromIRCommand.cs1
-rw-r--r--src/WixToolset.Core.Burn/Bind/ProcessBundleSoftwareTagsCommand.cs142
-rw-r--r--src/WixToolset.Core.Burn/Bundles/CreateBurnManifestCommand.cs12
4 files changed, 155 insertions, 7 deletions
diff --git a/src/WixToolset.Core.Burn/Bind/BindBundleCommand.cs b/src/WixToolset.Core.Burn/Bind/BindBundleCommand.cs
index 93620e1b..c9a111c6 100644
--- a/src/WixToolset.Core.Burn/Bind/BindBundleCommand.cs
+++ b/src/WixToolset.Core.Burn/Bind/BindBundleCommand.cs
@@ -380,6 +380,13 @@ namespace WixToolset.Core.Burn
380 // Update the bundle per-machine/per-user scope based on the chained packages. 380 // Update the bundle per-machine/per-user scope based on the chained packages.
381 this.ResolveBundleInstallScope(section, bundleSymbol, orderedFacades); 381 this.ResolveBundleInstallScope(section, bundleSymbol, orderedFacades);
382 382
383 var softwareTags = section.Symbols.OfType<WixBundleTagSymbol>().ToList();
384 if (softwareTags.Any())
385 {
386 var command = new ProcessBundleSoftwareTagsCommand(section, softwareTags);
387 command.Execute();
388 }
389
383 // Give the extension one last hook before generating the output files. 390 // Give the extension one last hook before generating the output files.
384 foreach (var extension in this.BackendExtensions) 391 foreach (var extension in this.BackendExtensions)
385 { 392 {
diff --git a/src/WixToolset.Core.Burn/Bind/GenerateManifestDataFromIRCommand.cs b/src/WixToolset.Core.Burn/Bind/GenerateManifestDataFromIRCommand.cs
index c51d380c..36ced6cf 100644
--- a/src/WixToolset.Core.Burn/Bind/GenerateManifestDataFromIRCommand.cs
+++ b/src/WixToolset.Core.Burn/Bind/GenerateManifestDataFromIRCommand.cs
@@ -82,6 +82,7 @@ namespace WixToolset.Core.Burn.Bind
82 case SymbolDefinitionType.WixBundleRelatedPackage: 82 case SymbolDefinitionType.WixBundleRelatedPackage:
83 case SymbolDefinitionType.WixBundleRollbackBoundary: 83 case SymbolDefinitionType.WixBundleRollbackBoundary:
84 case SymbolDefinitionType.WixBundleSlipstreamMsp: 84 case SymbolDefinitionType.WixBundleSlipstreamMsp:
85 case SymbolDefinitionType.WixBundleTag:
85 case SymbolDefinitionType.WixBundleUpdate: 86 case SymbolDefinitionType.WixBundleUpdate:
86 case SymbolDefinitionType.WixBundleVariable: 87 case SymbolDefinitionType.WixBundleVariable:
87 case SymbolDefinitionType.WixBuildInfo: 88 case SymbolDefinitionType.WixBuildInfo:
diff --git a/src/WixToolset.Core.Burn/Bind/ProcessBundleSoftwareTagsCommand.cs b/src/WixToolset.Core.Burn/Bind/ProcessBundleSoftwareTagsCommand.cs
new file mode 100644
index 00000000..8584d2a4
--- /dev/null
+++ b/src/WixToolset.Core.Burn/Bind/ProcessBundleSoftwareTagsCommand.cs
@@ -0,0 +1,142 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3namespace WixToolset.Core.Burn.Bind
4{
5 using System;
6 using System.Collections.Generic;
7 using System.IO;
8 using System.Linq;
9 using System.Text;
10 using System.Xml;
11 using WixToolset.Data;
12 using WixToolset.Data.Symbols;
13 using WixToolset.Dtf.WindowsInstaller;
14
15 internal class ProcessBundleSoftwareTagsCommand
16 {
17 public ProcessBundleSoftwareTagsCommand(IntermediateSection section, IEnumerable<WixBundleTagSymbol> softwareTags)
18 {
19 this.Section = section;
20 this.SoftwareTags = softwareTags;
21 }
22
23 private IntermediateSection Section { get; }
24
25 private IEnumerable<WixBundleTagSymbol> SoftwareTags { get; }
26
27 public void Execute()
28 {
29 var bundleInfo = this.Section.Symbols.OfType<WixBundleSymbol>().FirstOrDefault();
30 var bundleId = NormalizeGuid(bundleInfo.BundleId);
31 var upgradeCode = NormalizeGuid(bundleInfo.UpgradeCode);
32
33 var uniqueId = String.Concat("wix:bundle/", bundleId);
34 var persistentId = String.Concat("wix:bundle.upgrade/", upgradeCode);
35
36 // Try to collect all the software id tags from all the child packages.
37 var containedTags = CollectPackageTags(this.Section);
38
39 foreach (var bundleTag in this.SoftwareTags)
40 {
41 using (var ms = new MemoryStream())
42 {
43 CreateTagFile(ms, uniqueId, bundleInfo.Name, bundleInfo.Version, bundleTag.Regid, bundleInfo.Manufacturer, persistentId, containedTags);
44 bundleTag.Xml = Encoding.UTF8.GetString(ms.ToArray());
45 }
46 }
47 }
48
49 private static string NormalizeGuid(string guidString)
50 {
51 if (Guid.TryParse(guidString, out var guid))
52 {
53 return guid.ToString("D").ToUpperInvariant();
54 }
55
56 return guidString;
57 }
58
59 private static IEnumerable<SoftwareTag> CollectPackageTags(IntermediateSection section)
60 {
61 var tags = new List<SoftwareTag>();
62
63 var msiPackages = section.Symbols.OfType<WixBundlePackageSymbol>().Where(s => s.Type == WixBundlePackageType.Msi).ToList();
64 if (msiPackages.Any())
65 {
66 var payloadSymbolsById = section.Symbols.OfType<WixBundlePayloadSymbol>().ToDictionary(s => s.Id.Id);
67
68 foreach (var msiPackage in msiPackages)
69 {
70 var payload = payloadSymbolsById[msiPackage.PayloadRef];
71
72 using (var db = new Database(payload.SourceFile.Path))
73 {
74 using (var view = db.OpenView("SELECT `Regid`, `TagId` FROM `SoftwareIdentificationTag`"))
75 {
76 view.Execute();
77 while (true)
78 {
79 using (var record = view.Fetch())
80 {
81 if (null == record)
82 {
83 break;
84 }
85
86 tags.Add(new SoftwareTag { Regid = record.GetString(1), Id = record.GetString(2) });
87 }
88 }
89 }
90 }
91 }
92 }
93
94 return tags;
95 }
96
97 private static void CreateTagFile(Stream stream, string uniqueId, string name, string version, string regid, string manufacturer, string persistendId, IEnumerable<SoftwareTag> containedTags)
98 {
99 var versionScheme = Version.TryParse(version, out _) ? "multipartnumeric" : "alphanumeric";
100
101 using (var writer = XmlWriter.Create(stream, new XmlWriterSettings { Indent = true}))
102 {
103 writer.WriteStartDocument();
104 writer.WriteStartElement("SoftwareIdentity", "http://standards.iso.org/iso/19770/-2/2015/schema.xsd");
105 writer.WriteAttributeString("tagId", uniqueId);
106 writer.WriteAttributeString("name", name);
107 writer.WriteAttributeString("version", version);
108 writer.WriteAttributeString("versionScheme", versionScheme);
109
110 writer.WriteStartElement("Entity");
111 writer.WriteAttributeString("name", manufacturer);
112 writer.WriteAttributeString("regid", regid);
113 writer.WriteAttributeString("role", "softwareCreator tagCreator");
114 writer.WriteEndElement(); // </Entity>
115
116 if (!String.IsNullOrEmpty(persistendId))
117 {
118 writer.WriteStartElement("Meta");
119 writer.WriteAttributeString("persistentId", persistendId);
120 writer.WriteEndElement(); // </Meta>
121 }
122
123 foreach (var containedTag in containedTags)
124 {
125 writer.WriteStartElement("Link");
126 writer.WriteAttributeString("rel", "component");
127 writer.WriteAttributeString("href", String.Concat("swid:", containedTag.Id));
128 writer.WriteEndElement(); // </Link>
129 }
130
131 writer.WriteEndElement(); // </SoftwareIdentity>
132 }
133 }
134
135 private class SoftwareTag
136 {
137 public string Regid { get; set; }
138
139 public string Id { get; set; }
140 }
141 }
142}
diff --git a/src/WixToolset.Core.Burn/Bundles/CreateBurnManifestCommand.cs b/src/WixToolset.Core.Burn/Bundles/CreateBurnManifestCommand.cs
index 71bc0229..3bc6bf1b 100644
--- a/src/WixToolset.Core.Burn/Bundles/CreateBurnManifestCommand.cs
+++ b/src/WixToolset.Core.Burn/Bundles/CreateBurnManifestCommand.cs
@@ -295,17 +295,15 @@ namespace WixToolset.Core.Burn.Bundles
295 writer.WriteEndElement(); // </Update> 295 writer.WriteEndElement(); // </Update>
296 } 296 }
297 297
298#if TODO // Handle SWID Tags 298 foreach (var bundleTagSymbol in this.Section.Symbols.OfType<WixBundleTagSymbol>())
299 var bundleTags = this.Output.Tables["WixBundleTag"].RowsAs<Row>();
300 foreach (var row in bundleTags)
301 { 299 {
302 writer.WriteStartElement("SoftwareTag"); 300 writer.WriteStartElement("SoftwareTag");
303 writer.WriteAttributeString("Filename", (string)row[0]); 301 writer.WriteAttributeString("Filename", bundleTagSymbol.Filename);
304 writer.WriteAttributeString("Regid", (string)row[1]); 302 writer.WriteAttributeString("Regid", bundleTagSymbol.Regid);
305 writer.WriteCData((string)row[4]); 303 writer.WriteAttributeString("Path", bundleTagSymbol.InstallPath);
304 writer.WriteCData(bundleTagSymbol.Xml);
306 writer.WriteEndElement(); 305 writer.WriteEndElement();
307 } 306 }
308#endif
309 307
310 writer.WriteEndElement(); // </Register> 308 writer.WriteEndElement(); // </Register>
311 309