aboutsummaryrefslogtreecommitdiff
path: root/src/ext/Bal/wixext
diff options
context:
space:
mode:
authorRob Mensching <rob@firegiant.com>2021-05-03 15:55:48 -0700
committerRob Mensching <rob@firegiant.com>2021-05-03 15:55:48 -0700
commitba7bab476501c16e437b0aee71c1be02c3dda176 (patch)
tree814fba485c29a7dfe1adb396169e27ed641ef9a3 /src/ext/Bal/wixext
parent14987a72cc1a3493ca8f80693d273352fc314bd9 (diff)
downloadwix-ba7bab476501c16e437b0aee71c1be02c3dda176.tar.gz
wix-ba7bab476501c16e437b0aee71c1be02c3dda176.tar.bz2
wix-ba7bab476501c16e437b0aee71c1be02c3dda176.zip
Move Bal.wixext into ext
Diffstat (limited to 'src/ext/Bal/wixext')
-rw-r--r--src/ext/Bal/wixext/BalBurnBackendExtension.cs171
-rw-r--r--src/ext/Bal/wixext/BalCompiler.cs923
-rw-r--r--src/ext/Bal/wixext/BalErrors.cs61
-rw-r--r--src/ext/Bal/wixext/BalExtensionData.cs30
-rw-r--r--src/ext/Bal/wixext/BalExtensionFactory.cs18
-rw-r--r--src/ext/Bal/wixext/BalWarnings.cs31
-rw-r--r--src/ext/Bal/wixext/Symbols/BalSymbolDefinitions.cs80
-rw-r--r--src/ext/Bal/wixext/Symbols/WixBalBAFactoryAssemblySymbol.cs55
-rw-r--r--src/ext/Bal/wixext/Symbols/WixBalBAFunctionsSymbol.cs47
-rw-r--r--src/ext/Bal/wixext/Symbols/WixBalConditionSymbol.cs55
-rw-r--r--src/ext/Bal/wixext/Symbols/WixBalPackageInfoSymbol.cs55
-rw-r--r--src/ext/Bal/wixext/Symbols/WixDncOptionsSymbol.cs47
-rw-r--r--src/ext/Bal/wixext/Symbols/WixMbaPrereqInformationSymbol.cs63
-rw-r--r--src/ext/Bal/wixext/Symbols/WixStdbaOptionsSymbol.cs79
-rw-r--r--src/ext/Bal/wixext/Symbols/WixStdbaOverridableVariableSymbol.cs47
-rw-r--r--src/ext/Bal/wixext/WixToolset.Bal.wixext.csproj39
-rw-r--r--src/ext/Bal/wixext/WixToolset.Bal.wixext.nuspec26
-rw-r--r--src/ext/Bal/wixext/WixToolset.Bal.wixext.targets11
18 files changed, 1838 insertions, 0 deletions
diff --git a/src/ext/Bal/wixext/BalBurnBackendExtension.cs b/src/ext/Bal/wixext/BalBurnBackendExtension.cs
new file mode 100644
index 00000000..e8dc7a3e
--- /dev/null
+++ b/src/ext/Bal/wixext/BalBurnBackendExtension.cs
@@ -0,0 +1,171 @@
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.Bal
4{
5 using System;
6 using System.Collections.Generic;
7 using System.Linq;
8 using WixToolset.Bal.Symbols;
9 using WixToolset.Data;
10 using WixToolset.Data.Burn;
11 using WixToolset.Data.Symbols;
12 using WixToolset.Extensibility;
13
14 public class BalBurnBackendExtension : BaseBurnBackendBinderExtension
15 {
16 private static readonly IntermediateSymbolDefinition[] BurnSymbolDefinitions =
17 {
18 BalSymbolDefinitions.WixBalBAFactoryAssembly,
19 BalSymbolDefinitions.WixBalBAFunctions,
20 BalSymbolDefinitions.WixBalCondition,
21 BalSymbolDefinitions.WixBalPackageInfo,
22 BalSymbolDefinitions.WixDncOptions,
23 BalSymbolDefinitions.WixMbaPrereqInformation,
24 BalSymbolDefinitions.WixStdbaOptions,
25 BalSymbolDefinitions.WixStdbaOverridableVariable,
26 };
27
28 protected override IReadOnlyCollection<IntermediateSymbolDefinition> SymbolDefinitions => BurnSymbolDefinitions;
29
30 public override void SymbolsFinalized(IntermediateSection section)
31 {
32 base.SymbolsFinalized(section);
33
34 var baSymbol = section.Symbols.OfType<WixBootstrapperApplicationDllSymbol>().SingleOrDefault();
35 var baId = baSymbol?.Id?.Id;
36 if (null == baId)
37 {
38 return;
39 }
40
41 var isStdBA = baId.StartsWith("WixStandardBootstrapperApplication");
42 var isMBA = baId.StartsWith("WixManagedBootstrapperApplicationHost");
43 var isDNC = baId.StartsWith("WixDotNetCoreBootstrapperApplicationHost");
44 var isSCD = isDNC && this.VerifySCD(section);
45
46 if (isDNC)
47 {
48 this.FinalizeBAFactorySymbol(section);
49 }
50
51 if (isStdBA || isMBA || isDNC)
52 {
53 this.VerifyBAFunctions(section);
54 }
55
56 if (isMBA || (isDNC && !isSCD))
57 {
58 this.VerifyPrereqPackages(section, isDNC);
59 }
60 }
61
62 private void FinalizeBAFactorySymbol(IntermediateSection section)
63 {
64 var factorySymbol = section.Symbols.OfType<WixBalBAFactoryAssemblySymbol>().SingleOrDefault();
65 if (null == factorySymbol)
66 {
67 return;
68 }
69
70 var factoryPayloadSymbol = section.Symbols.OfType<WixBundlePayloadSymbol>()
71 .Where(p => p.Id.Id == factorySymbol.PayloadId)
72 .SingleOrDefault();
73 if (null == factoryPayloadSymbol)
74 {
75 return;
76 }
77
78 factorySymbol.FilePath = factoryPayloadSymbol.Name;
79 }
80
81 private void VerifyBAFunctions(IntermediateSection section)
82 {
83 WixBalBAFunctionsSymbol baFunctionsSymbol = null;
84 foreach (var symbol in section.Symbols.OfType<WixBalBAFunctionsSymbol>())
85 {
86 if (null == baFunctionsSymbol)
87 {
88 baFunctionsSymbol = symbol;
89 }
90 else
91 {
92 this.Messaging.Write(BalErrors.MultipleBAFunctions(symbol.SourceLineNumbers));
93 }
94 }
95
96 var payloadPropertiesSymbols = section.Symbols.OfType<WixBundlePayloadSymbol>().ToList();
97 if (null == baFunctionsSymbol)
98 {
99 foreach (var payloadPropertiesSymbol in payloadPropertiesSymbols)
100 {
101 if (string.Equals(payloadPropertiesSymbol.Name, "bafunctions.dll", StringComparison.OrdinalIgnoreCase) &&
102 BurnConstants.BurnUXContainerName == payloadPropertiesSymbol.ContainerRef)
103 {
104 this.Messaging.Write(BalWarnings.UnmarkedBAFunctionsDLL(payloadPropertiesSymbol.SourceLineNumbers));
105 }
106 }
107 }
108 else
109 {
110 var payloadId = baFunctionsSymbol.Id;
111 var bundlePayloadSymbol = payloadPropertiesSymbols.Single(x => payloadId == x.Id);
112 if (BurnConstants.BurnUXContainerName != bundlePayloadSymbol.ContainerRef)
113 {
114 this.Messaging.Write(BalErrors.BAFunctionsPayloadRequiredInUXContainer(baFunctionsSymbol.SourceLineNumbers));
115 }
116 }
117 }
118
119 private void VerifyPrereqPackages(IntermediateSection section, bool isDNC)
120 {
121 var prereqInfoSymbols = section.Symbols.OfType<WixMbaPrereqInformationSymbol>().ToList();
122 if (prereqInfoSymbols.Count == 0)
123 {
124 var message = isDNC ? BalErrors.MissingDNCPrereq() : BalErrors.MissingMBAPrereq();
125 this.Messaging.Write(message);
126 return;
127 }
128
129 var foundLicenseFile = false;
130 var foundLicenseUrl = false;
131
132 foreach (var prereqInfoSymbol in prereqInfoSymbols)
133 {
134 if (null != prereqInfoSymbol.LicenseFile)
135 {
136 if (foundLicenseFile || foundLicenseUrl)
137 {
138 this.Messaging.Write(BalErrors.MultiplePrereqLicenses(prereqInfoSymbol.SourceLineNumbers));
139 return;
140 }
141
142 foundLicenseFile = true;
143 }
144
145 if (null != prereqInfoSymbol.LicenseUrl)
146 {
147 if (foundLicenseFile || foundLicenseUrl)
148 {
149 this.Messaging.Write(BalErrors.MultiplePrereqLicenses(prereqInfoSymbol.SourceLineNumbers));
150 return;
151 }
152
153 foundLicenseUrl = true;
154 }
155 }
156 }
157
158 private bool VerifySCD(IntermediateSection section)
159 {
160 var isSCD = false;
161
162 var dncOptions = section.Symbols.OfType<WixDncOptionsSymbol>().SingleOrDefault();
163 if (dncOptions != null)
164 {
165 isSCD = dncOptions.SelfContainedDeployment != 0;
166 }
167
168 return isSCD;
169 }
170 }
171}
diff --git a/src/ext/Bal/wixext/BalCompiler.cs b/src/ext/Bal/wixext/BalCompiler.cs
new file mode 100644
index 00000000..267345e7
--- /dev/null
+++ b/src/ext/Bal/wixext/BalCompiler.cs
@@ -0,0 +1,923 @@
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.Bal
4{
5 using System;
6 using System.Collections.Generic;
7 using System.Xml.Linq;
8 using WixToolset.Bal.Symbols;
9 using WixToolset.Data;
10 using WixToolset.Data.Symbols;
11 using WixToolset.Extensibility;
12 using WixToolset.Extensibility.Data;
13
14 /// <summary>
15 /// The compiler for the WiX Toolset Bal Extension.
16 /// </summary>
17 public sealed class BalCompiler : BaseCompilerExtension
18 {
19 private readonly Dictionary<string, WixMbaPrereqInformationSymbol> prereqInfoSymbolsByPackageId;
20
21 private enum WixDotNetCoreBootstrapperApplicationHostTheme
22 {
23 Unknown,
24 None,
25 Standard,
26 }
27
28 private enum WixManagedBootstrapperApplicationHostTheme
29 {
30 Unknown,
31 None,
32 Standard,
33 }
34
35 private enum WixStandardBootstrapperApplicationTheme
36 {
37 Unknown,
38 HyperlinkLargeLicense,
39 HyperlinkLicense,
40 HyperlinkSidebarLicense,
41 None,
42 RtfLargeLicense,
43 RtfLicense,
44 }
45
46 /// <summary>
47 /// Instantiate a new BalCompiler.
48 /// </summary>
49 public BalCompiler()
50 {
51 this.prereqInfoSymbolsByPackageId = new Dictionary<string, WixMbaPrereqInformationSymbol>();
52 }
53
54 public override XNamespace Namespace => "http://wixtoolset.org/schemas/v4/wxs/bal";
55
56 /// <summary>
57 /// Processes an element for the Compiler.
58 /// </summary>
59 /// <param name="intermediate"></param>
60 /// <param name="section"></param>
61 /// <param name="parentElement">Parent element of element to process.</param>
62 /// <param name="element">Element to process.</param>
63 /// <param name="context">Extra information about the context in which this element is being parsed.</param>
64 public override void ParseElement(Intermediate intermediate, IntermediateSection section, XElement parentElement, XElement element, IDictionary<string, string> context)
65 {
66 switch (parentElement.Name.LocalName)
67 {
68 case "Bundle":
69 case "Fragment":
70 switch (element.Name.LocalName)
71 {
72 case "Condition":
73 this.ParseConditionElement(intermediate, section, element);
74 break;
75 case "ManagedBootstrapperApplicationPrereqInformation":
76 this.ParseMbaPrereqInfoElement(intermediate, section, element);
77 break;
78 default:
79 this.ParseHelper.UnexpectedElement(parentElement, element);
80 break;
81 }
82 break;
83 case "BootstrapperApplication":
84 switch (element.Name.LocalName)
85 {
86 case "WixStandardBootstrapperApplication":
87 this.ParseWixStandardBootstrapperApplicationElement(intermediate, section, element);
88 break;
89 case "WixManagedBootstrapperApplicationHost":
90 this.ParseWixManagedBootstrapperApplicationHostElement(intermediate, section, element);
91 break;
92 case "WixDotNetCoreBootstrapperApplicationHost":
93 this.ParseWixDotNetCoreBootstrapperApplicationHostElement(intermediate, section, element);
94 break;
95 default:
96 this.ParseHelper.UnexpectedElement(parentElement, element);
97 break;
98 }
99 break;
100 default:
101 this.ParseHelper.UnexpectedElement(parentElement, element);
102 break;
103 }
104 }
105
106 /// <summary>
107 /// Processes an attribute for the Compiler.
108 /// </summary>
109 /// <param name="sourceLineNumbers">Source line number for the parent element.</param>
110 /// <param name="parentElement">Parent element of element to process.</param>
111 /// <param name="attribute">Attribute to process.</param>
112 /// <param name="context">Extra information about the context in which this element is being parsed.</param>
113 public override void ParseAttribute(Intermediate intermediate, IntermediateSection section, XElement parentElement, XAttribute attribute, IDictionary<string, string> context)
114 {
115 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(parentElement);
116 WixMbaPrereqInformationSymbol prereqInfo;
117
118 switch (parentElement.Name.LocalName)
119 {
120 case "ExePackage":
121 case "MsiPackage":
122 case "MspPackage":
123 case "MsuPackage":
124 string packageId;
125 if (!context.TryGetValue("PackageId", out packageId) || String.IsNullOrEmpty(packageId))
126 {
127 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, parentElement.Name.LocalName, "Id", attribute.Name.LocalName));
128 }
129 else
130 {
131 switch (attribute.Name.LocalName)
132 {
133 case "DisplayInternalUICondition":
134 switch (parentElement.Name.LocalName)
135 {
136 case "MsiPackage":
137 case "MspPackage":
138 var displayInternalUICondition = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attribute);
139 section.AddSymbol(new WixBalPackageInfoSymbol(sourceLineNumbers, new Identifier(AccessModifier.Global, packageId))
140 {
141 PackageId = packageId,
142 DisplayInternalUICondition = displayInternalUICondition,
143 });
144 break;
145 default:
146 this.ParseHelper.UnexpectedAttribute(parentElement, attribute);
147 break;
148 }
149 break;
150 case "PrereqLicenseFile":
151
152 if (!this.prereqInfoSymbolsByPackageId.TryGetValue(packageId, out prereqInfo))
153 {
154 // at the time the extension attribute is parsed, the compiler might not yet have
155 // parsed the PrereqPackage attribute, so we need to get it directly from the parent element.
156 var prereqPackage = parentElement.Attribute(this.Namespace + "PrereqPackage");
157
158 if (null != prereqPackage && YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, prereqPackage))
159 {
160 prereqInfo = section.AddSymbol(new WixMbaPrereqInformationSymbol(sourceLineNumbers)
161 {
162 PackageId = packageId,
163 });
164
165 this.prereqInfoSymbolsByPackageId.Add(packageId, prereqInfo);
166 }
167 else
168 {
169 this.Messaging.Write(BalErrors.AttributeRequiresPrereqPackage(sourceLineNumbers, parentElement.Name.LocalName, "PrereqLicenseFile"));
170 break;
171 }
172 }
173
174 if (null != prereqInfo.LicenseUrl)
175 {
176 this.Messaging.Write(ErrorMessages.IllegalAttributeWithOtherAttribute(sourceLineNumbers, parentElement.Name.LocalName, "PrereqLicenseFile", "PrereqLicenseUrl"));
177 }
178 else
179 {
180 prereqInfo.LicenseFile = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attribute);
181 }
182 break;
183 case "PrereqLicenseUrl":
184
185 if (!this.prereqInfoSymbolsByPackageId.TryGetValue(packageId, out prereqInfo))
186 {
187 // at the time the extension attribute is parsed, the compiler might not yet have
188 // parsed the PrereqPackage attribute, so we need to get it directly from the parent element.
189 var prereqPackage = parentElement.Attribute(this.Namespace + "PrereqPackage");
190
191 if (null != prereqPackage && YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, prereqPackage))
192 {
193 prereqInfo = section.AddSymbol(new WixMbaPrereqInformationSymbol(sourceLineNumbers)
194 {
195 PackageId = packageId,
196 });
197
198 this.prereqInfoSymbolsByPackageId.Add(packageId, prereqInfo);
199 }
200 else
201 {
202 this.Messaging.Write(BalErrors.AttributeRequiresPrereqPackage(sourceLineNumbers, parentElement.Name.LocalName, "PrereqLicenseUrl"));
203 break;
204 }
205 }
206
207 if (null != prereqInfo.LicenseFile)
208 {
209 this.Messaging.Write(ErrorMessages.IllegalAttributeWithOtherAttribute(sourceLineNumbers, parentElement.Name.LocalName, "PrereqLicenseUrl", "PrereqLicenseFile"));
210 }
211 else
212 {
213 prereqInfo.LicenseUrl = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attribute);
214 }
215 break;
216 case "PrereqPackage":
217 if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attribute))
218 {
219 if (!this.prereqInfoSymbolsByPackageId.TryGetValue(packageId, out prereqInfo))
220 {
221 prereqInfo = section.AddSymbol(new WixMbaPrereqInformationSymbol(sourceLineNumbers)
222 {
223 PackageId = packageId,
224 });
225
226 this.prereqInfoSymbolsByPackageId.Add(packageId, prereqInfo);
227 }
228 }
229 break;
230 default:
231 this.ParseHelper.UnexpectedAttribute(parentElement, attribute);
232 break;
233 }
234 }
235 break;
236 case "Payload":
237 string payloadId;
238 if (!context.TryGetValue("Id", out payloadId) || String.IsNullOrEmpty(payloadId))
239 {
240 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, parentElement.Name.LocalName, "Id", attribute.Name.LocalName));
241 }
242 else
243 {
244 switch (attribute.Name.LocalName)
245 {
246 case "BAFactoryAssembly":
247 if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attribute))
248 {
249 // There can only be one.
250 var id = new Identifier(AccessModifier.Global, "TheBAFactoryAssembly");
251 section.AddSymbol(new WixBalBAFactoryAssemblySymbol(sourceLineNumbers, id)
252 {
253 PayloadId = payloadId,
254 });
255 }
256 break;
257 case "BAFunctions":
258 if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attribute))
259 {
260 section.AddSymbol(new WixBalBAFunctionsSymbol(sourceLineNumbers)
261 {
262 PayloadId = payloadId,
263 });
264 }
265 break;
266 default:
267 this.ParseHelper.UnexpectedAttribute(parentElement, attribute);
268 break;
269 }
270 }
271 break;
272 case "Variable":
273 // at the time the extension attribute is parsed, the compiler might not yet have
274 // parsed the Name attribute, so we need to get it directly from the parent element.
275 var variableName = parentElement.Attribute("Name");
276 if (null == variableName)
277 {
278 this.Messaging.Write(ErrorMessages.ExpectedParentWithAttribute(sourceLineNumbers, "Variable", "Overridable", "Name"));
279 }
280 else
281 {
282 switch (attribute.Name.LocalName)
283 {
284 case "Overridable":
285 if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attribute))
286 {
287 section.AddSymbol(new WixStdbaOverridableVariableSymbol(sourceLineNumbers)
288 {
289 Name = variableName.Value,
290 });
291 }
292 break;
293 default:
294 this.ParseHelper.UnexpectedAttribute(parentElement, attribute);
295 break;
296 }
297 }
298 break;
299 }
300 }
301
302 /// <summary>
303 /// Parses a Condition element for Bundles.
304 /// </summary>
305 /// <param name="node">The element to parse.</param>
306 private void ParseConditionElement(Intermediate intermediate, IntermediateSection section, XElement node)
307 {
308 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node);
309 string condition = null;
310 string message = null;
311
312 foreach (var attrib in node.Attributes())
313 {
314 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
315 {
316 switch (attrib.Name.LocalName)
317 {
318 case "Message":
319 message = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
320 break;
321 case "Condition":
322 condition = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
323 break;
324 default:
325 this.ParseHelper.UnexpectedAttribute(node, attrib);
326 break;
327 }
328 }
329 else
330 {
331 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, node, attrib);
332 }
333 }
334
335 this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, node);
336
337 // Error check the values.
338 if (String.IsNullOrEmpty(condition))
339 {
340 this.Messaging.Write(ErrorMessages.ConditionExpected(sourceLineNumbers, node.Name.LocalName));
341 }
342
343 if (null == message)
344 {
345 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Message"));
346 }
347
348 if (!this.Messaging.EncounteredError)
349 {
350 section.AddSymbol(new WixBalConditionSymbol(sourceLineNumbers)
351 {
352 Condition = condition,
353 Message = message,
354 });
355 }
356 }
357
358 /// <summary>
359 /// Parses a Condition element for Bundles.
360 /// </summary>
361 /// <param name="node">The element to parse.</param>
362 private void ParseMbaPrereqInfoElement(Intermediate intermediate, IntermediateSection section, XElement node)
363 {
364 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node);
365 string packageId = null;
366 string licenseFile = null;
367 string licenseUrl = null;
368
369 foreach (var attrib in node.Attributes())
370 {
371 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
372 {
373 switch (attrib.Name.LocalName)
374 {
375 case "LicenseFile":
376 licenseFile = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
377 break;
378 case "LicenseUrl":
379 licenseUrl = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
380 break;
381 case "PackageId":
382 packageId = this.ParseHelper.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
383 break;
384 default:
385 this.ParseHelper.UnexpectedAttribute(node, attrib);
386 break;
387 }
388 }
389 else
390 {
391 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, node, attrib);
392 }
393 }
394
395 this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, node);
396
397 if (null == packageId)
398 {
399 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "PackageId"));
400 }
401
402 if (null == licenseFile && null == licenseUrl ||
403 null != licenseFile && null != licenseUrl)
404 {
405 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "LicenseFile", "LicenseUrl", true));
406 }
407
408 if (!this.Messaging.EncounteredError)
409 {
410 section.AddSymbol(new WixMbaPrereqInformationSymbol(sourceLineNumbers)
411 {
412 PackageId = packageId,
413 LicenseFile = licenseFile,
414 LicenseUrl = licenseUrl,
415 });
416 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, SymbolDefinitions.WixBundlePackage, packageId);
417 }
418 }
419
420 /// <summary>
421 /// Parses a WixStandardBootstrapperApplication element for Bundles.
422 /// </summary>
423 /// <param name="node">The element to parse.</param>
424 private void ParseWixStandardBootstrapperApplicationElement(Intermediate intermediate, IntermediateSection section, XElement node)
425 {
426 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node);
427 string launchTarget = null;
428 string launchTargetElevatedId = null;
429 string launchArguments = null;
430 var launchHidden = YesNoType.NotSet;
431 string launchWorkingDir = null;
432 string licenseFile = null;
433 string licenseUrl = null;
434 string logoFile = null;
435 string logoSideFile = null;
436 WixStandardBootstrapperApplicationTheme? theme = null;
437 string themeFile = null;
438 string localizationFile = null;
439 var suppressOptionsUI = YesNoType.NotSet;
440 var suppressDowngradeFailure = YesNoType.NotSet;
441 var suppressRepair = YesNoType.NotSet;
442 var showVersion = YesNoType.NotSet;
443 var supportCacheOnly = YesNoType.NotSet;
444
445 foreach (var attrib in node.Attributes())
446 {
447 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
448 {
449 switch (attrib.Name.LocalName)
450 {
451 case "LaunchTarget":
452 launchTarget = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
453 break;
454 case "LaunchTargetElevatedId":
455 launchTargetElevatedId = this.ParseHelper.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
456 break;
457 case "LaunchArguments":
458 launchArguments = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
459 break;
460 case "LaunchHidden":
461 launchHidden = this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib);
462 break;
463 case "LaunchWorkingFolder":
464 launchWorkingDir = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
465 break;
466 case "LicenseFile":
467 licenseFile = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
468 break;
469 case "LicenseUrl":
470 licenseUrl = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib, EmptyRule.CanBeEmpty);
471 break;
472 case "LogoFile":
473 logoFile = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
474 break;
475 case "LogoSideFile":
476 logoSideFile = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
477 break;
478 case "ThemeFile":
479 themeFile = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
480 break;
481 case "LocalizationFile":
482 localizationFile = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
483 break;
484 case "SuppressOptionsUI":
485 suppressOptionsUI = this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib);
486 break;
487 case "SuppressDowngradeFailure":
488 suppressDowngradeFailure = this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib);
489 break;
490 case "SuppressRepair":
491 suppressRepair = this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib);
492 break;
493 case "ShowVersion":
494 showVersion = this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib);
495 break;
496 case "SupportCacheOnly":
497 supportCacheOnly = this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib);
498 break;
499 case "Theme":
500 var themeValue = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
501 switch (themeValue)
502 {
503 case "hyperlinkLargeLicense":
504 theme = WixStandardBootstrapperApplicationTheme.HyperlinkLargeLicense;
505 break;
506 case "hyperlinkLicense":
507 theme = WixStandardBootstrapperApplicationTheme.HyperlinkLicense;
508 break;
509 case "hyperlinkSidebarLicense":
510 theme = WixStandardBootstrapperApplicationTheme.HyperlinkSidebarLicense;
511 break;
512 case "none":
513 theme = WixStandardBootstrapperApplicationTheme.None;
514 break;
515 case "rtfLargeLicense":
516 theme = WixStandardBootstrapperApplicationTheme.RtfLargeLicense;
517 break;
518 case "rtfLicense":
519 theme = WixStandardBootstrapperApplicationTheme.RtfLicense;
520 break;
521 default:
522 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, "Theme", themeValue, "hyperlinkLargeLicense", "hyperlinkLicense", "hyperlinkSidebarLicense", "none", "rtfLargeLicense", "rtfLicense"));
523 theme = WixStandardBootstrapperApplicationTheme.Unknown; // set a value to prevent expected attribute error below.
524 break;
525 }
526 break;
527 default:
528 this.ParseHelper.UnexpectedAttribute(node, attrib);
529 break;
530 }
531 }
532 else
533 {
534 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, node, attrib);
535 }
536 }
537
538 this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, node);
539
540 if (!theme.HasValue)
541 {
542 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Theme"));
543 }
544
545 if (theme != WixStandardBootstrapperApplicationTheme.None && String.IsNullOrEmpty(licenseFile) && null == licenseUrl)
546 {
547 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "LicenseFile", "LicenseUrl", true));
548 }
549
550 if (!this.Messaging.EncounteredError)
551 {
552 if (!String.IsNullOrEmpty(launchTarget))
553 {
554 section.AddSymbol(new WixBundleVariableSymbol(sourceLineNumbers, new Identifier(AccessModifier.Global, "LaunchTarget"))
555 {
556 Value = launchTarget,
557 Type = WixBundleVariableType.Formatted,
558 });
559 }
560
561 if (!String.IsNullOrEmpty(launchTargetElevatedId))
562 {
563 section.AddSymbol(new WixBundleVariableSymbol(sourceLineNumbers, new Identifier(AccessModifier.Global, "LaunchTargetElevatedId"))
564 {
565 Value = launchTargetElevatedId,
566 Type = WixBundleVariableType.Formatted,
567 });
568 }
569
570 if (!String.IsNullOrEmpty(launchArguments))
571 {
572 section.AddSymbol(new WixBundleVariableSymbol(sourceLineNumbers, new Identifier(AccessModifier.Global, "LaunchArguments"))
573 {
574 Value = launchArguments,
575 Type = WixBundleVariableType.Formatted,
576 });
577 }
578
579 if (YesNoType.Yes == launchHidden)
580 {
581 section.AddSymbol(new WixBundleVariableSymbol(sourceLineNumbers, new Identifier(AccessModifier.Global, "LaunchHidden"))
582 {
583 Value = "yes",
584 Type = WixBundleVariableType.Formatted,
585 });
586 }
587
588
589 if (!String.IsNullOrEmpty(launchWorkingDir))
590 {
591 section.AddSymbol(new WixBundleVariableSymbol(sourceLineNumbers, new Identifier(AccessModifier.Global, "LaunchWorkingFolder"))
592 {
593 Value = launchWorkingDir,
594 Type = WixBundleVariableType.Formatted,
595 });
596 }
597
598 if (!String.IsNullOrEmpty(licenseFile))
599 {
600 section.AddSymbol(new WixVariableSymbol(sourceLineNumbers, new Identifier(AccessModifier.Global, "WixStdbaLicenseRtf"))
601 {
602 Value = licenseFile,
603 });
604 }
605
606 if (null != licenseUrl)
607 {
608 section.AddSymbol(new WixVariableSymbol(sourceLineNumbers, new Identifier(AccessModifier.Global, "WixStdbaLicenseUrl"))
609 {
610 Value = licenseUrl,
611 });
612 }
613
614 if (!String.IsNullOrEmpty(logoFile))
615 {
616 section.AddSymbol(new WixVariableSymbol(sourceLineNumbers, new Identifier(AccessModifier.Global, "WixStdbaLogo"))
617 {
618 Value = logoFile,
619 });
620 }
621
622 if (!String.IsNullOrEmpty(logoSideFile))
623 {
624 section.AddSymbol(new WixVariableSymbol(sourceLineNumbers, new Identifier(AccessModifier.Global, "WixStdbaLogoSide"))
625 {
626 Value = logoSideFile,
627 });
628 }
629
630 if (!String.IsNullOrEmpty(themeFile))
631 {
632 section.AddSymbol(new WixVariableSymbol(sourceLineNumbers, new Identifier(AccessModifier.Global, "WixStdbaThemeXml"))
633 {
634 Value = themeFile,
635 });
636 }
637
638 if (!String.IsNullOrEmpty(localizationFile))
639 {
640 section.AddSymbol(new WixVariableSymbol(sourceLineNumbers, new Identifier(AccessModifier.Global, "WixStdbaThemeWxl"))
641 {
642 Value = localizationFile,
643 });
644 }
645
646 if (YesNoType.Yes == suppressOptionsUI || YesNoType.Yes == suppressDowngradeFailure || YesNoType.Yes == suppressRepair || YesNoType.Yes == showVersion || YesNoType.Yes == supportCacheOnly)
647 {
648 var symbol = section.AddSymbol(new WixStdbaOptionsSymbol(sourceLineNumbers));
649 if (YesNoType.Yes == suppressOptionsUI)
650 {
651 symbol.SuppressOptionsUI = 1;
652 }
653
654 if (YesNoType.Yes == suppressDowngradeFailure)
655 {
656 symbol.SuppressDowngradeFailure = 1;
657 }
658
659 if (YesNoType.Yes == suppressRepair)
660 {
661 symbol.SuppressRepair = 1;
662 }
663
664 if (YesNoType.Yes == showVersion)
665 {
666 symbol.ShowVersion = 1;
667 }
668
669 if (YesNoType.Yes == supportCacheOnly)
670 {
671 symbol.SupportCacheOnly = 1;
672 }
673 }
674
675 var baId = "WixStandardBootstrapperApplication";
676 switch (theme)
677 {
678 case WixStandardBootstrapperApplicationTheme.HyperlinkLargeLicense:
679 baId = "WixStandardBootstrapperApplication.HyperlinkLargeLicense";
680 break;
681 case WixStandardBootstrapperApplicationTheme.HyperlinkLicense:
682 baId = "WixStandardBootstrapperApplication.HyperlinkLicense";
683 break;
684 case WixStandardBootstrapperApplicationTheme.HyperlinkSidebarLicense:
685 baId = "WixStandardBootstrapperApplication.HyperlinkSidebarLicense";
686 break;
687 case WixStandardBootstrapperApplicationTheme.RtfLargeLicense:
688 baId = "WixStandardBootstrapperApplication.RtfLargeLicense";
689 break;
690 case WixStandardBootstrapperApplicationTheme.RtfLicense:
691 baId = "WixStandardBootstrapperApplication.RtfLicense";
692 break;
693 }
694
695 this.CreateBARef(section, sourceLineNumbers, node, baId);
696 }
697 }
698
699 /// <summary>
700 /// Parses a WixManagedBootstrapperApplicationHost element for Bundles.
701 /// </summary>
702 /// <param name="node">The element to parse.</param>
703 private void ParseWixManagedBootstrapperApplicationHostElement(Intermediate intermediate, IntermediateSection section, XElement node)
704 {
705 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node);
706 string logoFile = null;
707 string themeFile = null;
708 string localizationFile = null;
709 WixManagedBootstrapperApplicationHostTheme? theme = null;
710
711 foreach (var attrib in node.Attributes())
712 {
713 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
714 {
715 switch (attrib.Name.LocalName)
716 {
717 case "LogoFile":
718 logoFile = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
719 break;
720 case "ThemeFile":
721 themeFile = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
722 break;
723 case "LocalizationFile":
724 localizationFile = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
725 break;
726 case "Theme":
727 var themeValue = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
728 switch (themeValue)
729 {
730 case "none":
731 theme = WixManagedBootstrapperApplicationHostTheme.None;
732 break;
733 case "standard":
734 theme = WixManagedBootstrapperApplicationHostTheme.Standard;
735 break;
736 default:
737 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, "Theme", themeValue, "none", "standard"));
738 theme = WixManagedBootstrapperApplicationHostTheme.Unknown;
739 break;
740 }
741 break;
742 default:
743 this.ParseHelper.UnexpectedAttribute(node, attrib);
744 break;
745 }
746 }
747 else
748 {
749 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, node, attrib);
750 }
751 }
752
753 if (!theme.HasValue)
754 {
755 theme = WixManagedBootstrapperApplicationHostTheme.Standard;
756 }
757
758 this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, node);
759
760 if (!this.Messaging.EncounteredError)
761 {
762 if (!String.IsNullOrEmpty(logoFile))
763 {
764 section.AddSymbol(new WixVariableSymbol(sourceLineNumbers, new Identifier(AccessModifier.Global, "PreqbaLogo"))
765 {
766 Value = logoFile,
767 });
768 }
769
770 if (!String.IsNullOrEmpty(themeFile))
771 {
772 section.AddSymbol(new WixVariableSymbol(sourceLineNumbers, new Identifier(AccessModifier.Global, "PreqbaThemeXml"))
773 {
774 Value = themeFile,
775 });
776 }
777
778 if (!String.IsNullOrEmpty(localizationFile))
779 {
780 section.AddSymbol(new WixVariableSymbol(sourceLineNumbers, new Identifier(AccessModifier.Global, "PreqbaThemeWxl"))
781 {
782 Value = localizationFile,
783 });
784 }
785
786 var baId = "WixManagedBootstrapperApplicationHost";
787 switch (theme)
788 {
789 case WixManagedBootstrapperApplicationHostTheme.Standard:
790 baId = "WixManagedBootstrapperApplicationHost.Standard";
791 break;
792 }
793
794 this.CreateBARef(section, sourceLineNumbers, node, baId);
795 }
796 }
797
798 /// <summary>
799 /// Parses a WixDotNetCoreBootstrapperApplication element for Bundles.
800 /// </summary>
801 /// <param name="node">The element to parse.</param>
802 private void ParseWixDotNetCoreBootstrapperApplicationHostElement(Intermediate intermediate, IntermediateSection section, XElement node)
803 {
804 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node);
805 string logoFile = null;
806 string themeFile = null;
807 string localizationFile = null;
808 var selfContainedDeployment = YesNoType.NotSet;
809 WixDotNetCoreBootstrapperApplicationHostTheme? theme = null;
810
811 foreach (var attrib in node.Attributes())
812 {
813 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
814 {
815 switch (attrib.Name.LocalName)
816 {
817 case "LogoFile":
818 logoFile = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
819 break;
820 case "ThemeFile":
821 themeFile = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
822 break;
823 case "LocalizationFile":
824 localizationFile = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
825 break;
826 case "SelfContainedDeployment":
827 selfContainedDeployment = this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib);
828 break;
829 case "Theme":
830 var themeValue = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
831 switch (themeValue)
832 {
833 case "none":
834 theme = WixDotNetCoreBootstrapperApplicationHostTheme.None;
835 break;
836 case "standard":
837 theme = WixDotNetCoreBootstrapperApplicationHostTheme.Standard;
838 break;
839 default:
840 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, "Theme", themeValue, "none", "standard"));
841 theme = WixDotNetCoreBootstrapperApplicationHostTheme.Unknown;
842 break;
843 }
844 break;
845 default:
846 this.ParseHelper.UnexpectedAttribute(node, attrib);
847 break;
848 }
849 }
850 else
851 {
852 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, node, attrib);
853 }
854 }
855
856 if (!theme.HasValue)
857 {
858 theme = WixDotNetCoreBootstrapperApplicationHostTheme.Standard;
859 }
860
861 this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, node);
862
863 if (!this.Messaging.EncounteredError)
864 {
865 if (!String.IsNullOrEmpty(logoFile))
866 {
867 section.AddSymbol(new WixVariableSymbol(sourceLineNumbers, new Identifier(AccessModifier.Global, "DncPreqbaLogo"))
868 {
869 Value = logoFile,
870 });
871 }
872
873 if (!String.IsNullOrEmpty(themeFile))
874 {
875 section.AddSymbol(new WixVariableSymbol(sourceLineNumbers, new Identifier(AccessModifier.Global, "DncPreqbaThemeXml"))
876 {
877 Value = themeFile,
878 });
879 }
880
881 if (!String.IsNullOrEmpty(localizationFile))
882 {
883 section.AddSymbol(new WixVariableSymbol(sourceLineNumbers, new Identifier(AccessModifier.Global, "DncPreqbaThemeWxl"))
884 {
885 Value = localizationFile,
886 });
887 }
888
889 if (YesNoType.Yes == selfContainedDeployment)
890 {
891 section.AddSymbol(new WixDncOptionsSymbol(sourceLineNumbers)
892 {
893 SelfContainedDeployment = 1,
894 });
895 }
896
897 var baId = "WixDotNetCoreBootstrapperApplicationHost";
898 switch (theme)
899 {
900 case WixDotNetCoreBootstrapperApplicationHostTheme.Standard:
901 baId = "WixDotNetCoreBootstrapperApplicationHost.Standard";
902 break;
903 }
904
905 this.CreateBARef(section, sourceLineNumbers, node, baId);
906 }
907 }
908
909 private void CreateBARef(IntermediateSection section, SourceLineNumber sourceLineNumbers, XElement node, string name)
910 {
911 var id = this.ParseHelper.CreateIdentifierValueFromPlatform(name, this.Context.Platform, BurnPlatforms.X86 | BurnPlatforms.X64 | BurnPlatforms.ARM64);
912 if (id == null)
913 {
914 this.Messaging.Write(ErrorMessages.UnsupportedPlatformForElement(sourceLineNumbers, this.Context.Platform.ToString(), node.Name.LocalName));
915 }
916
917 if (!this.Messaging.EncounteredError)
918 {
919 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, SymbolDefinitions.WixBootstrapperApplication, id);
920 }
921 }
922 }
923}
diff --git a/src/ext/Bal/wixext/BalErrors.cs b/src/ext/Bal/wixext/BalErrors.cs
new file mode 100644
index 00000000..bc0186c1
--- /dev/null
+++ b/src/ext/Bal/wixext/BalErrors.cs
@@ -0,0 +1,61 @@
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.Bal
4{
5 using System;
6 using System.Resources;
7 using WixToolset.Data;
8
9 public static class BalErrors
10 {
11 public static Message AttributeRequiresPrereqPackage(SourceLineNumber sourceLineNumbers, string elementName, string attributeName)
12 {
13 return Message(sourceLineNumbers, Ids.AttributeRequiresPrereqPackage, "When the {0}/@{1} attribute is specified, the {0}/@PrereqPackage attribute must be set to \"yes\".", elementName, attributeName);
14 }
15
16 public static Message BAFunctionsPayloadRequiredInUXContainer(SourceLineNumber sourceLineNumbers)
17 {
18 return Message(sourceLineNumbers, Ids.BAFunctionsPayloadRequiredInUXContainer, "The BAFunctions DLL Payload element must be located inside the BootstrapperApplication container.");
19 }
20
21 public static Message MissingDNCPrereq()
22 {
23 return Message(null, Ids.MissingDNCPrereq, "There must be at least one PrereqPackage when using the DotNetCoreBootstrapperApplicationHost with SelfContainedDeployment set to \"no\".");
24 }
25
26 public static Message MissingMBAPrereq()
27 {
28 return Message(null, Ids.MissingMBAPrereq, "There must be at least one PrereqPackage when using the ManagedBootstrapperApplicationHost.\nThis is typically done by using the WixNetFxExtension and referencing one of the NetFxAsPrereq package groups.");
29 }
30
31 public static Message MultipleBAFunctions(SourceLineNumber sourceLineNumbers)
32 {
33 return Message(sourceLineNumbers, Ids.MultipleBAFunctions, "WixStandardBootstrapperApplication doesn't support multiple BAFunctions DLLs.");
34 }
35
36 public static Message MultiplePrereqLicenses(SourceLineNumber sourceLineNumbers)
37 {
38 return Message(sourceLineNumbers, Ids.MultiplePrereqLicenses, "There may only be one package in the bundle that has either the PrereqLicenseFile attribute or the PrereqLicenseUrl attribute.");
39 }
40
41 private static Message Message(SourceLineNumber sourceLineNumber, Ids id, string format, params object[] args)
42 {
43 return new Message(sourceLineNumber, MessageLevel.Error, (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.Error, (int)id, resourceManager, resourceName, args);
49 }
50
51 public enum Ids
52 {
53 AttributeRequiresPrereqPackage = 6801,
54 MissingMBAPrereq = 6802,
55 MultiplePrereqLicenses = 6803,
56 MultipleBAFunctions = 6804,
57 BAFunctionsPayloadRequiredInUXContainer = 6805,
58 MissingDNCPrereq = 6806,
59 }
60 }
61}
diff --git a/src/ext/Bal/wixext/BalExtensionData.cs b/src/ext/Bal/wixext/BalExtensionData.cs
new file mode 100644
index 00000000..55daf005
--- /dev/null
+++ b/src/ext/Bal/wixext/BalExtensionData.cs
@@ -0,0 +1,30 @@
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.Bal
4{
5 using WixToolset.Data;
6 using WixToolset.Extensibility;
7
8 /// <summary>
9 /// The WiX Toolset Bal Extension.
10 /// </summary>
11 public sealed class BalExtensionData : BaseExtensionData
12 {
13 /// <summary>
14 /// Gets the default culture.
15 /// </summary>
16 /// <value>The default culture.</value>
17 public override string DefaultCulture => "en-US";
18
19 public override bool TryGetSymbolDefinitionByName(string name, out IntermediateSymbolDefinition symbolDefinition)
20 {
21 symbolDefinition = BalSymbolDefinitions.ByName(name);
22 return symbolDefinition != null;
23 }
24
25 public override Intermediate GetLibrary(ISymbolDefinitionCreator symbolDefinitions)
26 {
27 return Intermediate.Load(typeof(BalExtensionData).Assembly, "WixToolset.Bal.bal.wixlib", symbolDefinitions);
28 }
29 }
30}
diff --git a/src/ext/Bal/wixext/BalExtensionFactory.cs b/src/ext/Bal/wixext/BalExtensionFactory.cs
new file mode 100644
index 00000000..0bfb6c5f
--- /dev/null
+++ b/src/ext/Bal/wixext/BalExtensionFactory.cs
@@ -0,0 +1,18 @@
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.Bal
4{
5 using System;
6 using System.Collections.Generic;
7 using WixToolset.Extensibility;
8
9 public class BalExtensionFactory : BaseExtensionFactory
10 {
11 protected override IReadOnlyCollection<Type> ExtensionTypes => new[]
12 {
13 typeof(BalCompiler),
14 typeof(BalExtensionData),
15 typeof(BalBurnBackendExtension),
16 };
17 }
18}
diff --git a/src/ext/Bal/wixext/BalWarnings.cs b/src/ext/Bal/wixext/BalWarnings.cs
new file mode 100644
index 00000000..18b25062
--- /dev/null
+++ b/src/ext/Bal/wixext/BalWarnings.cs
@@ -0,0 +1,31 @@
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.Bal
4{
5 using System;
6 using System.Resources;
7 using WixToolset.Data;
8
9 public static class BalWarnings
10 {
11 public static Message UnmarkedBAFunctionsDLL(SourceLineNumber sourceLineNumbers)
12 {
13 return Message(sourceLineNumbers, Ids.UnmarkedBAFunctionsDLL, "WixStandardBootstrapperApplication doesn't automatically load BAFunctions.dll. Use the bal:BAFunctions attribute to indicate that it should be loaded.");
14 }
15
16 private static Message Message(SourceLineNumber sourceLineNumber, Ids id, string format, params object[] args)
17 {
18 return new Message(sourceLineNumber, MessageLevel.Warning, (int)id, format, args);
19 }
20
21 private static Message Message(SourceLineNumber sourceLineNumber, Ids id, ResourceManager resourceManager, string resourceName, params object[] args)
22 {
23 return new Message(sourceLineNumber, MessageLevel.Warning, (int)id, resourceManager, resourceName, args);
24 }
25
26 public enum Ids
27 {
28 UnmarkedBAFunctionsDLL = 6501,
29 }
30 }
31}
diff --git a/src/ext/Bal/wixext/Symbols/BalSymbolDefinitions.cs b/src/ext/Bal/wixext/Symbols/BalSymbolDefinitions.cs
new file mode 100644
index 00000000..90865621
--- /dev/null
+++ b/src/ext/Bal/wixext/Symbols/BalSymbolDefinitions.cs
@@ -0,0 +1,80 @@
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.Bal
4{
5 using System;
6 using WixToolset.Data;
7 using WixToolset.Data.Burn;
8
9 public enum BalSymbolDefinitionType
10 {
11 WixBalBAFactoryAssembly,
12 WixBalBAFunctions,
13 WixBalCondition,
14 WixBalPackageInfo,
15 WixDncOptions,
16 WixMbaPrereqInformation,
17 WixStdbaOptions,
18 WixStdbaOverridableVariable,
19 }
20
21 public static partial class BalSymbolDefinitions
22 {
23 public static readonly Version Version = new Version("4.0.0");
24
25 public static IntermediateSymbolDefinition ByName(string name)
26 {
27 if (!Enum.TryParse(name, out BalSymbolDefinitionType type))
28 {
29 return null;
30 }
31
32 return ByType(type);
33 }
34
35 public static IntermediateSymbolDefinition ByType(BalSymbolDefinitionType type)
36 {
37 switch (type)
38 {
39 case BalSymbolDefinitionType.WixBalBAFactoryAssembly:
40 return BalSymbolDefinitions.WixBalBAFactoryAssembly;
41
42 case BalSymbolDefinitionType.WixBalBAFunctions:
43 return BalSymbolDefinitions.WixBalBAFunctions;
44
45 case BalSymbolDefinitionType.WixBalCondition:
46 return BalSymbolDefinitions.WixBalCondition;
47
48 case BalSymbolDefinitionType.WixBalPackageInfo:
49 return BalSymbolDefinitions.WixBalPackageInfo;
50
51 case BalSymbolDefinitionType.WixDncOptions:
52 return BalSymbolDefinitions.WixDncOptions;
53
54 case BalSymbolDefinitionType.WixMbaPrereqInformation:
55 return BalSymbolDefinitions.WixMbaPrereqInformation;
56
57 case BalSymbolDefinitionType.WixStdbaOptions:
58 return BalSymbolDefinitions.WixStdbaOptions;
59
60 case BalSymbolDefinitionType.WixStdbaOverridableVariable:
61 return BalSymbolDefinitions.WixStdbaOverridableVariable;
62
63 default:
64 throw new ArgumentOutOfRangeException(nameof(type));
65 }
66 }
67
68 static BalSymbolDefinitions()
69 {
70 WixBalBAFactoryAssembly.AddTag(BurnConstants.BootstrapperApplicationDataSymbolDefinitionTag);
71 WixBalBAFunctions.AddTag(BurnConstants.BootstrapperApplicationDataSymbolDefinitionTag);
72 WixBalCondition.AddTag(BurnConstants.BootstrapperApplicationDataSymbolDefinitionTag);
73 WixBalPackageInfo.AddTag(BurnConstants.BootstrapperApplicationDataSymbolDefinitionTag);
74 WixDncOptions.AddTag(BurnConstants.BootstrapperApplicationDataSymbolDefinitionTag);
75 WixMbaPrereqInformation.AddTag(BurnConstants.BootstrapperApplicationDataSymbolDefinitionTag);
76 WixStdbaOptions.AddTag(BurnConstants.BootstrapperApplicationDataSymbolDefinitionTag);
77 WixStdbaOverridableVariable.AddTag(BurnConstants.BootstrapperApplicationDataSymbolDefinitionTag);
78 }
79 }
80}
diff --git a/src/ext/Bal/wixext/Symbols/WixBalBAFactoryAssemblySymbol.cs b/src/ext/Bal/wixext/Symbols/WixBalBAFactoryAssemblySymbol.cs
new file mode 100644
index 00000000..52042e4c
--- /dev/null
+++ b/src/ext/Bal/wixext/Symbols/WixBalBAFactoryAssemblySymbol.cs
@@ -0,0 +1,55 @@
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.Bal
4{
5 using WixToolset.Data;
6 using WixToolset.Bal.Symbols;
7
8 public static partial class BalSymbolDefinitions
9 {
10 public static readonly IntermediateSymbolDefinition WixBalBAFactoryAssembly = new IntermediateSymbolDefinition(
11 BalSymbolDefinitionType.WixBalBAFactoryAssembly.ToString(),
12 new[]
13 {
14 new IntermediateFieldDefinition(nameof(WixBalBAFactorySymbolFields.PayloadId), IntermediateFieldType.String),
15 new IntermediateFieldDefinition(nameof(WixBalBAFactorySymbolFields.FilePath), IntermediateFieldType.String),
16 },
17 typeof(WixBalBAFactoryAssemblySymbol));
18 }
19}
20
21namespace WixToolset.Bal.Symbols
22{
23 using WixToolset.Data;
24
25 public enum WixBalBAFactorySymbolFields
26 {
27 PayloadId,
28 FilePath,
29 }
30
31 public class WixBalBAFactoryAssemblySymbol : IntermediateSymbol
32 {
33 public WixBalBAFactoryAssemblySymbol() : base(BalSymbolDefinitions.WixBalBAFactoryAssembly, null, null)
34 {
35 }
36
37 public WixBalBAFactoryAssemblySymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(BalSymbolDefinitions.WixBalBAFactoryAssembly, sourceLineNumber, id)
38 {
39 }
40
41 public IntermediateField this[WixBalBAFactorySymbolFields index] => this.Fields[(int)index];
42
43 public string PayloadId
44 {
45 get => this.Fields[(int)WixBalBAFactorySymbolFields.PayloadId].AsString();
46 set => this.Set((int)WixBalBAFactorySymbolFields.PayloadId, value);
47 }
48
49 public string FilePath
50 {
51 get => this.Fields[(int)WixBalBAFactorySymbolFields.FilePath].AsString();
52 set => this.Set((int)WixBalBAFactorySymbolFields.FilePath, value);
53 }
54 }
55} \ No newline at end of file
diff --git a/src/ext/Bal/wixext/Symbols/WixBalBAFunctionsSymbol.cs b/src/ext/Bal/wixext/Symbols/WixBalBAFunctionsSymbol.cs
new file mode 100644
index 00000000..19c7602d
--- /dev/null
+++ b/src/ext/Bal/wixext/Symbols/WixBalBAFunctionsSymbol.cs
@@ -0,0 +1,47 @@
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.Bal
4{
5 using WixToolset.Data;
6 using WixToolset.Bal.Symbols;
7
8 public static partial class BalSymbolDefinitions
9 {
10 public static readonly IntermediateSymbolDefinition WixBalBAFunctions = new IntermediateSymbolDefinition(
11 BalSymbolDefinitionType.WixBalBAFunctions.ToString(),
12 new[]
13 {
14 new IntermediateFieldDefinition(nameof(WixBalBAFunctionsSymbolFields.PayloadId), IntermediateFieldType.String),
15 },
16 typeof(WixBalBAFunctionsSymbol));
17 }
18}
19
20namespace WixToolset.Bal.Symbols
21{
22 using WixToolset.Data;
23
24 public enum WixBalBAFunctionsSymbolFields
25 {
26 PayloadId,
27 }
28
29 public class WixBalBAFunctionsSymbol : IntermediateSymbol
30 {
31 public WixBalBAFunctionsSymbol() : base(BalSymbolDefinitions.WixBalBAFunctions, null, null)
32 {
33 }
34
35 public WixBalBAFunctionsSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(BalSymbolDefinitions.WixBalBAFunctions, sourceLineNumber, id)
36 {
37 }
38
39 public IntermediateField this[WixBalBAFunctionsSymbolFields index] => this.Fields[(int)index];
40
41 public string PayloadId
42 {
43 get => this.Fields[(int)WixBalBAFunctionsSymbolFields.PayloadId].AsString();
44 set => this.Set((int)WixBalBAFunctionsSymbolFields.PayloadId, value);
45 }
46 }
47} \ No newline at end of file
diff --git a/src/ext/Bal/wixext/Symbols/WixBalConditionSymbol.cs b/src/ext/Bal/wixext/Symbols/WixBalConditionSymbol.cs
new file mode 100644
index 00000000..c2527fbc
--- /dev/null
+++ b/src/ext/Bal/wixext/Symbols/WixBalConditionSymbol.cs
@@ -0,0 +1,55 @@
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.Bal
4{
5 using WixToolset.Data;
6 using WixToolset.Bal.Symbols;
7
8 public static partial class BalSymbolDefinitions
9 {
10 public static readonly IntermediateSymbolDefinition WixBalCondition = new IntermediateSymbolDefinition(
11 BalSymbolDefinitionType.WixBalCondition.ToString(),
12 new[]
13 {
14 new IntermediateFieldDefinition(nameof(WixBalConditionSymbolFields.Condition), IntermediateFieldType.String),
15 new IntermediateFieldDefinition(nameof(WixBalConditionSymbolFields.Message), IntermediateFieldType.String),
16 },
17 typeof(WixBalConditionSymbol));
18 }
19}
20
21namespace WixToolset.Bal.Symbols
22{
23 using WixToolset.Data;
24
25 public enum WixBalConditionSymbolFields
26 {
27 Condition,
28 Message,
29 }
30
31 public class WixBalConditionSymbol : IntermediateSymbol
32 {
33 public WixBalConditionSymbol() : base(BalSymbolDefinitions.WixBalCondition, null, null)
34 {
35 }
36
37 public WixBalConditionSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(BalSymbolDefinitions.WixBalCondition, sourceLineNumber, id)
38 {
39 }
40
41 public IntermediateField this[WixBalConditionSymbolFields index] => this.Fields[(int)index];
42
43 public string Condition
44 {
45 get => this.Fields[(int)WixBalConditionSymbolFields.Condition].AsString();
46 set => this.Set((int)WixBalConditionSymbolFields.Condition, value);
47 }
48
49 public string Message
50 {
51 get => this.Fields[(int)WixBalConditionSymbolFields.Message].AsString();
52 set => this.Set((int)WixBalConditionSymbolFields.Message, value);
53 }
54 }
55} \ No newline at end of file
diff --git a/src/ext/Bal/wixext/Symbols/WixBalPackageInfoSymbol.cs b/src/ext/Bal/wixext/Symbols/WixBalPackageInfoSymbol.cs
new file mode 100644
index 00000000..b09cb191
--- /dev/null
+++ b/src/ext/Bal/wixext/Symbols/WixBalPackageInfoSymbol.cs
@@ -0,0 +1,55 @@
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.Bal
4{
5 using WixToolset.Data;
6 using WixToolset.Bal.Symbols;
7
8 public static partial class BalSymbolDefinitions
9 {
10 public static readonly IntermediateSymbolDefinition WixBalPackageInfo = new IntermediateSymbolDefinition(
11 BalSymbolDefinitionType.WixBalPackageInfo.ToString(),
12 new[]
13 {
14 new IntermediateFieldDefinition(nameof(WixBalPackageInfoSymbolFields.PackageId), IntermediateFieldType.String),
15 new IntermediateFieldDefinition(nameof(WixBalPackageInfoSymbolFields.DisplayInternalUICondition), IntermediateFieldType.String),
16 },
17 typeof(WixBalPackageInfoSymbol));
18 }
19}
20
21namespace WixToolset.Bal.Symbols
22{
23 using WixToolset.Data;
24
25 public enum WixBalPackageInfoSymbolFields
26 {
27 PackageId,
28 DisplayInternalUICondition,
29 }
30
31 public class WixBalPackageInfoSymbol : IntermediateSymbol
32 {
33 public WixBalPackageInfoSymbol() : base(BalSymbolDefinitions.WixBalPackageInfo, null, null)
34 {
35 }
36
37 public WixBalPackageInfoSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(BalSymbolDefinitions.WixBalPackageInfo, sourceLineNumber, id)
38 {
39 }
40
41 public IntermediateField this[WixBalPackageInfoSymbolFields index] => this.Fields[(int)index];
42
43 public string PackageId
44 {
45 get => this.Fields[(int)WixBalPackageInfoSymbolFields.PackageId].AsString();
46 set => this.Set((int)WixBalPackageInfoSymbolFields.PackageId, value);
47 }
48
49 public string DisplayInternalUICondition
50 {
51 get => this.Fields[(int)WixBalPackageInfoSymbolFields.DisplayInternalUICondition].AsString();
52 set => this.Set((int)WixBalPackageInfoSymbolFields.DisplayInternalUICondition, value);
53 }
54 }
55}
diff --git a/src/ext/Bal/wixext/Symbols/WixDncOptionsSymbol.cs b/src/ext/Bal/wixext/Symbols/WixDncOptionsSymbol.cs
new file mode 100644
index 00000000..b9a41c21
--- /dev/null
+++ b/src/ext/Bal/wixext/Symbols/WixDncOptionsSymbol.cs
@@ -0,0 +1,47 @@
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.Bal
4{
5 using WixToolset.Data;
6 using WixToolset.Bal.Symbols;
7
8 public static partial class BalSymbolDefinitions
9 {
10 public static readonly IntermediateSymbolDefinition WixDncOptions = new IntermediateSymbolDefinition(
11 BalSymbolDefinitionType.WixDncOptions.ToString(),
12 new[]
13 {
14 new IntermediateFieldDefinition(nameof(WixDncOptionsSymbolFields.SelfContainedDeployment), IntermediateFieldType.Number),
15 },
16 typeof(WixDncOptionsSymbol));
17 }
18}
19
20namespace WixToolset.Bal.Symbols
21{
22 using WixToolset.Data;
23
24 public enum WixDncOptionsSymbolFields
25 {
26 SelfContainedDeployment,
27 }
28
29 public class WixDncOptionsSymbol : IntermediateSymbol
30 {
31 public WixDncOptionsSymbol() : base(BalSymbolDefinitions.WixDncOptions, null, null)
32 {
33 }
34
35 public WixDncOptionsSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(BalSymbolDefinitions.WixDncOptions, sourceLineNumber, id)
36 {
37 }
38
39 public IntermediateField this[WixDncOptionsSymbolFields index] => this.Fields[(int)index];
40
41 public int SelfContainedDeployment
42 {
43 get => this.Fields[(int)WixDncOptionsSymbolFields.SelfContainedDeployment].AsNumber();
44 set => this.Set((int)WixDncOptionsSymbolFields.SelfContainedDeployment, value);
45 }
46 }
47} \ No newline at end of file
diff --git a/src/ext/Bal/wixext/Symbols/WixMbaPrereqInformationSymbol.cs b/src/ext/Bal/wixext/Symbols/WixMbaPrereqInformationSymbol.cs
new file mode 100644
index 00000000..e4d78da0
--- /dev/null
+++ b/src/ext/Bal/wixext/Symbols/WixMbaPrereqInformationSymbol.cs
@@ -0,0 +1,63 @@
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.Bal
4{
5 using WixToolset.Data;
6 using WixToolset.Bal.Symbols;
7
8 public static partial class BalSymbolDefinitions
9 {
10 public static readonly IntermediateSymbolDefinition WixMbaPrereqInformation = new IntermediateSymbolDefinition(
11 BalSymbolDefinitionType.WixMbaPrereqInformation.ToString(),
12 new[]
13 {
14 new IntermediateFieldDefinition(nameof(WixMbaPrereqInformationSymbolFields.PackageId), IntermediateFieldType.String),
15 new IntermediateFieldDefinition(nameof(WixMbaPrereqInformationSymbolFields.LicenseFile), IntermediateFieldType.String),
16 new IntermediateFieldDefinition(nameof(WixMbaPrereqInformationSymbolFields.LicenseUrl), IntermediateFieldType.String),
17 },
18 typeof(WixMbaPrereqInformationSymbol));
19 }
20}
21
22namespace WixToolset.Bal.Symbols
23{
24 using WixToolset.Data;
25
26 public enum WixMbaPrereqInformationSymbolFields
27 {
28 PackageId,
29 LicenseFile,
30 LicenseUrl,
31 }
32
33 public class WixMbaPrereqInformationSymbol : IntermediateSymbol
34 {
35 public WixMbaPrereqInformationSymbol() : base(BalSymbolDefinitions.WixMbaPrereqInformation, null, null)
36 {
37 }
38
39 public WixMbaPrereqInformationSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(BalSymbolDefinitions.WixMbaPrereqInformation, sourceLineNumber, id)
40 {
41 }
42
43 public IntermediateField this[WixMbaPrereqInformationSymbolFields index] => this.Fields[(int)index];
44
45 public string PackageId
46 {
47 get => this.Fields[(int)WixMbaPrereqInformationSymbolFields.PackageId].AsString();
48 set => this.Set((int)WixMbaPrereqInformationSymbolFields.PackageId, value);
49 }
50
51 public string LicenseFile
52 {
53 get => this.Fields[(int)WixMbaPrereqInformationSymbolFields.LicenseFile].AsString();
54 set => this.Set((int)WixMbaPrereqInformationSymbolFields.LicenseFile, value);
55 }
56
57 public string LicenseUrl
58 {
59 get => this.Fields[(int)WixMbaPrereqInformationSymbolFields.LicenseUrl].AsString();
60 set => this.Set((int)WixMbaPrereqInformationSymbolFields.LicenseUrl, value);
61 }
62 }
63} \ No newline at end of file
diff --git a/src/ext/Bal/wixext/Symbols/WixStdbaOptionsSymbol.cs b/src/ext/Bal/wixext/Symbols/WixStdbaOptionsSymbol.cs
new file mode 100644
index 00000000..cb2694da
--- /dev/null
+++ b/src/ext/Bal/wixext/Symbols/WixStdbaOptionsSymbol.cs
@@ -0,0 +1,79 @@
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.Bal
4{
5 using WixToolset.Data;
6 using WixToolset.Bal.Symbols;
7
8 public static partial class BalSymbolDefinitions
9 {
10 public static readonly IntermediateSymbolDefinition WixStdbaOptions = new IntermediateSymbolDefinition(
11 BalSymbolDefinitionType.WixStdbaOptions.ToString(),
12 new[]
13 {
14 new IntermediateFieldDefinition(nameof(WixStdbaOptionsSymbolFields.SuppressOptionsUI), IntermediateFieldType.Number),
15 new IntermediateFieldDefinition(nameof(WixStdbaOptionsSymbolFields.SuppressDowngradeFailure), IntermediateFieldType.Number),
16 new IntermediateFieldDefinition(nameof(WixStdbaOptionsSymbolFields.SuppressRepair), IntermediateFieldType.Number),
17 new IntermediateFieldDefinition(nameof(WixStdbaOptionsSymbolFields.ShowVersion), IntermediateFieldType.Number),
18 new IntermediateFieldDefinition(nameof(WixStdbaOptionsSymbolFields.SupportCacheOnly), IntermediateFieldType.Number),
19 },
20 typeof(WixStdbaOptionsSymbol));
21 }
22}
23
24namespace WixToolset.Bal.Symbols
25{
26 using WixToolset.Data;
27
28 public enum WixStdbaOptionsSymbolFields
29 {
30 SuppressOptionsUI,
31 SuppressDowngradeFailure,
32 SuppressRepair,
33 ShowVersion,
34 SupportCacheOnly,
35 }
36
37 public class WixStdbaOptionsSymbol : IntermediateSymbol
38 {
39 public WixStdbaOptionsSymbol() : base(BalSymbolDefinitions.WixStdbaOptions, null, null)
40 {
41 }
42
43 public WixStdbaOptionsSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(BalSymbolDefinitions.WixStdbaOptions, sourceLineNumber, id)
44 {
45 }
46
47 public IntermediateField this[WixStdbaOptionsSymbolFields index] => this.Fields[(int)index];
48
49 public int SuppressOptionsUI
50 {
51 get => this.Fields[(int)WixStdbaOptionsSymbolFields.SuppressOptionsUI].AsNumber();
52 set => this.Set((int)WixStdbaOptionsSymbolFields.SuppressOptionsUI, value);
53 }
54
55 public int SuppressDowngradeFailure
56 {
57 get => this.Fields[(int)WixStdbaOptionsSymbolFields.SuppressDowngradeFailure].AsNumber();
58 set => this.Set((int)WixStdbaOptionsSymbolFields.SuppressDowngradeFailure, value);
59 }
60
61 public int SuppressRepair
62 {
63 get => this.Fields[(int)WixStdbaOptionsSymbolFields.SuppressRepair].AsNumber();
64 set => this.Set((int)WixStdbaOptionsSymbolFields.SuppressRepair, value);
65 }
66
67 public int ShowVersion
68 {
69 get => this.Fields[(int)WixStdbaOptionsSymbolFields.ShowVersion].AsNumber();
70 set => this.Set((int)WixStdbaOptionsSymbolFields.ShowVersion, value);
71 }
72
73 public int SupportCacheOnly
74 {
75 get => this.Fields[(int)WixStdbaOptionsSymbolFields.SupportCacheOnly].AsNumber();
76 set => this.Set((int)WixStdbaOptionsSymbolFields.SupportCacheOnly, value);
77 }
78 }
79} \ No newline at end of file
diff --git a/src/ext/Bal/wixext/Symbols/WixStdbaOverridableVariableSymbol.cs b/src/ext/Bal/wixext/Symbols/WixStdbaOverridableVariableSymbol.cs
new file mode 100644
index 00000000..1d84d1aa
--- /dev/null
+++ b/src/ext/Bal/wixext/Symbols/WixStdbaOverridableVariableSymbol.cs
@@ -0,0 +1,47 @@
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.Bal
4{
5 using WixToolset.Data;
6 using WixToolset.Bal.Symbols;
7
8 public static partial class BalSymbolDefinitions
9 {
10 public static readonly IntermediateSymbolDefinition WixStdbaOverridableVariable = new IntermediateSymbolDefinition(
11 BalSymbolDefinitionType.WixStdbaOverridableVariable.ToString(),
12 new[]
13 {
14 new IntermediateFieldDefinition(nameof(WixStdbaOverridableVariableSymbolFields.Name), IntermediateFieldType.String),
15 },
16 typeof(WixStdbaOverridableVariableSymbol));
17 }
18}
19
20namespace WixToolset.Bal.Symbols
21{
22 using WixToolset.Data;
23
24 public enum WixStdbaOverridableVariableSymbolFields
25 {
26 Name,
27 }
28
29 public class WixStdbaOverridableVariableSymbol : IntermediateSymbol
30 {
31 public WixStdbaOverridableVariableSymbol() : base(BalSymbolDefinitions.WixStdbaOverridableVariable, null, null)
32 {
33 }
34
35 public WixStdbaOverridableVariableSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(BalSymbolDefinitions.WixStdbaOverridableVariable, sourceLineNumber, id)
36 {
37 }
38
39 public IntermediateField this[WixStdbaOverridableVariableSymbolFields index] => this.Fields[(int)index];
40
41 public string Name
42 {
43 get => this.Fields[(int)WixStdbaOverridableVariableSymbolFields.Name].AsString();
44 set => this.Set((int)WixStdbaOverridableVariableSymbolFields.Name, value);
45 }
46 }
47} \ No newline at end of file
diff --git a/src/ext/Bal/wixext/WixToolset.Bal.wixext.csproj b/src/ext/Bal/wixext/WixToolset.Bal.wixext.csproj
new file mode 100644
index 00000000..00451403
--- /dev/null
+++ b/src/ext/Bal/wixext/WixToolset.Bal.wixext.csproj
@@ -0,0 +1,39 @@
1<?xml version="1.0" encoding="utf-8"?>
2<!-- 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. -->
3
4<Project Sdk="Microsoft.NET.Sdk">
5 <PropertyGroup>
6 <TargetFramework>netstandard2.0</TargetFramework>
7 <RootNamespace>WixToolset.Bal</RootNamespace>
8 <Description>WiX Toolset Bal Extension</Description>
9 <Title>WiX Toolset Bal Extension</Title>
10 <DebugType>embedded</DebugType>
11 <NuspecFile>$(MSBuildThisFileName).nuspec</NuspecFile>
12 <IncludeSymbols>true</IncludeSymbols>
13 <NuspecProperties>Id=$(MSBuildThisFileName);Authors=$(Authors);Copyright=$(Copyright);Description=$(Description);Title=$(Title)</NuspecProperties>
14 </PropertyGroup>
15 <ItemGroup>
16 <Content Include="$(MSBuildThisFileName).targets" />
17 <EmbeddedResource Include="$(OutputPath)..\bal.wixlib" />
18 </ItemGroup>
19 <ItemGroup>
20 <PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="all" />
21 <PackageReference Include="WixToolset.Data" Version="4.0.*" PrivateAssets="all" />
22 <PackageReference Include="WixToolset.Extensibility" Version="4.0.*" PrivateAssets="all" />
23 </ItemGroup>
24
25 <ItemGroup>
26 <ProjectReference Include="..\wixlib\bal.wixproj" ReferenceOutputAssembly="false" Condition=" '$(NCrunch)'=='' " />
27 </ItemGroup>
28
29 <ItemGroup>
30 <PackageReference Include="Nerdbank.GitVersioning" Version="3.3.37" PrivateAssets="all" />
31 </ItemGroup>
32
33 <Target Name="SetNuspecProperties" DependsOnTargets="InitializeSourceControlInformation" AfterTargets="GetBuildVersion">
34 <PropertyGroup>
35 <NuspecBasePath>$(OutputPath)..\</NuspecBasePath>
36 <NuspecProperties>$(NuspecProperties);Version=$(BuildVersionSimple);RepositoryCommit=$(SourceRevisionId);RepositoryType=$(RepositoryType);RepositoryUrl=$(PrivateRepositoryUrl);ProjectFolder=$(MSBuildThisFileDirectory)</NuspecProperties>
37 </PropertyGroup>
38 </Target>
39</Project>
diff --git a/src/ext/Bal/wixext/WixToolset.Bal.wixext.nuspec b/src/ext/Bal/wixext/WixToolset.Bal.wixext.nuspec
new file mode 100644
index 00000000..d9e704ae
--- /dev/null
+++ b/src/ext/Bal/wixext/WixToolset.Bal.wixext.nuspec
@@ -0,0 +1,26 @@
1<?xml version="1.0"?>
2<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
3 <metadata minClientVersion="4.0">
4 <id>$id$</id>
5 <version>$version$</version>
6 <authors>$authors$</authors>
7 <owners>$authors$</owners>
8 <license type="expression">MS-RL</license>
9 <projectUrl>https://github.com/wixtoolset/Bal.wixext</projectUrl>
10 <requireLicenseAcceptance>false</requireLicenseAcceptance>
11 <title>$title$</title>
12 <description>$description$</description>
13 <copyright>$copyright$</copyright>
14 <repository type="$repositorytype$" url="$repositoryurl$" commit="$repositorycommit$" />
15 </metadata>
16
17 <files>
18 <file src="$projectFolder$$id$.targets" target="build" />
19
20 <file src="netstandard2.0\$id$.dll" target="tools" />
21
22 <file src="x86\*.pdb" target="pdbs\x86" />
23 <file src="x64\*.pdb" target="pdbs\x64" />
24 <file src="ARM64\*.pdb" target="pdbs\ARM64" />
25 </files>
26</package>
diff --git a/src/ext/Bal/wixext/WixToolset.Bal.wixext.targets b/src/ext/Bal/wixext/WixToolset.Bal.wixext.targets
new file mode 100644
index 00000000..70c5a19c
--- /dev/null
+++ b/src/ext/Bal/wixext/WixToolset.Bal.wixext.targets
@@ -0,0 +1,11 @@
1<?xml version="1.0" encoding="utf-8"?>
2<!-- 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. -->
3
4<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
5 <PropertyGroup>
6 <WixToolsetBalWixextPath Condition=" '$(WixToolsetBalWixextPath)' == '' ">$(MSBuildThisFileDirectory)..\tools\WixToolset.Bal.wixext.dll</WixToolsetBalWixextPath>
7 </PropertyGroup>
8 <ItemGroup>
9 <WixExtension Include="$(WixToolsetBalWixextPath)" />
10 </ItemGroup>
11</Project>