diff options
author | Rob Mensching <rob@firegiant.com> | 2021-02-27 07:50:33 -0800 |
---|---|---|
committer | Rob Mensching <rob@firegiant.com> | 2021-02-27 15:42:33 -0800 |
commit | 3fae69ccb71d99c79adba6855ba7d6402216085d (patch) | |
tree | 538dfa5877fc26c9f8eb2953e9743fe98adeec13 /src/wixext | |
parent | f217241ff291dc53abefe3ba551d16b120d5a7aa (diff) | |
download | wix-3fae69ccb71d99c79adba6855ba7d6402216085d.tar.gz wix-3fae69ccb71d99c79adba6855ba7d6402216085d.tar.bz2 wix-3fae69ccb71d99c79adba6855ba7d6402216085d.zip |
Integrate Dependency into Core
Only the custom action handling is left in Dependency.wixext
Partially fixes wixtoolset/issues#5945
Diffstat (limited to 'src/wixext')
-rw-r--r-- | src/wixext/DependencyCommon.cs | 26 | ||||
-rw-r--r-- | src/wixext/DependencyCompiler.cs | 542 | ||||
-rw-r--r-- | src/wixext/DependencyErrors.cs | 37 | ||||
-rw-r--r-- | src/wixext/DependencyExtensionData.cs | 11 | ||||
-rw-r--r-- | src/wixext/DependencyExtensionFactory.cs | 1 | ||||
-rw-r--r-- | src/wixext/DependencyTableDefinitions.cs | 57 | ||||
-rw-r--r-- | src/wixext/DependencyWarnings.cs | 60 | ||||
-rw-r--r-- | src/wixext/DependencyWindowsInstallerBackendBinderExtension.cs | 168 | ||||
-rw-r--r-- | src/wixext/Symbols/DependencySymbolDefinitions.cs | 43 | ||||
-rw-r--r-- | src/wixext/Symbols/WixDependencyRefSymbol.cs | 55 | ||||
-rw-r--r-- | src/wixext/Symbols/WixDependencySymbol.cs | 71 |
11 files changed, 20 insertions, 1051 deletions
diff --git a/src/wixext/DependencyCommon.cs b/src/wixext/DependencyCommon.cs deleted file mode 100644 index cb36be36..00000000 --- a/src/wixext/DependencyCommon.cs +++ /dev/null | |||
@@ -1,26 +0,0 @@ | |||
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 | |||
3 | namespace WixToolset.Dependency | ||
4 | { | ||
5 | using System; | ||
6 | using WixToolset; | ||
7 | |||
8 | internal static class DependencyCommon | ||
9 | { | ||
10 | // Bundle attributes are in the upper 32-bits. | ||
11 | internal const int ProvidesAttributesBundle = 0x10000; | ||
12 | |||
13 | // Same values as for the Upgrade table in Windows Installer. | ||
14 | internal const int RequiresAttributesMinVersionInclusive = 256; | ||
15 | internal const int RequiresAttributesMaxVersionInclusive = 512; | ||
16 | |||
17 | // The root registry key for the dependency extension. We write to Software\Classes explicitly | ||
18 | // based on the current security context instead of HKCR. See | ||
19 | // http://msdn.microsoft.com/en-us/library/ms724475(VS.85).aspx for more information. | ||
20 | internal static readonly string RegistryRoot = @"Software\Classes\Installer\Dependencies\"; | ||
21 | internal static readonly string RegistryDependents = "Dependents"; | ||
22 | |||
23 | // The following characters cannot be used in a provider key. | ||
24 | internal static readonly char[] InvalidCharacters = new char[] { ' ', '\"', ';', '\\' }; | ||
25 | } | ||
26 | } | ||
diff --git a/src/wixext/DependencyCompiler.cs b/src/wixext/DependencyCompiler.cs index 18bb89df..0405c324 100644 --- a/src/wixext/DependencyCompiler.cs +++ b/src/wixext/DependencyCompiler.cs | |||
@@ -2,13 +2,9 @@ | |||
2 | 2 | ||
3 | namespace WixToolset.Dependency | 3 | namespace WixToolset.Dependency |
4 | { | 4 | { |
5 | using System; | ||
6 | using System.Collections.Generic; | 5 | using System.Collections.Generic; |
7 | using System.Text; | ||
8 | using System.Xml.Linq; | 6 | using System.Xml.Linq; |
9 | using WixToolset.Data; | 7 | using WixToolset.Data; |
10 | using WixToolset.Data.Symbols; | ||
11 | using WixToolset.Dependency.Symbols; | ||
12 | using WixToolset.Extensibility; | 8 | using WixToolset.Extensibility; |
13 | using WixToolset.Extensibility.Data; | 9 | using WixToolset.Extensibility.Data; |
14 | 10 | ||
@@ -17,18 +13,6 @@ namespace WixToolset.Dependency | |||
17 | /// </summary> | 13 | /// </summary> |
18 | public sealed class DependencyCompiler : BaseCompilerExtension | 14 | public sealed class DependencyCompiler : BaseCompilerExtension |
19 | { | 15 | { |
20 | /// <summary> | ||
21 | /// Package type when parsing the Provides element. | ||
22 | /// </summary> | ||
23 | private enum PackageType | ||
24 | { | ||
25 | None, | ||
26 | ExePackage, | ||
27 | MsiPackage, | ||
28 | MspPackage, | ||
29 | MsuPackage | ||
30 | } | ||
31 | |||
32 | public override XNamespace Namespace => "http://wixtoolset.org/schemas/v4/wxs/dependency"; | 16 | public override XNamespace Namespace => "http://wixtoolset.org/schemas/v4/wxs/dependency"; |
33 | 17 | ||
34 | /// <summary> | 18 | /// <summary> |
@@ -40,534 +24,38 @@ namespace WixToolset.Dependency | |||
40 | public override void ParseAttribute(Intermediate intermediate, IntermediateSection section, XElement parentElement, XAttribute attribute, IDictionary<string, string> context) | 24 | public override void ParseAttribute(Intermediate intermediate, IntermediateSection section, XElement parentElement, XAttribute attribute, IDictionary<string, string> context) |
41 | { | 25 | { |
42 | var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(parentElement); | 26 | var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(parentElement); |
43 | switch (parentElement.Name.LocalName) | 27 | var addCheck = YesNoType.NotSet; |
44 | { | 28 | var addRequire = YesNoType.NotSet; |
45 | case "Bundle": | ||
46 | switch (attribute.Name.LocalName) | ||
47 | { | ||
48 | case "ProviderKey": | ||
49 | this.ParseProviderKeyAttribute(section, sourceLineNumbers, parentElement, attribute); | ||
50 | break; | ||
51 | default: | ||
52 | this.ParseHelper.UnexpectedAttribute(parentElement, attribute); | ||
53 | break; | ||
54 | } | ||
55 | break; | ||
56 | default: | ||
57 | this.ParseHelper.UnexpectedAttribute(parentElement, attribute); | ||
58 | break; | ||
59 | } | ||
60 | } | ||
61 | |||
62 | /// <summary> | ||
63 | /// Processes an element for the Compiler. | ||
64 | /// </summary> | ||
65 | /// <param name="sourceLineNumbers">Source line number for the parent element.</param> | ||
66 | /// <param name="parentElement">Parent element of element to process.</param> | ||
67 | /// <param name="element">Element to process.</param> | ||
68 | /// <param name="contextValues">Extra information about the context in which this element is being parsed.</param> | ||
69 | public override void ParseElement(Intermediate intermediate, IntermediateSection section, XElement parentElement, XElement element, IDictionary<string, string> context) | ||
70 | { | ||
71 | var packageType = PackageType.None; | ||
72 | 29 | ||
73 | switch (parentElement.Name.LocalName) | 30 | switch (parentElement.Name.LocalName) |
74 | { | 31 | { |
75 | case "Bundle": | 32 | case "Provides": |
76 | case "Fragment": | 33 | if (attribute.Name.LocalName == "Check" && parentElement.Parent.Name.LocalName == "Component") |
77 | case "Module": | ||
78 | case "Package": | ||
79 | switch (element.Name.LocalName) | ||
80 | { | 34 | { |
81 | case "Requires": | 35 | addCheck = this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attribute); |
82 | this.ParseRequiresElement(intermediate, section, element, null, false); | ||
83 | break; | ||
84 | default: | ||
85 | this.ParseHelper.UnexpectedElement(parentElement, element); | ||
86 | break; | ||
87 | } | 36 | } |
88 | break; | 37 | break; |
89 | case "ExePackage": | 38 | case "Requires": |
90 | packageType = PackageType.ExePackage; | 39 | case "RequiresRef": |
91 | break; | 40 | if (attribute.Name.LocalName == "Enforce" && parentElement.Parent.Name.LocalName == "Component") |
92 | case "MsiPackage": | ||
93 | packageType = PackageType.MsiPackage; | ||
94 | break; | ||
95 | case "MspPackage": | ||
96 | packageType = PackageType.MspPackage; | ||
97 | break; | ||
98 | case "MsuPackage": | ||
99 | packageType = PackageType.MsuPackage; | ||
100 | break; | ||
101 | default: | ||
102 | this.ParseHelper.UnexpectedElement(parentElement, element); | ||
103 | break; | ||
104 | } | ||
105 | |||
106 | if (PackageType.None != packageType) | ||
107 | { | ||
108 | var packageId = context["PackageId"]; | ||
109 | |||
110 | switch (element.Name.LocalName) | ||
111 | { | ||
112 | case "Provides": | ||
113 | this.ParseProvidesElement(intermediate, section, element, packageType, packageId); | ||
114 | break; | ||
115 | default: | ||
116 | this.ParseHelper.UnexpectedElement(parentElement, element); | ||
117 | break; | ||
118 | } | ||
119 | } | ||
120 | } | ||
121 | |||
122 | /// <summary> | ||
123 | /// Processes a child element of a Component for the Compiler. | ||
124 | /// </summary> | ||
125 | /// <param name="parentElement">Parent element of element to process.</param> | ||
126 | /// <param name="element">Element to process.</param> | ||
127 | /// <param name="context">Extra information about the context in which this element is being parsed.</param> | ||
128 | /// <returns>The component key path type if set.</returns> | ||
129 | public override IComponentKeyPath ParsePossibleKeyPathElement(Intermediate intermediate, IntermediateSection section, XElement parentElement, XElement element, IDictionary<string, string> context) | ||
130 | { | ||
131 | var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(parentElement); | ||
132 | IComponentKeyPath keyPath = null; | ||
133 | |||
134 | switch (parentElement.Name.LocalName) | ||
135 | { | ||
136 | case "Component": | ||
137 | var componentId = context["ComponentId"]; | ||
138 | |||
139 | // 64-bit components may cause issues downlevel. | ||
140 | Boolean.TryParse(context["Win64"], out var win64); | ||
141 | |||
142 | switch (element.Name.LocalName) | ||
143 | { | 41 | { |
144 | case "Provides": | 42 | addRequire = this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attribute); |
145 | if (win64) | ||
146 | { | ||
147 | this.Messaging.Write(DependencyWarnings.Win64Component(sourceLineNumbers, componentId)); | ||
148 | } | ||
149 | |||
150 | keyPath = this.ParseProvidesElement(intermediate, section, element, PackageType.None, componentId); | ||
151 | break; | ||
152 | default: | ||
153 | this.ParseHelper.UnexpectedElement(parentElement, element); | ||
154 | break; | ||
155 | } | 43 | } |
156 | break; | 44 | break; |
157 | default: | ||
158 | this.ParseHelper.UnexpectedElement(parentElement, element); | ||
159 | break; | ||
160 | } | ||
161 | |||
162 | return keyPath; | ||
163 | } | ||
164 | |||
165 | /// <summary> | ||
166 | /// Processes the ProviderKey bundle attribute. | ||
167 | /// </summary> | ||
168 | /// <param name="sourceLineNumbers">Source line number for the parent element.</param> | ||
169 | /// <param name="parentElement">Parent element of attribute.</param> | ||
170 | /// <param name="attribute">The XML attribute for the ProviderKey attribute.</param> | ||
171 | private void ParseProviderKeyAttribute(IntermediateSection section, SourceLineNumber sourceLineNumbers, XElement parentElement, XAttribute attribute) | ||
172 | { | ||
173 | Identifier id = null; | ||
174 | string providerKey = null; | ||
175 | int illegalChar = -1; | ||
176 | |||
177 | switch (attribute.Name.LocalName) | ||
178 | { | ||
179 | case "ProviderKey": | ||
180 | providerKey = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attribute); | ||
181 | break; | ||
182 | default: | ||
183 | this.ParseHelper.UnexpectedAttribute(parentElement, attribute); | ||
184 | break; | ||
185 | } | ||
186 | |||
187 | // Make sure the key does not contain any illegal characters or values. | ||
188 | if (String.IsNullOrEmpty(providerKey)) | ||
189 | { | ||
190 | this.Messaging.Write(ErrorMessages.IllegalEmptyAttributeValue(sourceLineNumbers, parentElement.Name.LocalName, attribute.Name.LocalName)); | ||
191 | } | 45 | } |
192 | else if (0 <= (illegalChar = providerKey.IndexOfAny(DependencyCommon.InvalidCharacters))) | ||
193 | { | ||
194 | var sb = new StringBuilder(DependencyCommon.InvalidCharacters.Length * 2); | ||
195 | Array.ForEach<char>(DependencyCommon.InvalidCharacters, c => sb.Append(c).Append(" ")); | ||
196 | 46 | ||
197 | this.Messaging.Write(DependencyErrors.IllegalCharactersInProvider(sourceLineNumbers, "ProviderKey", providerKey[illegalChar], sb.ToString())); | 47 | if (addCheck == YesNoType.NotSet && addRequire == YesNoType.NotSet) |
198 | } | ||
199 | else if ("ALL" == providerKey) | ||
200 | { | 48 | { |
201 | this.Messaging.Write(DependencyErrors.ReservedValue(sourceLineNumbers, parentElement.Name.LocalName, "ProviderKey", providerKey)); | 49 | this.ParseHelper.UnexpectedAttribute(parentElement, attribute); |
202 | } | 50 | } |
203 | 51 | else if (addCheck == YesNoType.Yes) | |
204 | // Generate the primary key for the row. | ||
205 | id = this.ParseHelper.CreateIdentifier("dep", attribute.Name.LocalName, providerKey); | ||
206 | |||
207 | if (!this.Messaging.EncounteredError) | ||
208 | { | 52 | { |
209 | // Create the provider symbol for the bundle. The Component_ field is required | 53 | this.ParseHelper.CreateCustomActionReference(sourceLineNumbers, section, "Wix4DependencyCheck", this.Context.Platform, CustomActionPlatforms.X86 | CustomActionPlatforms.X64 | CustomActionPlatforms.ARM64); |
210 | // in the table definition but unused for bundles, so just set it to the valid ID. | ||
211 | section.AddSymbol(new WixDependencyProviderSymbol(sourceLineNumbers, id) | ||
212 | { | ||
213 | ComponentRef = id.Id, | ||
214 | ProviderKey = providerKey, | ||
215 | Attributes = WixDependencyProviderAttributes.ProvidesAttributesBundle, | ||
216 | }); | ||
217 | } | 54 | } |
218 | } | 55 | else if (addRequire == YesNoType.Yes) |
219 | |||
220 | /// <summary> | ||
221 | /// Processes the Provides element. | ||
222 | /// </summary> | ||
223 | /// <param name="node">The XML node for the Provides element.</param> | ||
224 | /// <param name="packageType">The type of the package being chained into a bundle, or "None" if building an MSI package.</param> | ||
225 | /// <param name="keyPath">Explicit key path.</param> | ||
226 | /// <param name="parentId">The identifier of the parent component or package.</param> | ||
227 | /// <returns>The type of key path if set.</returns> | ||
228 | private IComponentKeyPath ParseProvidesElement(Intermediate intermediate, IntermediateSection section, XElement node, PackageType packageType, string parentId) | ||
229 | { | ||
230 | var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node); | ||
231 | IComponentKeyPath keyPath = null; | ||
232 | Identifier id = null; | ||
233 | string key = null; | ||
234 | string version = null; | ||
235 | string displayName = null; | ||
236 | int illegalChar = -1; | ||
237 | |||
238 | foreach (var attrib in node.Attributes()) | ||
239 | { | 56 | { |
240 | if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace) | 57 | this.ParseHelper.CreateCustomActionReference(sourceLineNumbers, section, "Wix4DependencyRequire", this.Context.Platform, CustomActionPlatforms.X86 | CustomActionPlatforms.X64 | CustomActionPlatforms.ARM64); |
241 | { | ||
242 | switch (attrib.Name.LocalName) | ||
243 | { | ||
244 | case "Id": | ||
245 | id = this.ParseHelper.GetAttributeIdentifier(sourceLineNumbers, attrib); | ||
246 | break; | ||
247 | case "Key": | ||
248 | key = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); | ||
249 | break; | ||
250 | case "Version": | ||
251 | version = this.ParseHelper.GetAttributeVersionValue(sourceLineNumbers, attrib); | ||
252 | break; | ||
253 | case "DisplayName": | ||
254 | displayName = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); | ||
255 | break; | ||
256 | default: | ||
257 | this.ParseHelper.UnexpectedAttribute(node, attrib); | ||
258 | break; | ||
259 | } | ||
260 | } | ||
261 | else | ||
262 | { | ||
263 | this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, node, attrib); | ||
264 | } | ||
265 | } | 58 | } |
266 | |||
267 | // Make sure the key is valid. The key will default to the ProductCode for MSI packages | ||
268 | // and the package code for MSP packages in the binder if not specified. | ||
269 | if (!String.IsNullOrEmpty(key)) | ||
270 | { | ||
271 | // Make sure the key does not contain any illegal characters or values. | ||
272 | if (0 <= (illegalChar = key.IndexOfAny(DependencyCommon.InvalidCharacters))) | ||
273 | { | ||
274 | var sb = new StringBuilder(DependencyCommon.InvalidCharacters.Length * 2); | ||
275 | Array.ForEach<char>(DependencyCommon.InvalidCharacters, c => sb.Append(c).Append(" ")); | ||
276 | |||
277 | this.Messaging.Write(DependencyErrors.IllegalCharactersInProvider(sourceLineNumbers, "Key", key[illegalChar], sb.ToString())); | ||
278 | } | ||
279 | else if ("ALL" == key) | ||
280 | { | ||
281 | this.Messaging.Write(DependencyErrors.ReservedValue(sourceLineNumbers, node.Name.LocalName, "Key", key)); | ||
282 | } | ||
283 | } | ||
284 | else if (PackageType.ExePackage == packageType || PackageType.MsuPackage == packageType) | ||
285 | { | ||
286 | // Must specify the provider key when authored for a package. | ||
287 | this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Key")); | ||
288 | } | ||
289 | else if (PackageType.None == packageType) | ||
290 | { | ||
291 | // Make sure the ProductCode is authored and set the key. | ||
292 | this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, SymbolDefinitions.Property, "ProductCode"); | ||
293 | key = "!(bind.property.ProductCode)"; | ||
294 | } | ||
295 | |||
296 | // The Version attribute should not be authored in or for an MSI package. | ||
297 | if (!String.IsNullOrEmpty(version)) | ||
298 | { | ||
299 | switch (packageType) | ||
300 | { | ||
301 | case PackageType.None: | ||
302 | this.Messaging.Write(DependencyWarnings.DiscouragedVersionAttribute(sourceLineNumbers)); | ||
303 | break; | ||
304 | case PackageType.MsiPackage: | ||
305 | this.Messaging.Write(DependencyWarnings.DiscouragedVersionAttribute(sourceLineNumbers, parentId)); | ||
306 | break; | ||
307 | } | ||
308 | } | ||
309 | else if (PackageType.MspPackage == packageType || PackageType.MsuPackage == packageType) | ||
310 | { | ||
311 | // Must specify the Version when authored for packages that do not contain a version. | ||
312 | this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Version")); | ||
313 | } | ||
314 | |||
315 | // Need the element ID for child element processing, so generate now if not authored. | ||
316 | if (null == id) | ||
317 | { | ||
318 | id = this.ParseHelper.CreateIdentifier("dep", node.Name.LocalName, parentId, key); | ||
319 | } | ||
320 | |||
321 | foreach (var child in node.Elements()) | ||
322 | { | ||
323 | if (this.Namespace == child.Name.Namespace) | ||
324 | { | ||
325 | switch (child.Name.LocalName) | ||
326 | { | ||
327 | case "Requires": | ||
328 | this.ParseRequiresElement(intermediate, section, child, id.Id, PackageType.None == packageType); | ||
329 | break; | ||
330 | case "RequiresRef": | ||
331 | this.ParseRequiresRefElement(intermediate, section, child, id.Id, PackageType.None == packageType); | ||
332 | break; | ||
333 | default: | ||
334 | this.ParseHelper.UnexpectedElement(node, child); | ||
335 | break; | ||
336 | } | ||
337 | } | ||
338 | else | ||
339 | { | ||
340 | this.ParseHelper.ParseExtensionElement(this.Context.Extensions, intermediate, section, node, child); | ||
341 | } | ||
342 | } | ||
343 | |||
344 | if (!this.Messaging.EncounteredError) | ||
345 | { | ||
346 | var symbol = section.AddSymbol(new WixDependencyProviderSymbol(sourceLineNumbers, id) | ||
347 | { | ||
348 | ComponentRef = parentId, | ||
349 | ProviderKey = key, | ||
350 | }); | ||
351 | |||
352 | if (!String.IsNullOrEmpty(version)) | ||
353 | { | ||
354 | symbol.Version = version; | ||
355 | } | ||
356 | |||
357 | if (!String.IsNullOrEmpty(displayName)) | ||
358 | { | ||
359 | symbol.DisplayName = displayName; | ||
360 | } | ||
361 | |||
362 | if (PackageType.None == packageType) | ||
363 | { | ||
364 | this.ParseHelper.CreateCustomActionReference(sourceLineNumbers, section, "DependencyCheck", this.Context.Platform, CustomActionPlatforms.X86 | CustomActionPlatforms.X64 | CustomActionPlatforms.ARM64); | ||
365 | |||
366 | // Generate registry rows for the provider using binder properties. | ||
367 | var keyProvides = String.Concat(DependencyCommon.RegistryRoot, key); | ||
368 | var root = RegistryRootType.MachineUser; | ||
369 | |||
370 | var value = "[ProductCode]"; | ||
371 | this.ParseHelper.CreateRegistrySymbol(section, sourceLineNumbers, root, keyProvides, null, value, parentId, false); | ||
372 | |||
373 | value = !String.IsNullOrEmpty(version) ? version : "[ProductVersion]"; | ||
374 | var versionRegistrySymbol = | ||
375 | this.ParseHelper.CreateRegistrySymbol(section, sourceLineNumbers, root, keyProvides, "Version", value, parentId, false); | ||
376 | |||
377 | value = !String.IsNullOrEmpty(displayName) ? displayName : "[ProductName]"; | ||
378 | this.ParseHelper.CreateRegistrySymbol(section, sourceLineNumbers, root, keyProvides, "DisplayName", value, parentId, false); | ||
379 | |||
380 | // Use the Version registry value and use that as a potential key path. | ||
381 | keyPath = this.CreateComponentKeyPath(); | ||
382 | keyPath.Id = versionRegistrySymbol.Id; | ||
383 | keyPath.Explicit = false; | ||
384 | keyPath.Type = PossibleKeyPathType.Registry; | ||
385 | } | ||
386 | } | ||
387 | |||
388 | return keyPath; | ||
389 | } | ||
390 | |||
391 | /// <summary> | ||
392 | /// Processes the Requires element. | ||
393 | /// </summary> | ||
394 | /// <param name="node">The XML node for the Requires element.</param> | ||
395 | /// <param name="providerId">The parent provider identifier.</param> | ||
396 | /// <param name="requiresAction">Whether the Requires custom action should be referenced.</param> | ||
397 | private void ParseRequiresElement(Intermediate intermediate, IntermediateSection section, XElement node, string providerId, bool requiresAction) | ||
398 | { | ||
399 | var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node); | ||
400 | Identifier id = null; | ||
401 | string providerKey = null; | ||
402 | string minVersion = null; | ||
403 | string maxVersion = null; | ||
404 | int attributes = 0; | ||
405 | int illegalChar = -1; | ||
406 | |||
407 | foreach (var attrib in node.Attributes()) | ||
408 | { | ||
409 | if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace) | ||
410 | { | ||
411 | switch (attrib.Name.LocalName) | ||
412 | { | ||
413 | case "Id": | ||
414 | id = this.ParseHelper.GetAttributeIdentifier(sourceLineNumbers, attrib); | ||
415 | break; | ||
416 | case "ProviderKey": | ||
417 | providerKey = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); | ||
418 | break; | ||
419 | case "Minimum": | ||
420 | minVersion = this.ParseHelper.GetAttributeVersionValue(sourceLineNumbers, attrib); | ||
421 | break; | ||
422 | case "Maximum": | ||
423 | maxVersion = this.ParseHelper.GetAttributeVersionValue(sourceLineNumbers, attrib); | ||
424 | break; | ||
425 | case "IncludeMinimum": | ||
426 | if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) | ||
427 | { | ||
428 | attributes |= DependencyCommon.RequiresAttributesMinVersionInclusive; | ||
429 | } | ||
430 | break; | ||
431 | case "IncludeMaximum": | ||
432 | if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) | ||
433 | { | ||
434 | attributes |= DependencyCommon.RequiresAttributesMaxVersionInclusive; | ||
435 | } | ||
436 | break; | ||
437 | default: | ||
438 | this.ParseHelper.UnexpectedAttribute(node, attrib); | ||
439 | break; | ||
440 | } | ||
441 | } | ||
442 | else | ||
443 | { | ||
444 | this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, node, attrib); | ||
445 | } | ||
446 | } | ||
447 | |||
448 | this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, node); | ||
449 | |||
450 | if (null == id) | ||
451 | { | ||
452 | // Generate an ID only if this element is authored under a Provides element; otherwise, a RequiresRef | ||
453 | // element will be necessary and the Id attribute will be required. | ||
454 | if (!String.IsNullOrEmpty(providerId)) | ||
455 | { | ||
456 | id = this.ParseHelper.CreateIdentifier("dep", node.Name.LocalName, providerKey); | ||
457 | } | ||
458 | else | ||
459 | { | ||
460 | this.Messaging.Write(ErrorMessages.ExpectedAttributeWhenElementNotUnderElement(sourceLineNumbers, node.Name.LocalName, "Id", "Provides")); | ||
461 | id = Identifier.Invalid; | ||
462 | } | ||
463 | } | ||
464 | |||
465 | if (String.IsNullOrEmpty(providerKey)) | ||
466 | { | ||
467 | this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "ProviderKey")); | ||
468 | } | ||
469 | // Make sure the key does not contain any illegal characters. | ||
470 | else if (0 <= (illegalChar = providerKey.IndexOfAny(DependencyCommon.InvalidCharacters))) | ||
471 | { | ||
472 | var sb = new StringBuilder(DependencyCommon.InvalidCharacters.Length * 2); | ||
473 | Array.ForEach<char>(DependencyCommon.InvalidCharacters, c => sb.Append(c).Append(" ")); | ||
474 | |||
475 | this.Messaging.Write(DependencyErrors.IllegalCharactersInProvider(sourceLineNumbers, "ProviderKey", providerKey[illegalChar], sb.ToString())); | ||
476 | } | ||
477 | |||
478 | if (!this.Messaging.EncounteredError) | ||
479 | { | ||
480 | // Reference the Require custom action if required. | ||
481 | if (requiresAction) | ||
482 | { | ||
483 | this.AddReferenceToWixDependencyRequire(section, sourceLineNumbers); | ||
484 | } | ||
485 | |||
486 | var symbol = section.AddSymbol(new WixDependencySymbol(sourceLineNumbers, id) | ||
487 | { | ||
488 | ProviderKey = providerKey, | ||
489 | MinVersion = minVersion, | ||
490 | MaxVersion = maxVersion, | ||
491 | }); | ||
492 | |||
493 | if (0 != attributes) | ||
494 | { | ||
495 | symbol.Attributes = attributes; | ||
496 | } | ||
497 | |||
498 | // Create the relationship between this WixDependency symbol and the WixDependencyProvider symbol. | ||
499 | if (!String.IsNullOrEmpty(providerId)) | ||
500 | { | ||
501 | section.AddSymbol(new WixDependencyRefSymbol(sourceLineNumbers) | ||
502 | { | ||
503 | WixDependencyProviderRef = providerId, | ||
504 | WixDependencyRef = id.Id, | ||
505 | }); | ||
506 | } | ||
507 | } | ||
508 | } | ||
509 | |||
510 | /// <summary> | ||
511 | /// Processes the RequiresRef element. | ||
512 | /// </summary> | ||
513 | /// <param name="node">The XML node for the RequiresRef element.</param> | ||
514 | /// <param name="providerId">The parent provider identifier.</param> | ||
515 | /// <param name="requiresAction">Whether the Requires custom action should be referenced.</param> | ||
516 | private void ParseRequiresRefElement(Intermediate intermediate, IntermediateSection section, XElement node, string providerId, bool requiresAction) | ||
517 | { | ||
518 | var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node); | ||
519 | string id = null; | ||
520 | |||
521 | foreach (var attrib in node.Attributes()) | ||
522 | { | ||
523 | if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace) | ||
524 | { | ||
525 | switch (attrib.Name.LocalName) | ||
526 | { | ||
527 | case "Id": | ||
528 | id = this.ParseHelper.GetAttributeIdentifierValue(sourceLineNumbers, attrib); | ||
529 | break; | ||
530 | default: | ||
531 | this.ParseHelper.UnexpectedAttribute(node, attrib); | ||
532 | break; | ||
533 | } | ||
534 | } | ||
535 | else | ||
536 | { | ||
537 | this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, node, attrib); | ||
538 | } | ||
539 | } | ||
540 | |||
541 | this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, node); | ||
542 | |||
543 | if (String.IsNullOrEmpty(id)) | ||
544 | { | ||
545 | this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); | ||
546 | } | ||
547 | |||
548 | if (!this.Messaging.EncounteredError) | ||
549 | { | ||
550 | // Reference the Require custom action if required. | ||
551 | if (requiresAction) | ||
552 | { | ||
553 | this.AddReferenceToWixDependencyRequire(section, sourceLineNumbers); | ||
554 | } | ||
555 | |||
556 | // Create a link dependency on the row that contains information we'll need during bind. | ||
557 | this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, DependencySymbolDefinitions.WixDependency, id); | ||
558 | |||
559 | // Create the relationship between the WixDependency row and the parent WixDependencyProvider row. | ||
560 | section.AddSymbol(new WixDependencyRefSymbol(sourceLineNumbers) | ||
561 | { | ||
562 | WixDependencyProviderRef = providerId, | ||
563 | WixDependencyRef = id, | ||
564 | }); | ||
565 | } | ||
566 | } | ||
567 | |||
568 | private void AddReferenceToWixDependencyRequire(IntermediateSection section, SourceLineNumber sourceLineNumbers) | ||
569 | { | ||
570 | this.ParseHelper.CreateCustomActionReference(sourceLineNumbers, section, "DependencyRequire", this.Context.Platform, CustomActionPlatforms.X86 | CustomActionPlatforms.X64 | CustomActionPlatforms.ARM64); | ||
571 | } | 59 | } |
572 | } | 60 | } |
573 | } | 61 | } |
diff --git a/src/wixext/DependencyErrors.cs b/src/wixext/DependencyErrors.cs deleted file mode 100644 index 83c0986a..00000000 --- a/src/wixext/DependencyErrors.cs +++ /dev/null | |||
@@ -1,37 +0,0 @@ | |||
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 | |||
3 | namespace WixToolset.Dependency | ||
4 | { | ||
5 | using System; | ||
6 | using System.Resources; | ||
7 | using WixToolset.Data; | ||
8 | |||
9 | public static class DependencyErrors | ||
10 | { | ||
11 | public static Message IllegalCharactersInProvider(SourceLineNumber sourceLineNumbers, string attributeName, Char illegalChar, string illegalChars) | ||
12 | { | ||
13 | return Message(sourceLineNumbers, Ids.IllegalCharactersInProvider, "The provider key authored into the {0} attribute contains an illegal character, '{1}'. Please author the provider key without any of the following characters: {2}", attributeName, illegalChar, illegalChars); | ||
14 | } | ||
15 | |||
16 | public static Message ReservedValue(SourceLineNumber sourceLineNumbers, string elementName, string attributeName, string attributeValue) | ||
17 | { | ||
18 | return Message(sourceLineNumbers, Ids.ReservedValue, "The {0}/@{1} attribute value '{2}' is reserved and cannot be used here. Please choose a different value.", elementName, attributeName, attributeValue); | ||
19 | } | ||
20 | |||
21 | private static Message Message(SourceLineNumber sourceLineNumber, Ids id, string format, params object[] args) | ||
22 | { | ||
23 | return new Message(sourceLineNumber, MessageLevel.Error, (int)id, format, args); | ||
24 | } | ||
25 | |||
26 | private static Message Message(SourceLineNumber sourceLineNumber, Ids id, ResourceManager resourceManager, string resourceName, params object[] args) | ||
27 | { | ||
28 | return new Message(sourceLineNumber, MessageLevel.Error, (int)id, resourceManager, resourceName, args); | ||
29 | } | ||
30 | |||
31 | public enum Ids | ||
32 | { | ||
33 | IllegalCharactersInProvider = 5400, | ||
34 | ReservedValue = 5401, | ||
35 | } | ||
36 | } | ||
37 | } | ||
diff --git a/src/wixext/DependencyExtensionData.cs b/src/wixext/DependencyExtensionData.cs index e7d8746c..2f30c2bf 100644 --- a/src/wixext/DependencyExtensionData.cs +++ b/src/wixext/DependencyExtensionData.cs | |||
@@ -16,12 +16,11 @@ namespace WixToolset.Dependency | |||
16 | /// <value>The default culture.</value> | 16 | /// <value>The default culture.</value> |
17 | public override string DefaultCulture => "en-US"; | 17 | public override string DefaultCulture => "en-US"; |
18 | 18 | ||
19 | public override bool TryGetSymbolDefinitionByName(string name, out IntermediateSymbolDefinition symbolDefinition) | 19 | /// <summary> |
20 | { | 20 | /// Gets the contained .wixlib content. |
21 | symbolDefinition = DependencySymbolDefinitions.ByName(name); | 21 | /// </summary> |
22 | return symbolDefinition != null; | 22 | /// <param name="symbolDefinitions">Strong typed symbold definitions.</param> |
23 | } | 23 | /// <returns>The .wixlib.</returns> |
24 | |||
25 | public override Intermediate GetLibrary(ISymbolDefinitionCreator symbolDefinitions) | 24 | public override Intermediate GetLibrary(ISymbolDefinitionCreator symbolDefinitions) |
26 | { | 25 | { |
27 | return Intermediate.Load(typeof(DependencyExtensionData).Assembly, "WixToolset.Dependency.dependency.wixlib", symbolDefinitions); | 26 | return Intermediate.Load(typeof(DependencyExtensionData).Assembly, "WixToolset.Dependency.dependency.wixlib", symbolDefinitions); |
diff --git a/src/wixext/DependencyExtensionFactory.cs b/src/wixext/DependencyExtensionFactory.cs index c5b89658..354f9234 100644 --- a/src/wixext/DependencyExtensionFactory.cs +++ b/src/wixext/DependencyExtensionFactory.cs | |||
@@ -12,7 +12,6 @@ namespace WixToolset.Dependency | |||
12 | { | 12 | { |
13 | typeof(DependencyCompiler), | 13 | typeof(DependencyCompiler), |
14 | typeof(DependencyExtensionData), | 14 | typeof(DependencyExtensionData), |
15 | typeof(DependencyWindowsInstallerBackendBinderExtension), | ||
16 | }; | 15 | }; |
17 | } | 16 | } |
18 | } | 17 | } |
diff --git a/src/wixext/DependencyTableDefinitions.cs b/src/wixext/DependencyTableDefinitions.cs deleted file mode 100644 index d3f643e4..00000000 --- a/src/wixext/DependencyTableDefinitions.cs +++ /dev/null | |||
@@ -1,57 +0,0 @@ | |||
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 | |||
3 | namespace WixToolset.Dependency | ||
4 | { | ||
5 | using WixToolset.Data; | ||
6 | using WixToolset.Data.WindowsInstaller; | ||
7 | |||
8 | public static class DependencyTableDefinitions | ||
9 | { | ||
10 | public static readonly TableDefinition WixDependencyProvider = new TableDefinition( | ||
11 | "WixDependencyProvider", | ||
12 | SymbolDefinitions.WixDependencyProvider, | ||
13 | new[] | ||
14 | { | ||
15 | new ColumnDefinition("WixDependencyProvider", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, description: "The non-localized primary key for the table.", modularizeType: ColumnModularizeType.Column), | ||
16 | new ColumnDefinition("Component_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, keyTable: "Component", keyColumn: 1, description: "The foreign key into the Component table used to determine install state.", modularizeType: ColumnModularizeType.Column), | ||
17 | new ColumnDefinition("ProviderKey", ColumnType.String, 255, primaryKey: false, nullable: false, ColumnCategory.Text, description: "The name of the registry key that holds the provider identity."), | ||
18 | new ColumnDefinition("Version", ColumnType.String, 72, primaryKey: false, nullable: true, ColumnCategory.Version, description: "The version of the package."), | ||
19 | new ColumnDefinition("DisplayName", ColumnType.String, 255, primaryKey: false, nullable: true, ColumnCategory.Text, description: "The display name of the package."), | ||
20 | new ColumnDefinition("Attributes", ColumnType.Number, 4, primaryKey: false, nullable: true, ColumnCategory.Unknown, minValue: 0, maxValue: 2147483647, description: "A 32-bit word that specifies the attribute flags to be applied."), | ||
21 | }, | ||
22 | symbolIdIsPrimaryKey: true | ||
23 | ); | ||
24 | |||
25 | public static readonly TableDefinition WixDependency = new TableDefinition( | ||
26 | "WixDependency", | ||
27 | DependencySymbolDefinitions.WixDependency, | ||
28 | new[] | ||
29 | { | ||
30 | new ColumnDefinition("WixDependency", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, description: "The non-localized primary key for the table.", modularizeType: ColumnModularizeType.Column), | ||
31 | new ColumnDefinition("ProviderKey", ColumnType.String, 255, primaryKey: false, nullable: false, ColumnCategory.Text, description: "The name of the registry key that holds the provider identity."), | ||
32 | new ColumnDefinition("MinVersion", ColumnType.String, 72, primaryKey: false, nullable: true, ColumnCategory.Version, description: "The minimum version of the provider supported."), | ||
33 | new ColumnDefinition("MaxVersion", ColumnType.String, 72, primaryKey: false, nullable: true, ColumnCategory.Version, description: "The maximum version of the provider supported."), | ||
34 | new ColumnDefinition("Attributes", ColumnType.Number, 4, primaryKey: false, nullable: true, ColumnCategory.Unknown, minValue: 0, maxValue: 2147483647, description: "A 32-bit word that specifies the attribute flags to be applied."), | ||
35 | }, | ||
36 | symbolIdIsPrimaryKey: true | ||
37 | ); | ||
38 | |||
39 | public static readonly TableDefinition WixDependencyRef = new TableDefinition( | ||
40 | "WixDependencyRef", | ||
41 | DependencySymbolDefinitions.WixDependencyRef, | ||
42 | new[] | ||
43 | { | ||
44 | new ColumnDefinition("WixDependencyProvider_", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, keyTable: "WixDependencyProvider", keyColumn: 1, description: "Foreign key into the Component table.", modularizeType: ColumnModularizeType.Column), | ||
45 | new ColumnDefinition("WixDependency_", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, keyTable: "WixDependency", keyColumn: 1, description: "Foreign key into the WixDependency table.", modularizeType: ColumnModularizeType.Column), | ||
46 | }, | ||
47 | symbolIdIsPrimaryKey: false | ||
48 | ); | ||
49 | |||
50 | public static readonly TableDefinition[] All = new[] | ||
51 | { | ||
52 | WixDependencyProvider, | ||
53 | WixDependency, | ||
54 | WixDependencyRef, | ||
55 | }; | ||
56 | } | ||
57 | } | ||
diff --git a/src/wixext/DependencyWarnings.cs b/src/wixext/DependencyWarnings.cs deleted file mode 100644 index 802edc22..00000000 --- a/src/wixext/DependencyWarnings.cs +++ /dev/null | |||
@@ -1,60 +0,0 @@ | |||
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 | |||
3 | namespace WixToolset.Dependency | ||
4 | { | ||
5 | using System; | ||
6 | using System.Resources; | ||
7 | using WixToolset.Data; | ||
8 | |||
9 | public static class DependencyWarnings | ||
10 | { | ||
11 | public static Message DiscouragedVersionAttribute(SourceLineNumber sourceLineNumbers) | ||
12 | { | ||
13 | return Message(sourceLineNumbers, Ids.DiscouragedVersionAttribute, "The Provides/@Version attribute should not be specified in an MSI package. The ProductVersion will be used by default."); | ||
14 | } | ||
15 | |||
16 | public static Message DiscouragedVersionAttribute(SourceLineNumber sourceLineNumbers, string id) | ||
17 | { | ||
18 | return Message(sourceLineNumbers, Ids.DiscouragedVersionAttribute, "The Provides/@Version attribute should not be specified for MSI package {0}. The ProductVersion will be used by default.", id); | ||
19 | } | ||
20 | |||
21 | public static Message PropertyRemoved(string name) | ||
22 | { | ||
23 | return Message(null, Ids.PropertyRemoved, "The property {0} was authored in the package with a value and will be removed. The property should not be authored.", name); | ||
24 | } | ||
25 | |||
26 | public static Message ProvidesKeyNotFound(SourceLineNumber sourceLineNumbers, string id) | ||
27 | { | ||
28 | return Message(sourceLineNumbers, Ids.ProvidesKeyNotFound, "The provider key with identifier {0} was not found in the WixDependencyProvider table. Related registry rows will not be removed from authoring.", id); | ||
29 | } | ||
30 | |||
31 | public static Message RequiresKeyNotFound(SourceLineNumber sourceLineNumbers, string id) | ||
32 | { | ||
33 | return Message(sourceLineNumbers, Ids.RequiresKeyNotFound, "The dependency key with identifier {0} was not found in the WixDependency table. Related registry rows will not be removed from authoring.", id); | ||
34 | } | ||
35 | |||
36 | public static Message Win64Component(SourceLineNumber sourceLineNumbers, string componentId) | ||
37 | { | ||
38 | return Message(sourceLineNumbers, Ids.Win64Component, "The Provides element should not be authored in the 64-bit component with identifier {0}. The dependency feature may not work if installing this package on 64-bit Windows operating systems prior to Windows 7 and Windows Server 2008 R2. Set the Component/@Win64 attribute to \"no\" to make sure the dependency feature works correctly on all supported operating systems.", componentId); | ||
39 | } | ||
40 | |||
41 | private static Message Message(SourceLineNumber sourceLineNumber, Ids id, string format, params object[] args) | ||
42 | { | ||
43 | return new Message(sourceLineNumber, MessageLevel.Warning, (int)id, format, args); | ||
44 | } | ||
45 | |||
46 | private static Message Message(SourceLineNumber sourceLineNumber, Ids id, ResourceManager resourceManager, string resourceName, params object[] args) | ||
47 | { | ||
48 | return new Message(sourceLineNumber, MessageLevel.Warning, (int)id, resourceManager, resourceName, args); | ||
49 | } | ||
50 | |||
51 | public enum Ids | ||
52 | { | ||
53 | ProvidesKeyNotFound = 5431, | ||
54 | RequiresKeyNotFound = 5432, | ||
55 | PropertyRemoved = 5433, | ||
56 | DiscouragedVersionAttribute = 5434, | ||
57 | Win64Component = 5435, | ||
58 | } | ||
59 | } | ||
60 | } | ||
diff --git a/src/wixext/DependencyWindowsInstallerBackendBinderExtension.cs b/src/wixext/DependencyWindowsInstallerBackendBinderExtension.cs deleted file mode 100644 index f52f97f3..00000000 --- a/src/wixext/DependencyWindowsInstallerBackendBinderExtension.cs +++ /dev/null | |||
@@ -1,168 +0,0 @@ | |||
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 | |||
3 | namespace WixToolset.Dependency | ||
4 | { | ||
5 | using System.Collections.Generic; | ||
6 | using WixToolset.Data.WindowsInstaller; | ||
7 | using WixToolset.Extensibility; | ||
8 | |||
9 | public class DependencyWindowsInstallerBackendBinderExtension : BaseWindowsInstallerBackendBinderExtension | ||
10 | { | ||
11 | public override IEnumerable<TableDefinition> TableDefinitions => DependencyTableDefinitions.All; | ||
12 | |||
13 | #if TODO_DEPENDENCY_BINDER_EXTENSION | ||
14 | private Output output; | ||
15 | |||
16 | /// <summary> | ||
17 | /// Called after all output changes occur and right before the output is bound into its final format. | ||
18 | /// </summary> | ||
19 | public void Finish(Output output) | ||
20 | { | ||
21 | // Only process MSI packages. | ||
22 | if (OutputType.Product != output.Type) | ||
23 | { | ||
24 | return; | ||
25 | } | ||
26 | |||
27 | this.output = output; | ||
28 | |||
29 | Table wixDependencyTable = output.Tables["WixDependency"]; | ||
30 | Table wixDependencyProviderTable = output.Tables["WixDependencyProvider"]; | ||
31 | Table wixDependencyRefTable = output.Tables["WixDependencyRef"]; | ||
32 | |||
33 | // Make sure there's something to do. | ||
34 | if (null != wixDependencyRefTable) | ||
35 | { | ||
36 | KeyedRowCollection wixDependencyRows = new KeyedRowCollection(wixDependencyTable); | ||
37 | KeyedRowCollection wixDependencyProviderRows = new KeyedRowCollection(wixDependencyProviderTable); | ||
38 | |||
39 | // For each relationship, get the provides and requires rows to generate registry values. | ||
40 | foreach (Row wixDependencyRefRow in wixDependencyRefTable.Rows) | ||
41 | { | ||
42 | string providesId = (string)wixDependencyRefRow[0]; | ||
43 | string requiresId = (string)wixDependencyRefRow[1]; | ||
44 | |||
45 | Row wixDependencyRow = null; | ||
46 | if (wixDependencyRows.Contains(requiresId)) | ||
47 | { | ||
48 | wixDependencyRow = wixDependencyRows[requiresId]; | ||
49 | } | ||
50 | |||
51 | Row wixDependencyProviderRow = null; | ||
52 | if (wixDependencyProviderRows.Contains(providesId)) | ||
53 | { | ||
54 | wixDependencyProviderRow = wixDependencyProviderRows[providesId]; | ||
55 | } | ||
56 | |||
57 | // If we found both rows, generate the registry values. | ||
58 | if (null != wixDependencyRow && null != wixDependencyProviderRow) | ||
59 | { | ||
60 | // Format the root registry key using the required provider key and the current provider key. | ||
61 | string requiresKey = (string)wixDependencyRow[1]; | ||
62 | string providesKey = (string)wixDependencyProviderRow[2]; | ||
63 | string keyRequires = String.Format(@"{0}{1}\{2}\{3}", DependencyCommon.RegistryRoot, requiresKey, DependencyCommon.RegistryDependents, providesKey); | ||
64 | |||
65 | // Get the component ID from the provider. | ||
66 | string componentId = (string)wixDependencyProviderRow[1]; | ||
67 | |||
68 | Row row = this.CreateRegistryRow(wixDependencyRow); | ||
69 | row[0] = this.Core.CreateIdentifier("reg", providesId, requiresId, "(Default)"); | ||
70 | row[1] = -1; | ||
71 | row[2] = keyRequires; | ||
72 | row[3] = "*"; | ||
73 | row[4] = null; | ||
74 | row[5] = componentId; | ||
75 | |||
76 | string minVersion = (string)wixDependencyRow[2]; | ||
77 | if (!String.IsNullOrEmpty(minVersion)) | ||
78 | { | ||
79 | row = this.CreateRegistryRow(wixDependencyRow); | ||
80 | row[0] = this.Core.CreateIdentifier("reg", providesId, requiresId, "MinVersion"); | ||
81 | row[1] = -1; | ||
82 | row[2] = keyRequires; | ||
83 | row[3] = "MinVersion"; | ||
84 | row[4] = minVersion; | ||
85 | row[5] = componentId; | ||
86 | } | ||
87 | |||
88 | string maxVersion = (string)wixDependencyRow[3]; | ||
89 | if (!String.IsNullOrEmpty(minVersion)) | ||
90 | { | ||
91 | row = this.CreateRegistryRow(wixDependencyRow); | ||
92 | row[0] = this.Core.CreateIdentifier("reg", providesId, requiresId, "MaxVersion"); | ||
93 | row[1] = -1; | ||
94 | row[2] = keyRequires; | ||
95 | row[3] = "MaxVersion"; | ||
96 | row[4] = maxVersion; | ||
97 | row[5] = componentId; | ||
98 | } | ||
99 | |||
100 | if (null != wixDependencyRow[4]) | ||
101 | { | ||
102 | int attributes = (int)wixDependencyRow[4]; | ||
103 | |||
104 | row = this.CreateRegistryRow(wixDependencyRow); | ||
105 | row[0] = this.Core.CreateIdentifier("reg", providesId, requiresId, "Attributes"); | ||
106 | row[1] = -1; | ||
107 | row[2] = keyRequires; | ||
108 | row[3] = "Attributes"; | ||
109 | row[4] = String.Concat("#", attributes.ToString(CultureInfo.InvariantCulture.NumberFormat)); | ||
110 | row[5] = componentId; | ||
111 | } | ||
112 | } | ||
113 | } | ||
114 | } | ||
115 | } | ||
116 | |||
117 | /// <summary> | ||
118 | /// Creates a registry row using source information from the given <see cref="Row"/>. | ||
119 | /// </summary> | ||
120 | /// <param name="referenceRow">The <see cref="Row"/> from which the section and source line information are retrieved.</param> | ||
121 | /// <returns>A new Registry row.</returns> | ||
122 | private Row CreateRegistryRow(Row referenceRow) | ||
123 | { | ||
124 | TableDefinition tableDefinition = this.Core.TableDefinitions["Registry"]; | ||
125 | |||
126 | // Create the row from the main tables, which were populated during link anyway. | ||
127 | // We still associate the table with the dependency row's section to maintain servicing. | ||
128 | Table table = this.output.EnsureTable(tableDefinition, referenceRow.Table.Section); | ||
129 | Row row = table.CreateRow(referenceRow.SourceLineNumbers); | ||
130 | |||
131 | // Set the section ID for patching and return the new row. | ||
132 | row.SectionId = referenceRow.SectionId; | ||
133 | return row; | ||
134 | } | ||
135 | |||
136 | /// <summary> | ||
137 | /// A keyed collection of <see cref="Row"/> instances for O(1) lookup. | ||
138 | /// </summary> | ||
139 | private sealed class KeyedRowCollection : KeyedCollection<string, Row> | ||
140 | { | ||
141 | /// <summary> | ||
142 | /// Initializes the <see cref="KeyedRowCollection"/> class with all rows from the specified <paramref name="table"/>. | ||
143 | /// </summary> | ||
144 | /// <param name="table">The <see cref="Table"/> containing rows to index.</param> | ||
145 | internal KeyedRowCollection(Table table) | ||
146 | { | ||
147 | if (null != table) | ||
148 | { | ||
149 | foreach (Row row in table.Rows) | ||
150 | { | ||
151 | this.Add(row); | ||
152 | } | ||
153 | } | ||
154 | } | ||
155 | |||
156 | /// <summary> | ||
157 | /// Gets the primary key for the <see cref="Row"/>. | ||
158 | /// </summary> | ||
159 | /// <param name="row">The <see cref="Row"/> to index.</param> | ||
160 | /// <returns>The primary key for the <see cref="Row"/>.</returns> | ||
161 | protected override string GetKeyForItem(Row row) | ||
162 | { | ||
163 | return row.GetPrimaryKey('/'); | ||
164 | } | ||
165 | } | ||
166 | #endif | ||
167 | } | ||
168 | } | ||
diff --git a/src/wixext/Symbols/DependencySymbolDefinitions.cs b/src/wixext/Symbols/DependencySymbolDefinitions.cs deleted file mode 100644 index 5a18ae4b..00000000 --- a/src/wixext/Symbols/DependencySymbolDefinitions.cs +++ /dev/null | |||
@@ -1,43 +0,0 @@ | |||
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 | |||
3 | namespace WixToolset.Dependency | ||
4 | { | ||
5 | using System; | ||
6 | using WixToolset.Data; | ||
7 | |||
8 | public enum DependencySymbolDefinitionType | ||
9 | { | ||
10 | WixDependency, | ||
11 | WixDependencyRef, | ||
12 | } | ||
13 | |||
14 | public static partial class DependencySymbolDefinitions | ||
15 | { | ||
16 | public static readonly Version Version = new Version("4.0.0"); | ||
17 | |||
18 | public static IntermediateSymbolDefinition ByName(string name) | ||
19 | { | ||
20 | if (!Enum.TryParse(name, out DependencySymbolDefinitionType type)) | ||
21 | { | ||
22 | return null; | ||
23 | } | ||
24 | |||
25 | return ByType(type); | ||
26 | } | ||
27 | |||
28 | public static IntermediateSymbolDefinition ByType(DependencySymbolDefinitionType type) | ||
29 | { | ||
30 | switch (type) | ||
31 | { | ||
32 | case DependencySymbolDefinitionType.WixDependency: | ||
33 | return DependencySymbolDefinitions.WixDependency; | ||
34 | |||
35 | case DependencySymbolDefinitionType.WixDependencyRef: | ||
36 | return DependencySymbolDefinitions.WixDependencyRef; | ||
37 | |||
38 | default: | ||
39 | throw new ArgumentOutOfRangeException(nameof(type)); | ||
40 | } | ||
41 | } | ||
42 | } | ||
43 | } | ||
diff --git a/src/wixext/Symbols/WixDependencyRefSymbol.cs b/src/wixext/Symbols/WixDependencyRefSymbol.cs deleted file mode 100644 index 6f2aaadf..00000000 --- a/src/wixext/Symbols/WixDependencyRefSymbol.cs +++ /dev/null | |||
@@ -1,55 +0,0 @@ | |||
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 | |||
3 | namespace WixToolset.Dependency | ||
4 | { | ||
5 | using WixToolset.Data; | ||
6 | using WixToolset.Dependency.Symbols; | ||
7 | |||
8 | public static partial class DependencySymbolDefinitions | ||
9 | { | ||
10 | public static readonly IntermediateSymbolDefinition WixDependencyRef = new IntermediateSymbolDefinition( | ||
11 | DependencySymbolDefinitionType.WixDependencyRef.ToString(), | ||
12 | new[] | ||
13 | { | ||
14 | new IntermediateFieldDefinition(nameof(WixDependencyRefSymbolFields.WixDependencyProviderRef), IntermediateFieldType.String), | ||
15 | new IntermediateFieldDefinition(nameof(WixDependencyRefSymbolFields.WixDependencyRef), IntermediateFieldType.String), | ||
16 | }, | ||
17 | typeof(WixDependencyRefSymbol)); | ||
18 | } | ||
19 | } | ||
20 | |||
21 | namespace WixToolset.Dependency.Symbols | ||
22 | { | ||
23 | using WixToolset.Data; | ||
24 | |||
25 | public enum WixDependencyRefSymbolFields | ||
26 | { | ||
27 | WixDependencyProviderRef, | ||
28 | WixDependencyRef, | ||
29 | } | ||
30 | |||
31 | public class WixDependencyRefSymbol : IntermediateSymbol | ||
32 | { | ||
33 | public WixDependencyRefSymbol() : base(DependencySymbolDefinitions.WixDependencyRef, null, null) | ||
34 | { | ||
35 | } | ||
36 | |||
37 | public WixDependencyRefSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(DependencySymbolDefinitions.WixDependencyRef, sourceLineNumber, id) | ||
38 | { | ||
39 | } | ||
40 | |||
41 | public IntermediateField this[WixDependencyRefSymbolFields index] => this.Fields[(int)index]; | ||
42 | |||
43 | public string WixDependencyProviderRef | ||
44 | { | ||
45 | get => this.Fields[(int)WixDependencyRefSymbolFields.WixDependencyProviderRef].AsString(); | ||
46 | set => this.Set((int)WixDependencyRefSymbolFields.WixDependencyProviderRef, value); | ||
47 | } | ||
48 | |||
49 | public string WixDependencyRef | ||
50 | { | ||
51 | get => this.Fields[(int)WixDependencyRefSymbolFields.WixDependencyRef].AsString(); | ||
52 | set => this.Set((int)WixDependencyRefSymbolFields.WixDependencyRef, value); | ||
53 | } | ||
54 | } | ||
55 | } \ No newline at end of file | ||
diff --git a/src/wixext/Symbols/WixDependencySymbol.cs b/src/wixext/Symbols/WixDependencySymbol.cs deleted file mode 100644 index 17c631c5..00000000 --- a/src/wixext/Symbols/WixDependencySymbol.cs +++ /dev/null | |||
@@ -1,71 +0,0 @@ | |||
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 | |||
3 | namespace WixToolset.Dependency | ||
4 | { | ||
5 | using WixToolset.Data; | ||
6 | using WixToolset.Dependency.Symbols; | ||
7 | |||
8 | public static partial class DependencySymbolDefinitions | ||
9 | { | ||
10 | public static readonly IntermediateSymbolDefinition WixDependency = new IntermediateSymbolDefinition( | ||
11 | DependencySymbolDefinitionType.WixDependency.ToString(), | ||
12 | new[] | ||
13 | { | ||
14 | new IntermediateFieldDefinition(nameof(WixDependencySymbolFields.ProviderKey), IntermediateFieldType.String), | ||
15 | new IntermediateFieldDefinition(nameof(WixDependencySymbolFields.MinVersion), IntermediateFieldType.String), | ||
16 | new IntermediateFieldDefinition(nameof(WixDependencySymbolFields.MaxVersion), IntermediateFieldType.String), | ||
17 | new IntermediateFieldDefinition(nameof(WixDependencySymbolFields.Attributes), IntermediateFieldType.Number), | ||
18 | }, | ||
19 | typeof(WixDependencySymbol)); | ||
20 | } | ||
21 | } | ||
22 | |||
23 | namespace WixToolset.Dependency.Symbols | ||
24 | { | ||
25 | using WixToolset.Data; | ||
26 | |||
27 | public enum WixDependencySymbolFields | ||
28 | { | ||
29 | ProviderKey, | ||
30 | MinVersion, | ||
31 | MaxVersion, | ||
32 | Attributes, | ||
33 | } | ||
34 | |||
35 | public class WixDependencySymbol : IntermediateSymbol | ||
36 | { | ||
37 | public WixDependencySymbol() : base(DependencySymbolDefinitions.WixDependency, null, null) | ||
38 | { | ||
39 | } | ||
40 | |||
41 | public WixDependencySymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(DependencySymbolDefinitions.WixDependency, sourceLineNumber, id) | ||
42 | { | ||
43 | } | ||
44 | |||
45 | public IntermediateField this[WixDependencySymbolFields index] => this.Fields[(int)index]; | ||
46 | |||
47 | public string ProviderKey | ||
48 | { | ||
49 | get => this.Fields[(int)WixDependencySymbolFields.ProviderKey].AsString(); | ||
50 | set => this.Set((int)WixDependencySymbolFields.ProviderKey, value); | ||
51 | } | ||
52 | |||
53 | public string MinVersion | ||
54 | { | ||
55 | get => this.Fields[(int)WixDependencySymbolFields.MinVersion].AsString(); | ||
56 | set => this.Set((int)WixDependencySymbolFields.MinVersion, value); | ||
57 | } | ||
58 | |||
59 | public string MaxVersion | ||
60 | { | ||
61 | get => this.Fields[(int)WixDependencySymbolFields.MaxVersion].AsString(); | ||
62 | set => this.Set((int)WixDependencySymbolFields.MaxVersion, value); | ||
63 | } | ||
64 | |||
65 | public int Attributes | ||
66 | { | ||
67 | get => this.Fields[(int)WixDependencySymbolFields.Attributes].AsNumber(); | ||
68 | set => this.Set((int)WixDependencySymbolFields.Attributes, value); | ||
69 | } | ||
70 | } | ||
71 | } \ No newline at end of file | ||