aboutsummaryrefslogtreecommitdiff
path: root/src/wixext/DependencyCompiler.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/wixext/DependencyCompiler.cs')
-rw-r--r--src/wixext/DependencyCompiler.cs182
1 files changed, 80 insertions, 102 deletions
diff --git a/src/wixext/DependencyCompiler.cs b/src/wixext/DependencyCompiler.cs
index dafcfb3e..4ec6f477 100644
--- a/src/wixext/DependencyCompiler.cs
+++ b/src/wixext/DependencyCompiler.cs
@@ -8,6 +8,8 @@ namespace WixToolset.Dependency
8 using System.Text; 8 using System.Text;
9 using System.Xml.Linq; 9 using System.Xml.Linq;
10 using WixToolset.Data; 10 using WixToolset.Data;
11 using WixToolset.Data.Tuples;
12 using WixToolset.Dependency.Tuples;
11 using WixToolset.Extensibility; 13 using WixToolset.Extensibility;
12 using WixToolset.Extensibility.Data; 14 using WixToolset.Extensibility.Data;
13 15
@@ -38,7 +40,7 @@ namespace WixToolset.Dependency
38 /// <param name="attribute">Attribute to process.</param> 40 /// <param name="attribute">Attribute to process.</param>
39 public override void ParseAttribute(Intermediate intermediate, IntermediateSection section, XElement parentElement, XAttribute attribute, IDictionary<string, string> context) 41 public override void ParseAttribute(Intermediate intermediate, IntermediateSection section, XElement parentElement, XAttribute attribute, IDictionary<string, string> context)
40 { 42 {
41 SourceLineNumber sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(parentElement); 43 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(parentElement);
42 switch (parentElement.Name.LocalName) 44 switch (parentElement.Name.LocalName)
43 { 45 {
44 case "Bundle": 46 case "Bundle":
@@ -67,7 +69,7 @@ namespace WixToolset.Dependency
67 /// <param name="contextValues">Extra information about the context in which this element is being parsed.</param> 69 /// <param name="contextValues">Extra information about the context in which this element is being parsed.</param>
68 public override void ParseElement(Intermediate intermediate, IntermediateSection section, XElement parentElement, XElement element, IDictionary<string, string> context) 70 public override void ParseElement(Intermediate intermediate, IntermediateSection section, XElement parentElement, XElement element, IDictionary<string, string> context)
69 { 71 {
70 PackageType packageType = PackageType.None; 72 var packageType = PackageType.None;
71 73
72 switch (parentElement.Name.LocalName) 74 switch (parentElement.Name.LocalName)
73 { 75 {
@@ -104,7 +106,7 @@ namespace WixToolset.Dependency
104 106
105 if (PackageType.None != packageType) 107 if (PackageType.None != packageType)
106 { 108 {
107 string packageId = context["PackageId"]; 109 var packageId = context["PackageId"];
108 110
109 switch (element.Name.LocalName) 111 switch (element.Name.LocalName)
110 { 112 {
@@ -127,17 +129,16 @@ namespace WixToolset.Dependency
127 /// <returns>The component key path type if set.</returns> 129 /// <returns>The component key path type if set.</returns>
128 public override IComponentKeyPath ParsePossibleKeyPathElement(Intermediate intermediate, IntermediateSection section, XElement parentElement, XElement element, IDictionary<string, string> context) 130 public override IComponentKeyPath ParsePossibleKeyPathElement(Intermediate intermediate, IntermediateSection section, XElement parentElement, XElement element, IDictionary<string, string> context)
129 { 131 {
130 SourceLineNumber sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(parentElement); 132 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(parentElement);
131 IComponentKeyPath keyPath = null; 133 IComponentKeyPath keyPath = null;
132 134
133 switch (parentElement.Name.LocalName) 135 switch (parentElement.Name.LocalName)
134 { 136 {
135 case "Component": 137 case "Component":
136 string componentId = context["ComponentId"]; 138 var componentId = context["ComponentId"];
137 139
138 // 64-bit components may cause issues downlevel. 140 // 64-bit components may cause issues downlevel.
139 bool win64 = false; 141 Boolean.TryParse(context["Win64"], out var win64);
140 Boolean.TryParse(context["Win64"], out win64);
141 142
142 switch (element.Name.LocalName) 143 switch (element.Name.LocalName)
143 { 144 {
@@ -191,7 +192,7 @@ namespace WixToolset.Dependency
191 } 192 }
192 else if (0 <= (illegalChar = providerKey.IndexOfAny(DependencyCommon.InvalidCharacters))) 193 else if (0 <= (illegalChar = providerKey.IndexOfAny(DependencyCommon.InvalidCharacters)))
193 { 194 {
194 StringBuilder sb = new StringBuilder(DependencyCommon.InvalidCharacters.Length * 2); 195 var sb = new StringBuilder(DependencyCommon.InvalidCharacters.Length * 2);
195 Array.ForEach<char>(DependencyCommon.InvalidCharacters, c => sb.Append(c).Append(" ")); 196 Array.ForEach<char>(DependencyCommon.InvalidCharacters, c => sb.Append(c).Append(" "));
196 197
197 this.Messaging.Write(DependencyErrors.IllegalCharactersInProvider(sourceLineNumbers, "ProviderKey", providerKey[illegalChar], sb.ToString())); 198 this.Messaging.Write(DependencyErrors.IllegalCharactersInProvider(sourceLineNumbers, "ProviderKey", providerKey[illegalChar], sb.ToString()));
@@ -206,12 +207,14 @@ namespace WixToolset.Dependency
206 207
207 if (!this.Messaging.EncounteredError) 208 if (!this.Messaging.EncounteredError)
208 { 209 {
209 // Create the provider row for the bundle. The Component_ field is required 210 // Create the provider tuple for the bundle. The Component_ field is required
210 // in the table definition but unused for bundles, so just set it to the valid ID. 211 // in the table definition but unused for bundles, so just set it to the valid ID.
211 var row = this.ParseHelper.CreateRow(section, sourceLineNumbers, "WixDependencyProvider", id); 212 section.AddTuple(new WixDependencyProviderTuple(sourceLineNumbers, id)
212 row.Set(1, id.Id); 213 {
213 row.Set(2, providerKey); 214 ComponentRef = id.Id,
214 row.Set(5, DependencyCommon.ProvidesAttributesBundle); 215 ProviderKey = providerKey,
216 Attributes = WixDependencyProviderAttributes.ProvidesAttributesBundle,
217 });
215 } 218 }
216 } 219 }
217 220
@@ -225,16 +228,15 @@ namespace WixToolset.Dependency
225 /// <returns>The type of key path if set.</returns> 228 /// <returns>The type of key path if set.</returns>
226 private IComponentKeyPath ParseProvidesElement(Intermediate intermediate, IntermediateSection section, XElement node, PackageType packageType, string parentId) 229 private IComponentKeyPath ParseProvidesElement(Intermediate intermediate, IntermediateSection section, XElement node, PackageType packageType, string parentId)
227 { 230 {
228 SourceLineNumber sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node); 231 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node);
229 IComponentKeyPath keyPath = null; 232 IComponentKeyPath keyPath = null;
230 Identifier id = null; 233 Identifier id = null;
231 string key = null; 234 string key = null;
232 string version = null; 235 string version = null;
233 string displayName = null; 236 string displayName = null;
234 int attributes = 0;
235 int illegalChar = -1; 237 int illegalChar = -1;
236 238
237 foreach (XAttribute attrib in node.Attributes()) 239 foreach (var attrib in node.Attributes())
238 { 240 {
239 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace) 241 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
240 { 242 {
@@ -270,7 +272,7 @@ namespace WixToolset.Dependency
270 // Make sure the key does not contain any illegal characters or values. 272 // Make sure the key does not contain any illegal characters or values.
271 if (0 <= (illegalChar = key.IndexOfAny(DependencyCommon.InvalidCharacters))) 273 if (0 <= (illegalChar = key.IndexOfAny(DependencyCommon.InvalidCharacters)))
272 { 274 {
273 StringBuilder sb = new StringBuilder(DependencyCommon.InvalidCharacters.Length * 2); 275 var sb = new StringBuilder(DependencyCommon.InvalidCharacters.Length * 2);
274 Array.ForEach<char>(DependencyCommon.InvalidCharacters, c => sb.Append(c).Append(" ")); 276 Array.ForEach<char>(DependencyCommon.InvalidCharacters, c => sb.Append(c).Append(" "));
275 277
276 this.Messaging.Write(DependencyErrors.IllegalCharactersInProvider(sourceLineNumbers, "Key", key[illegalChar], sb.ToString())); 278 this.Messaging.Write(DependencyErrors.IllegalCharactersInProvider(sourceLineNumbers, "Key", key[illegalChar], sb.ToString()));
@@ -288,7 +290,7 @@ namespace WixToolset.Dependency
288 else if (PackageType.None == packageType) 290 else if (PackageType.None == packageType)
289 { 291 {
290 // Make sure the ProductCode is authored and set the key. 292 // Make sure the ProductCode is authored and set the key.
291 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "Property", "ProductCode"); 293 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, TupleDefinitions.Property, "ProductCode");
292 key = "!(bind.property.ProductCode)"; 294 key = "!(bind.property.ProductCode)";
293 } 295 }
294 296
@@ -317,7 +319,7 @@ namespace WixToolset.Dependency
317 id = this.ParseHelper.CreateIdentifier("dep", node.Name.LocalName, parentId, key); 319 id = this.ParseHelper.CreateIdentifier("dep", node.Name.LocalName, parentId, key);
318 } 320 }
319 321
320 foreach (XElement child in node.Elements()) 322 foreach (var child in node.Elements())
321 { 323 {
322 if (this.Namespace == child.Name.Namespace) 324 if (this.Namespace == child.Name.Namespace)
323 { 325 {
@@ -342,24 +344,20 @@ namespace WixToolset.Dependency
342 344
343 if (!this.Messaging.EncounteredError) 345 if (!this.Messaging.EncounteredError)
344 { 346 {
345 // Create the row in the provider table. 347 var tuple = section.AddTuple(new WixDependencyProviderTuple(sourceLineNumbers, id)
346 var row = this.ParseHelper.CreateRow(section, sourceLineNumbers, "WixDependencyProvider", id); 348 {
347 row.Set(1, parentId); 349 ComponentRef = parentId,
348 row.Set(2, key); 350 ProviderKey = key,
351 });
349 352
350 if (!String.IsNullOrEmpty(version)) 353 if (!String.IsNullOrEmpty(version))
351 { 354 {
352 row.Set(3, version); 355 tuple.Version = version;
353 } 356 }
354 357
355 if (!String.IsNullOrEmpty(displayName)) 358 if (!String.IsNullOrEmpty(displayName))
356 { 359 {
357 row.Set(4, displayName); 360 tuple.DisplayName = displayName;
358 }
359
360 if (0 != attributes)
361 {
362 row.Set(5, attributes);
363 } 361 }
364 362
365 if (PackageType.None == packageType) 363 if (PackageType.None == packageType)
@@ -377,44 +375,24 @@ namespace WixToolset.Dependency
377 } 375 }
378 376
379 // Generate registry rows for the provider using binder properties. 377 // Generate registry rows for the provider using binder properties.
380 string keyProvides = String.Concat(DependencyCommon.RegistryRoot, key); 378 var keyProvides = String.Concat(DependencyCommon.RegistryRoot, key);
379 var root = RegistryRootType.MachineUser;
380
381 var value = "[ProductCode]";
382 this.ParseHelper.CreateRegistryTuple(section, sourceLineNumbers, root, keyProvides, null, value, parentId, false);
381 383
382 row = this.ParseHelper.CreateRow(section, sourceLineNumbers, "Registry", this.ParseHelper.CreateIdentifier("reg", id.Id, "(Default)")); 384 value = !String.IsNullOrEmpty(version) ? version : "[ProductVersion]";
383 row.Set(1, -1); 385 var versionRegistryTuple =
384 row.Set(2, keyProvides); 386 this.ParseHelper.CreateRegistryTuple(section, sourceLineNumbers, root, keyProvides, "Version", value, parentId, false);
385 row.Set(4, "[ProductCode]"); 387
386 row.Set(5, parentId); 388 value = !String.IsNullOrEmpty(displayName) ? displayName : "[ProductName]";
389 this.ParseHelper.CreateRegistryTuple(section, sourceLineNumbers, root, keyProvides, "DisplayName", value, parentId, false);
387 390
388 // Use the Version registry value and use that as a potential key path. 391 // Use the Version registry value and use that as a potential key path.
389 Identifier idVersion = this.ParseHelper.CreateIdentifier("reg", id.Id, "Version");
390 keyPath = this.CreateComponentKeyPath(); 392 keyPath = this.CreateComponentKeyPath();
391 keyPath.Id = idVersion.Id; 393 keyPath.Id = versionRegistryTuple.Id;
392 keyPath.Explicit = false; 394 keyPath.Explicit = false;
393 keyPath.Type = PossibleKeyPathType.Registry; 395 keyPath.Type = PossibleKeyPathType.Registry;
394
395 row = this.ParseHelper.CreateRow(section, sourceLineNumbers, "Registry", idVersion);
396 row.Set(1, -1);
397 row.Set(2, keyProvides);
398 row.Set(3, "Version");
399 row.Set(4, !String.IsNullOrEmpty(version) ? version : "[ProductVersion]");
400 row.Set(5, parentId);
401
402 row = this.ParseHelper.CreateRow(section, sourceLineNumbers, "Registry", this.ParseHelper.CreateIdentifier("reg", id.Id, "DisplayName"));
403 row.Set(1, -1);
404 row.Set(2, keyProvides);
405 row.Set(3, "DisplayName");
406 row.Set(4, !String.IsNullOrEmpty(displayName) ? displayName : "[ProductName]");
407 row.Set(5, parentId);
408
409 if (0 != attributes)
410 {
411 row = this.ParseHelper.CreateRow(section, sourceLineNumbers, "Registry", this.ParseHelper.CreateIdentifier("reg", id.Id, "Attributes"));
412 row.Set(1, -1);
413 row.Set(2, keyProvides);
414 row.Set(3, "Attributes");
415 row.Set(4, String.Concat("#", attributes.ToString(CultureInfo.InvariantCulture.NumberFormat)));
416 row.Set(5, parentId);
417 }
418 } 396 }
419 } 397 }
420 398
@@ -429,7 +407,7 @@ namespace WixToolset.Dependency
429 /// <param name="requiresAction">Whether the Requires custom action should be referenced.</param> 407 /// <param name="requiresAction">Whether the Requires custom action should be referenced.</param>
430 private void ParseRequiresElement(Intermediate intermediate, IntermediateSection section, XElement node, string providerId, bool requiresAction) 408 private void ParseRequiresElement(Intermediate intermediate, IntermediateSection section, XElement node, string providerId, bool requiresAction)
431 { 409 {
432 SourceLineNumber sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node); 410 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node);
433 Identifier id = null; 411 Identifier id = null;
434 string providerKey = null; 412 string providerKey = null;
435 string minVersion = null; 413 string minVersion = null;
@@ -437,7 +415,7 @@ namespace WixToolset.Dependency
437 int attributes = 0; 415 int attributes = 0;
438 int illegalChar = -1; 416 int illegalChar = -1;
439 417
440 foreach (XAttribute attrib in node.Attributes()) 418 foreach (var attrib in node.Attributes())
441 { 419 {
442 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace) 420 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
443 { 421 {
@@ -502,47 +480,40 @@ namespace WixToolset.Dependency
502 // Make sure the key does not contain any illegal characters. 480 // Make sure the key does not contain any illegal characters.
503 else if (0 <= (illegalChar = providerKey.IndexOfAny(DependencyCommon.InvalidCharacters))) 481 else if (0 <= (illegalChar = providerKey.IndexOfAny(DependencyCommon.InvalidCharacters)))
504 { 482 {
505 StringBuilder sb = new StringBuilder(DependencyCommon.InvalidCharacters.Length * 2); 483 var sb = new StringBuilder(DependencyCommon.InvalidCharacters.Length * 2);
506 Array.ForEach<char>(DependencyCommon.InvalidCharacters, c => sb.Append(c).Append(" ")); 484 Array.ForEach<char>(DependencyCommon.InvalidCharacters, c => sb.Append(c).Append(" "));
507 485
508 this.Messaging.Write(DependencyErrors.IllegalCharactersInProvider(sourceLineNumbers, "ProviderKey", providerKey[illegalChar], sb.ToString())); 486 this.Messaging.Write(DependencyErrors.IllegalCharactersInProvider(sourceLineNumbers, "ProviderKey", providerKey[illegalChar], sb.ToString()));
509 } 487 }
510 488
511
512 if (!this.Messaging.EncounteredError) 489 if (!this.Messaging.EncounteredError)
513 { 490 {
514 // Reference the Require custom action if required. 491 // Reference the Require custom action if required.
515 if (requiresAction) 492 if (requiresAction)
516 { 493 {
517 if (Platform.ARM == this.Context.Platform) 494 this.AddReferenceToWixDependencyRequire(section, sourceLineNumbers);
518 {
519 // Ensure the ARM version of the CA is referenced.
520 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "CustomAction", "WixDependencyRequire_ARM");
521 }
522 else
523 {
524 // All other supported platforms use x86.
525 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "CustomAction", "WixDependencyRequire");
526 }
527 } 495 }
528 496
529 var row = this.ParseHelper.CreateRow(section, sourceLineNumbers, "WixDependency", id); 497 var tuple = section.AddTuple(new WixDependencyTuple(sourceLineNumbers, id)
530 row.Set(1, providerKey); 498 {
531 row.Set(2, minVersion); 499 ProviderKey = providerKey,
532 row.Set(3, maxVersion); 500 MinVersion = minVersion,
501 MaxVersion = maxVersion,
502 });
533 503
534 if (0 != attributes) 504 if (0 != attributes)
535 { 505 {
536 row.Set(4, attributes); 506 tuple.Attributes = attributes;
537 } 507 }
538 508
539 // Create the relationship between this WixDependency row and the WixDependencyProvider row. 509 // Create the relationship between this WixDependency tuple and the WixDependencyProvider tuple.
540 if (!String.IsNullOrEmpty(providerId)) 510 if (!String.IsNullOrEmpty(providerId))
541 { 511 {
542 // Create the relationship between the WixDependency row and the parent WixDependencyProvider row. 512 section.AddTuple(new WixDependencyRefTuple(sourceLineNumbers)
543 row = this.ParseHelper.CreateRow(section, sourceLineNumbers, "WixDependencyRef"); 513 {
544 row.Set(0, providerId); 514 WixDependencyProviderRef = providerId,
545 row.Set(1, id.Id); 515 WixDependencyRef = id.Id,
516 });
546 } 517 }
547 } 518 }
548 } 519 }
@@ -555,10 +526,10 @@ namespace WixToolset.Dependency
555 /// <param name="requiresAction">Whether the Requires custom action should be referenced.</param> 526 /// <param name="requiresAction">Whether the Requires custom action should be referenced.</param>
556 private void ParseRequiresRefElement(Intermediate intermediate, IntermediateSection section, XElement node, string providerId, bool requiresAction) 527 private void ParseRequiresRefElement(Intermediate intermediate, IntermediateSection section, XElement node, string providerId, bool requiresAction)
557 { 528 {
558 SourceLineNumber sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node); 529 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node);
559 string id = null; 530 string id = null;
560 531
561 foreach (XAttribute attrib in node.Attributes()) 532 foreach (var attrib in node.Attributes())
562 { 533 {
563 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace) 534 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
564 { 535 {
@@ -590,25 +561,32 @@ namespace WixToolset.Dependency
590 // Reference the Require custom action if required. 561 // Reference the Require custom action if required.
591 if (requiresAction) 562 if (requiresAction)
592 { 563 {
593 if (Platform.ARM == this.Context.Platform) 564 this.AddReferenceToWixDependencyRequire(section, sourceLineNumbers);
594 {
595 // Ensure the ARM version of the CA is referenced.
596 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "CustomAction", "WixDependencyRequire_ARM");
597 }
598 else
599 {
600 // All other supported platforms use x86.
601 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "CustomAction", "WixDependencyRequire");
602 }
603 } 565 }
604 566
605 // Create a link dependency on the row that contains information we'll need during bind. 567 // Create a link dependency on the row that contains information we'll need during bind.
606 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "WixDependency", id); 568 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, DependencyTupleDefinitions.WixDependency, id);
607 569
608 // Create the relationship between the WixDependency row and the parent WixDependencyProvider row. 570 // Create the relationship between the WixDependency row and the parent WixDependencyProvider row.
609 var row = this.ParseHelper.CreateRow(section, sourceLineNumbers, "WixDependencyRef"); 571 section.AddTuple(new WixDependencyRefTuple(sourceLineNumbers)
610 row.Set(0, providerId); 572 {
611 row.Set(1, id); 573 WixDependencyProviderRef = providerId,
574 WixDependencyRef = id,
575 });
576 }
577 }
578
579 private void AddReferenceToWixDependencyRequire(IntermediateSection section, SourceLineNumber sourceLineNumbers)
580 {
581 if (Platform.ARM == this.Context.Platform)
582 {
583 // Ensure the ARM version of the CA is referenced.
584 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "CustomAction", "WixDependencyRequire_ARM");
585 }
586 else
587 {
588 // All other supported platforms use x86.
589 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "CustomAction", "WixDependencyRequire");
612 } 590 }
613 } 591 }
614 } 592 }