diff options
| author | Sean Hall <r.sean.hall@gmail.com> | 2021-02-28 21:04:16 -0600 |
|---|---|---|
| committer | Sean Hall <r.sean.hall@gmail.com> | 2021-03-02 15:50:47 -0600 |
| commit | a6013a643208a8d1fc2d1136ef8d3a6c3e909522 (patch) | |
| tree | 4f3007b58541d3d944cea469f630d3656ba5ef89 /src | |
| parent | b54ac261d0a03b75cf05ef370351445774b82155 (diff) | |
| download | wix-a6013a643208a8d1fc2d1136ef8d3a6c3e909522.tar.gz wix-a6013a643208a8d1fc2d1136ef8d3a6c3e909522.tar.bz2 wix-a6013a643208a8d1fc2d1136ef8d3a6c3e909522.zip | |
Refactor payload compiling and harvesting.
Diffstat (limited to 'src')
8 files changed, 546 insertions, 343 deletions
diff --git a/src/WixToolset.Core.Burn/Bind/BindBundleCommand.cs b/src/WixToolset.Core.Burn/Bind/BindBundleCommand.cs index c9a111c6..724dd7ff 100644 --- a/src/WixToolset.Core.Burn/Bind/BindBundleCommand.cs +++ b/src/WixToolset.Core.Burn/Bind/BindBundleCommand.cs | |||
| @@ -11,6 +11,7 @@ namespace WixToolset.Core.Burn | |||
| 11 | using WixToolset.Core.Bind; | 11 | using WixToolset.Core.Bind; |
| 12 | using WixToolset.Core.Burn.Bind; | 12 | using WixToolset.Core.Burn.Bind; |
| 13 | using WixToolset.Core.Burn.Bundles; | 13 | using WixToolset.Core.Burn.Bundles; |
| 14 | using WixToolset.Core.Burn.Interfaces; | ||
| 14 | using WixToolset.Data; | 15 | using WixToolset.Data; |
| 15 | using WixToolset.Data.Burn; | 16 | using WixToolset.Data.Burn; |
| 16 | using WixToolset.Data.Symbols; | 17 | using WixToolset.Data.Symbols; |
| @@ -31,6 +32,7 @@ namespace WixToolset.Core.Burn | |||
| 31 | 32 | ||
| 32 | this.BackendHelper = context.ServiceProvider.GetService<IBackendHelper>(); | 33 | this.BackendHelper = context.ServiceProvider.GetService<IBackendHelper>(); |
| 33 | this.InternalBurnBackendHelper = context.ServiceProvider.GetService<IInternalBurnBackendHelper>(); | 34 | this.InternalBurnBackendHelper = context.ServiceProvider.GetService<IInternalBurnBackendHelper>(); |
| 35 | this.PayloadHarvester = context.ServiceProvider.GetService<IPayloadHarvester>(); | ||
| 34 | 36 | ||
| 35 | this.DefaultCompressionLevel = context.DefaultCompressionLevel; | 37 | this.DefaultCompressionLevel = context.DefaultCompressionLevel; |
| 36 | this.DelayedFields = context.DelayedFields; | 38 | this.DelayedFields = context.DelayedFields; |
| @@ -52,6 +54,8 @@ namespace WixToolset.Core.Burn | |||
| 52 | 54 | ||
| 53 | private IInternalBurnBackendHelper InternalBurnBackendHelper { get; } | 55 | private IInternalBurnBackendHelper InternalBurnBackendHelper { get; } |
| 54 | 56 | ||
| 57 | private IPayloadHarvester PayloadHarvester { get; } | ||
| 58 | |||
| 55 | private CompressionLevel? DefaultCompressionLevel { get; } | 59 | private CompressionLevel? DefaultCompressionLevel { get; } |
| 56 | 60 | ||
| 57 | public IEnumerable<IDelayedField> DelayedFields { get; } | 61 | public IEnumerable<IDelayedField> DelayedFields { get; } |
| @@ -165,7 +169,7 @@ namespace WixToolset.Core.Burn | |||
| 165 | // Process the explicitly authored payloads. | 169 | // Process the explicitly authored payloads. |
| 166 | ISet<string> processedPayloads; | 170 | ISet<string> processedPayloads; |
| 167 | { | 171 | { |
| 168 | var command = new ProcessPayloadsCommand(this.ServiceProvider, this.BackendHelper, payloadSymbols.Values, bundleSymbol.DefaultPackagingType, layoutDirectory); | 172 | var command = new ProcessPayloadsCommand(this.ServiceProvider, this.BackendHelper, this.PayloadHarvester, payloadSymbols.Values, bundleSymbol.DefaultPackagingType, layoutDirectory); |
| 169 | command.Execute(); | 173 | command.Execute(); |
| 170 | 174 | ||
| 171 | fileTransfers.AddRange(command.FileTransfers); | 175 | fileTransfers.AddRange(command.FileTransfers); |
| @@ -247,7 +251,7 @@ namespace WixToolset.Core.Burn | |||
| 247 | { | 251 | { |
| 248 | var toProcess = payloadSymbols.Values.Where(r => !processedPayloads.Contains(r.Id.Id)).ToList(); | 252 | var toProcess = payloadSymbols.Values.Where(r => !processedPayloads.Contains(r.Id.Id)).ToList(); |
| 249 | 253 | ||
| 250 | var command = new ProcessPayloadsCommand(this.ServiceProvider, this.BackendHelper, toProcess, bundleSymbol.DefaultPackagingType, layoutDirectory); | 254 | var command = new ProcessPayloadsCommand(this.ServiceProvider, this.BackendHelper, this.PayloadHarvester, toProcess, bundleSymbol.DefaultPackagingType, layoutDirectory); |
| 251 | command.Execute(); | 255 | command.Execute(); |
| 252 | 256 | ||
| 253 | fileTransfers.AddRange(command.FileTransfers); | 257 | fileTransfers.AddRange(command.FileTransfers); |
diff --git a/src/WixToolset.Core.Burn/Bundles/ProcessPayloadsCommand.cs b/src/WixToolset.Core.Burn/Bundles/ProcessPayloadsCommand.cs index db5b03fb..dea5b336 100644 --- a/src/WixToolset.Core.Burn/Bundles/ProcessPayloadsCommand.cs +++ b/src/WixToolset.Core.Burn/Bundles/ProcessPayloadsCommand.cs | |||
| @@ -6,6 +6,7 @@ namespace WixToolset.Core.Burn.Bundles | |||
| 6 | using System.Collections.Generic; | 6 | using System.Collections.Generic; |
| 7 | using System.Diagnostics; | 7 | using System.Diagnostics; |
| 8 | using System.IO; | 8 | using System.IO; |
| 9 | using WixToolset.Core.Burn.Interfaces; | ||
| 9 | using WixToolset.Data; | 10 | using WixToolset.Data; |
| 10 | using WixToolset.Data.Burn; | 11 | using WixToolset.Data.Burn; |
| 11 | using WixToolset.Data.Symbols; | 12 | using WixToolset.Data.Symbols; |
| @@ -14,13 +15,12 @@ namespace WixToolset.Core.Burn.Bundles | |||
| 14 | 15 | ||
| 15 | internal class ProcessPayloadsCommand | 16 | internal class ProcessPayloadsCommand |
| 16 | { | 17 | { |
| 17 | private static readonly Version EmptyVersion = new Version(0, 0, 0, 0); | 18 | public ProcessPayloadsCommand(IWixToolsetServiceProvider serviceProvider, IBackendHelper backendHelper, IPayloadHarvester payloadHarvester, IEnumerable<WixBundlePayloadSymbol> payloads, PackagingType defaultPackaging, string layoutDirectory) |
| 18 | |||
| 19 | public ProcessPayloadsCommand(IWixToolsetServiceProvider serviceProvider, IBackendHelper backendHelper, IEnumerable<WixBundlePayloadSymbol> payloads, PackagingType defaultPackaging, string layoutDirectory) | ||
| 20 | { | 19 | { |
| 21 | this.Messaging = serviceProvider.GetService<IMessaging>(); | 20 | this.Messaging = serviceProvider.GetService<IMessaging>(); |
| 22 | 21 | ||
| 23 | this.BackendHelper = backendHelper; | 22 | this.BackendHelper = backendHelper; |
| 23 | this.PayloadHarvester = payloadHarvester; | ||
| 24 | this.Payloads = payloads; | 24 | this.Payloads = payloads; |
| 25 | this.DefaultPackaging = defaultPackaging; | 25 | this.DefaultPackaging = defaultPackaging; |
| 26 | this.LayoutDirectory = layoutDirectory; | 26 | this.LayoutDirectory = layoutDirectory; |
| @@ -34,6 +34,8 @@ namespace WixToolset.Core.Burn.Bundles | |||
| 34 | 34 | ||
| 35 | private IBackendHelper BackendHelper { get; } | 35 | private IBackendHelper BackendHelper { get; } |
| 36 | 36 | ||
| 37 | private IPayloadHarvester PayloadHarvester { get; } | ||
| 38 | |||
| 37 | private IEnumerable<WixBundlePayloadSymbol> Payloads { get; } | 39 | private IEnumerable<WixBundlePayloadSymbol> Payloads { get; } |
| 38 | 40 | ||
| 39 | private PackagingType DefaultPackaging { get; } | 41 | private PackagingType DefaultPackaging { get; } |
| @@ -56,17 +58,13 @@ namespace WixToolset.Core.Burn.Bundles | |||
| 56 | 58 | ||
| 57 | this.UpdatePayloadPackagingType(payload); | 59 | this.UpdatePayloadPackagingType(payload); |
| 58 | 60 | ||
| 59 | if (String.IsNullOrEmpty(sourceFile?.Path)) | 61 | if (!this.PayloadHarvester.HarvestStandardInformation(payload)) |
| 60 | { | 62 | { |
| 61 | // Remote payloads obviously cannot be embedded. | 63 | // Remote payloads obviously cannot be embedded. |
| 62 | Debug.Assert(PackagingType.Embedded != payload.Packaging); | 64 | Debug.Assert(PackagingType.Embedded != payload.Packaging); |
| 63 | } | 65 | } |
| 64 | else // not a remote payload so we have a lot more to update. | 66 | else // not a remote payload so we have a lot more to update. |
| 65 | { | 67 | { |
| 66 | this.UpdatePayloadFileInformation(payload, sourceFile); | ||
| 67 | |||
| 68 | this.UpdatePayloadVersionInformation(payload, sourceFile); | ||
| 69 | |||
| 70 | // External payloads need to be transfered. | 68 | // External payloads need to be transfered. |
| 71 | if (PackagingType.External == payload.Packaging) | 69 | if (PackagingType.External == payload.Packaging) |
| 72 | { | 70 | { |
| @@ -110,40 +108,5 @@ namespace WixToolset.Core.Burn.Bundles | |||
| 110 | payload.ContainerRef = BurnConstants.BurnDefaultAttachedContainerName; | 108 | payload.ContainerRef = BurnConstants.BurnDefaultAttachedContainerName; |
| 111 | } | 109 | } |
| 112 | } | 110 | } |
| 113 | |||
| 114 | private void UpdatePayloadFileInformation(WixBundlePayloadSymbol payload, IntermediateFieldPathValue sourceFile) | ||
| 115 | { | ||
| 116 | var fileInfo = new FileInfo(sourceFile.Path); | ||
| 117 | |||
| 118 | if (null != fileInfo) | ||
| 119 | { | ||
| 120 | payload.FileSize = fileInfo.Length; | ||
| 121 | |||
| 122 | payload.Hash = BundleHashAlgorithm.Hash(fileInfo); | ||
| 123 | } | ||
| 124 | else | ||
| 125 | { | ||
| 126 | payload.FileSize = 0; | ||
| 127 | } | ||
| 128 | } | ||
| 129 | |||
| 130 | private void UpdatePayloadVersionInformation(WixBundlePayloadSymbol payload, IntermediateFieldPathValue sourceFile) | ||
| 131 | { | ||
| 132 | var versionInfo = FileVersionInfo.GetVersionInfo(sourceFile.Path); | ||
| 133 | |||
| 134 | if (null != versionInfo) | ||
| 135 | { | ||
| 136 | // Use the fixed version info block for the file since the resource text may not be a dotted quad. | ||
| 137 | var version = new Version(versionInfo.ProductMajorPart, versionInfo.ProductMinorPart, versionInfo.ProductBuildPart, versionInfo.ProductPrivatePart); | ||
| 138 | |||
| 139 | if (ProcessPayloadsCommand.EmptyVersion != version) | ||
| 140 | { | ||
| 141 | payload.Version = version.ToString(); | ||
| 142 | } | ||
| 143 | |||
| 144 | payload.Description = versionInfo.FileDescription; | ||
| 145 | payload.DisplayName = versionInfo.ProductName; | ||
| 146 | } | ||
| 147 | } | ||
| 148 | } | 111 | } |
| 149 | } | 112 | } |
diff --git a/src/WixToolset.Core.Burn/ExtensibilityServices/PayloadHarvester.cs b/src/WixToolset.Core.Burn/ExtensibilityServices/PayloadHarvester.cs new file mode 100644 index 00000000..9ef91028 --- /dev/null +++ b/src/WixToolset.Core.Burn/ExtensibilityServices/PayloadHarvester.cs | |||
| @@ -0,0 +1,68 @@ | |||
| 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.Core.Burn.ExtensibilityServices | ||
| 4 | { | ||
| 5 | using System; | ||
| 6 | using System.Diagnostics; | ||
| 7 | using System.IO; | ||
| 8 | using WixToolset.Core.Burn.Bundles; | ||
| 9 | using WixToolset.Core.Burn.Interfaces; | ||
| 10 | using WixToolset.Data.Symbols; | ||
| 11 | |||
| 12 | internal class PayloadHarvester : IPayloadHarvester | ||
| 13 | { | ||
| 14 | private static readonly Version EmptyVersion = new Version(0, 0, 0, 0); | ||
| 15 | |||
| 16 | /// <inheritdoc /> | ||
| 17 | public bool HarvestStandardInformation(WixBundlePayloadSymbol payload) | ||
| 18 | { | ||
| 19 | var filePath = payload.SourceFile?.Path; | ||
| 20 | |||
| 21 | if (String.IsNullOrEmpty(filePath)) | ||
| 22 | { | ||
| 23 | return false; | ||
| 24 | } | ||
| 25 | |||
| 26 | this.UpdatePayloadFileInformation(payload, filePath); | ||
| 27 | |||
| 28 | this.UpdatePayloadVersionInformation(payload, filePath); | ||
| 29 | |||
| 30 | return true; | ||
| 31 | } | ||
| 32 | |||
| 33 | private void UpdatePayloadFileInformation(WixBundlePayloadSymbol payload, string filePath) | ||
| 34 | { | ||
| 35 | var fileInfo = new FileInfo(filePath); | ||
| 36 | |||
| 37 | if (null != fileInfo) | ||
| 38 | { | ||
| 39 | payload.FileSize = fileInfo.Length; | ||
| 40 | |||
| 41 | payload.Hash = BundleHashAlgorithm.Hash(fileInfo); | ||
| 42 | } | ||
| 43 | else | ||
| 44 | { | ||
| 45 | payload.FileSize = 0; | ||
| 46 | } | ||
| 47 | } | ||
| 48 | |||
| 49 | private void UpdatePayloadVersionInformation(WixBundlePayloadSymbol payload, string filePath) | ||
| 50 | { | ||
| 51 | var versionInfo = FileVersionInfo.GetVersionInfo(filePath); | ||
| 52 | |||
| 53 | if (null != versionInfo) | ||
| 54 | { | ||
| 55 | // Use the fixed version info block for the file since the resource text may not be a dotted quad. | ||
| 56 | var version = new Version(versionInfo.ProductMajorPart, versionInfo.ProductMinorPart, versionInfo.ProductBuildPart, versionInfo.ProductPrivatePart); | ||
| 57 | |||
| 58 | if (PayloadHarvester.EmptyVersion != version) | ||
| 59 | { | ||
| 60 | payload.Version = version.ToString(); | ||
| 61 | } | ||
| 62 | |||
| 63 | payload.Description = versionInfo.FileDescription; | ||
| 64 | payload.DisplayName = versionInfo.ProductName; | ||
| 65 | } | ||
| 66 | } | ||
| 67 | } | ||
| 68 | } | ||
diff --git a/src/WixToolset.Core.Burn/Interfaces/IPayloadHarvester.cs b/src/WixToolset.Core.Burn/Interfaces/IPayloadHarvester.cs new file mode 100644 index 00000000..1bafa46e --- /dev/null +++ b/src/WixToolset.Core.Burn/Interfaces/IPayloadHarvester.cs | |||
| @@ -0,0 +1,23 @@ | |||
| 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.Core.Burn.Interfaces | ||
| 4 | { | ||
| 5 | using System.Diagnostics; | ||
| 6 | using WixToolset.Data.Symbols; | ||
| 7 | |||
| 8 | /// <summary> | ||
| 9 | /// Service for harvesting payload information. | ||
| 10 | /// </summary> | ||
| 11 | public interface IPayloadHarvester | ||
| 12 | { | ||
| 13 | /// <summary> | ||
| 14 | /// Uses <see cref="WixBundlePayloadSymbol.SourceFile"/> to: | ||
| 15 | /// update <see cref="WixBundlePayloadSymbol.Hash"/> from file contents, | ||
| 16 | /// update <see cref="WixBundlePayloadSymbol.FileSize"/> from file size, and | ||
| 17 | /// update <see cref="WixBundlePayloadSymbol.Description"/>, <see cref="WixBundlePayloadSymbol.DisplayName"/>, and <see cref="WixBundlePayloadSymbol.Version"/> from <see cref="FileVersionInfo"/>. | ||
| 18 | /// </summary> | ||
| 19 | /// <param name="payload">The symbol to update.</param> | ||
| 20 | /// <returns>Whether the symbol had a source file specified.</returns> | ||
| 21 | bool HarvestStandardInformation(WixBundlePayloadSymbol payload); | ||
| 22 | } | ||
| 23 | } | ||
diff --git a/src/WixToolset.Core.Burn/WixToolsetCoreServiceProviderExtensions.cs b/src/WixToolset.Core.Burn/WixToolsetCoreServiceProviderExtensions.cs index b0401b4a..58076d5e 100644 --- a/src/WixToolset.Core.Burn/WixToolsetCoreServiceProviderExtensions.cs +++ b/src/WixToolset.Core.Burn/WixToolsetCoreServiceProviderExtensions.cs | |||
| @@ -5,6 +5,7 @@ namespace WixToolset.Core.Burn | |||
| 5 | using System; | 5 | using System; |
| 6 | using System.Collections.Generic; | 6 | using System.Collections.Generic; |
| 7 | using WixToolset.Core.Burn.ExtensibilityServices; | 7 | using WixToolset.Core.Burn.ExtensibilityServices; |
| 8 | using WixToolset.Core.Burn.Interfaces; | ||
| 8 | using WixToolset.Extensibility.Services; | 9 | using WixToolset.Extensibility.Services; |
| 9 | 10 | ||
| 10 | /// <summary> | 11 | /// <summary> |
| @@ -31,6 +32,7 @@ namespace WixToolset.Core.Burn | |||
| 31 | { | 32 | { |
| 32 | // Singletons. | 33 | // Singletons. |
| 33 | coreProvider.AddService((provider, singletons) => AddSingleton<IInternalBurnBackendHelper>(singletons, new BurnBackendHelper(provider))); | 34 | coreProvider.AddService((provider, singletons) => AddSingleton<IInternalBurnBackendHelper>(singletons, new BurnBackendHelper(provider))); |
| 35 | coreProvider.AddService((provider, singletons) => AddSingleton<IPayloadHarvester>(singletons, new PayloadHarvester())); | ||
| 34 | coreProvider.AddService((provider, singletons) => AddSingleton<IBurnBackendHelper>(singletons, provider.GetService<IInternalBurnBackendHelper>())); | 36 | coreProvider.AddService((provider, singletons) => AddSingleton<IBurnBackendHelper>(singletons, provider.GetService<IInternalBurnBackendHelper>())); |
| 35 | } | 37 | } |
| 36 | 38 | ||
diff --git a/src/WixToolset.Core/Compile/CompilerPayload.cs b/src/WixToolset.Core/Compile/CompilerPayload.cs new file mode 100644 index 00000000..4eda56f8 --- /dev/null +++ b/src/WixToolset.Core/Compile/CompilerPayload.cs | |||
| @@ -0,0 +1,247 @@ | |||
| 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.Core | ||
| 4 | { | ||
| 5 | using System; | ||
| 6 | using System.IO; | ||
| 7 | using System.Xml.Linq; | ||
| 8 | using WixToolset.Data; | ||
| 9 | using WixToolset.Data.Burn; | ||
| 10 | using WixToolset.Data.Symbols; | ||
| 11 | |||
| 12 | internal class CompilerPayload | ||
| 13 | { | ||
| 14 | public YesNoDefaultType Compressed { get; set; } = YesNoDefaultType.Default; | ||
| 15 | |||
| 16 | public string Description { get; set; } | ||
| 17 | |||
| 18 | public string DisplayName { get; set; } | ||
| 19 | |||
| 20 | public string DownloadUrl { get; set; } | ||
| 21 | |||
| 22 | public string Hash { get; set; } | ||
| 23 | |||
| 24 | public Identifier Id { get; set; } | ||
| 25 | |||
| 26 | public bool IsRequired { get; set; } = true; | ||
| 27 | |||
| 28 | public string Name { get; set; } | ||
| 29 | |||
| 30 | public string ProductName { get; set; } | ||
| 31 | |||
| 32 | public long? Size { get; set; } | ||
| 33 | |||
| 34 | public string SourceFile { get; set; } | ||
| 35 | |||
| 36 | public string Version { get; set; } | ||
| 37 | |||
| 38 | public CompilerPayload(CompilerCore core, SourceLineNumber sourceLineNumbers, XElement element) | ||
| 39 | { | ||
| 40 | this.Core = core; | ||
| 41 | this.Element = element; | ||
| 42 | this.SourceLineNumbers = sourceLineNumbers; | ||
| 43 | } | ||
| 44 | |||
| 45 | private CompilerCore Core { get; } | ||
| 46 | |||
| 47 | private XElement Element { get; } | ||
| 48 | |||
| 49 | private SourceLineNumber SourceLineNumbers { get; } | ||
| 50 | |||
| 51 | private void CalculateAndVerifyFields(CompilerPayload remotePayload = null) | ||
| 52 | { | ||
| 53 | if (String.IsNullOrEmpty(this.SourceFile)) | ||
| 54 | { | ||
| 55 | if (String.IsNullOrEmpty(this.Name)) | ||
| 56 | { | ||
| 57 | if (this.IsRequired) | ||
| 58 | { | ||
| 59 | this.Core.Write(ErrorMessages.ExpectedAttributesWithOtherAttribute(this.SourceLineNumbers, this.Element.Name.LocalName, "Name", "SourceFile")); | ||
| 60 | } | ||
| 61 | } | ||
| 62 | else if (remotePayload == null) | ||
| 63 | { | ||
| 64 | this.SourceFile = Path.Combine("SourceDir", this.Name); | ||
| 65 | } | ||
| 66 | } | ||
| 67 | else if (remotePayload != null) | ||
| 68 | { | ||
| 69 | this.Core.Write(ErrorMessages.UnexpectedElementWithAttribute(this.SourceLineNumbers, this.Element.Name.LocalName, "RemotePayload", "SourceFile")); | ||
| 70 | } | ||
| 71 | else if (this.SourceFile.EndsWith(Path.DirectorySeparatorChar.ToString(), StringComparison.Ordinal)) | ||
| 72 | { | ||
| 73 | if (String.IsNullOrEmpty(this.Name)) | ||
| 74 | { | ||
| 75 | this.Core.Write(ErrorMessages.ExpectedAttribute(this.SourceLineNumbers, this.Element.Name.LocalName, "Name", "SourceFile", this.SourceFile)); | ||
| 76 | } | ||
| 77 | else | ||
| 78 | { | ||
| 79 | this.SourceFile = Path.Combine(this.SourceFile, Path.GetFileName(this.Name)); | ||
| 80 | } | ||
| 81 | } | ||
| 82 | |||
| 83 | if (remotePayload != null) | ||
| 84 | { | ||
| 85 | if (this.DownloadUrl == null) | ||
| 86 | { | ||
| 87 | this.Core.Write(ErrorMessages.ExpectedAttributeWithElement(this.SourceLineNumbers, this.Element.Name.LocalName, "DownloadUrl", "RemotePayload")); | ||
| 88 | } | ||
| 89 | |||
| 90 | if (YesNoDefaultType.No != this.Compressed) | ||
| 91 | { | ||
| 92 | this.Compressed = YesNoDefaultType.No; | ||
| 93 | this.Core.Write(WarningMessages.RemotePayloadsMustNotAlsoBeCompressed(this.SourceLineNumbers, this.Element.Name.LocalName)); | ||
| 94 | } | ||
| 95 | |||
| 96 | this.Description = remotePayload.Description; | ||
| 97 | this.DisplayName = remotePayload.DisplayName; | ||
| 98 | this.Hash = remotePayload.Hash; | ||
| 99 | this.Size = remotePayload.Size; | ||
| 100 | this.Version = remotePayload.Version; | ||
| 101 | } | ||
| 102 | } | ||
| 103 | |||
| 104 | public WixBundlePayloadSymbol CreatePayloadSymbol(ComplexReferenceParentType parentType, string parentId, ComplexReferenceChildType previousType = ComplexReferenceChildType.Unknown, string previousId = null) | ||
| 105 | { | ||
| 106 | WixBundlePayloadSymbol symbol = null; | ||
| 107 | |||
| 108 | if (parentType == ComplexReferenceParentType.Container && parentId == BurnConstants.BurnUXContainerName) | ||
| 109 | { | ||
| 110 | if (this.Compressed == YesNoDefaultType.No) | ||
| 111 | { | ||
| 112 | this.Core.Write(WarningMessages.UxPayloadsOnlySupportEmbedding(this.SourceLineNumbers, this.SourceFile)); | ||
| 113 | } | ||
| 114 | |||
| 115 | if (!String.IsNullOrEmpty(this.DownloadUrl)) | ||
| 116 | { | ||
| 117 | this.Core.Write(WarningMessages.DownloadUrlNotSupportedForEmbeddedPayloads(this.SourceLineNumbers, this.Id.Id)); | ||
| 118 | } | ||
| 119 | |||
| 120 | this.Compressed = YesNoDefaultType.Yes; | ||
| 121 | this.DownloadUrl = null; | ||
| 122 | } | ||
| 123 | |||
| 124 | if (!this.Core.EncounteredError) | ||
| 125 | { | ||
| 126 | symbol = this.Core.AddSymbol(new WixBundlePayloadSymbol(this.SourceLineNumbers, this.Id) | ||
| 127 | { | ||
| 128 | Name = String.IsNullOrEmpty(this.Name) ? Path.GetFileName(this.SourceFile) : this.Name, | ||
| 129 | SourceFile = new IntermediateFieldPathValue { Path = this.SourceFile }, | ||
| 130 | DownloadUrl = this.DownloadUrl, | ||
| 131 | Compressed = (this.Compressed == YesNoDefaultType.Yes) ? true : (this.Compressed == YesNoDefaultType.No) ? (bool?)false : null, | ||
| 132 | UnresolvedSourceFile = this.SourceFile, // duplicate of sourceFile but in a string column so it won't get resolved to a full path during binding. | ||
| 133 | DisplayName = this.DisplayName ?? this.ProductName, | ||
| 134 | Description = this.Description, | ||
| 135 | Hash = this.Hash, | ||
| 136 | FileSize = this.Size, | ||
| 137 | Version = this.Version, | ||
| 138 | }); | ||
| 139 | |||
| 140 | this.Core.CreateGroupAndOrderingRows(this.SourceLineNumbers, parentType, parentId, ComplexReferenceChildType.Payload, symbol.Id.Id, previousType, previousId); | ||
| 141 | } | ||
| 142 | |||
| 143 | return symbol; | ||
| 144 | } | ||
| 145 | |||
| 146 | public void FinishCompilingPackage(CompilerPayload remotePayload) | ||
| 147 | { | ||
| 148 | this.CalculateAndVerifyFields(remotePayload); | ||
| 149 | this.GenerateIdFromFilename(); | ||
| 150 | |||
| 151 | if (this.Id == null) | ||
| 152 | { | ||
| 153 | this.Core.Write(ErrorMessages.ExpectedAttribute(this.SourceLineNumbers, this.Element.Name.LocalName, "Id")); | ||
| 154 | this.Id = Identifier.Invalid; | ||
| 155 | } | ||
| 156 | } | ||
| 157 | |||
| 158 | public void FinishCompilingPayload() | ||
| 159 | { | ||
| 160 | this.CalculateAndVerifyFields(); | ||
| 161 | this.GenerateIdFromPrefix("pay"); | ||
| 162 | } | ||
| 163 | |||
| 164 | private void GenerateIdFromFilename() | ||
| 165 | { | ||
| 166 | if (this.Id == null) | ||
| 167 | { | ||
| 168 | if (!String.IsNullOrEmpty(this.Name)) | ||
| 169 | { | ||
| 170 | this.Id = this.Core.CreateIdentifierFromFilename(Path.GetFileName(this.Name)); | ||
| 171 | } | ||
| 172 | else if (!String.IsNullOrEmpty(this.SourceFile)) | ||
| 173 | { | ||
| 174 | this.Id = this.Core.CreateIdentifierFromFilename(Path.GetFileName(this.SourceFile)); | ||
| 175 | } | ||
| 176 | } | ||
| 177 | } | ||
| 178 | |||
| 179 | private void GenerateIdFromPrefix(string prefix) | ||
| 180 | { | ||
| 181 | if (this.Id == null) | ||
| 182 | { | ||
| 183 | this.Id = this.Core.CreateIdentifier(prefix, this.SourceFile?.ToUpperInvariant() ?? String.Empty); | ||
| 184 | } | ||
| 185 | } | ||
| 186 | |||
| 187 | public void ParseCompressed(XAttribute attrib) | ||
| 188 | { | ||
| 189 | this.Compressed = this.Core.GetAttributeYesNoDefaultValue(this.SourceLineNumbers, attrib); | ||
| 190 | } | ||
| 191 | |||
| 192 | public void ParseDescription(XAttribute attrib) | ||
| 193 | { | ||
| 194 | this.Description = this.Core.GetAttributeValue(this.SourceLineNumbers, attrib); | ||
| 195 | } | ||
| 196 | |||
| 197 | public void ParseDisplayName(XAttribute attrib) | ||
| 198 | { | ||
| 199 | this.DisplayName = this.Core.GetAttributeValue(this.SourceLineNumbers, attrib); | ||
| 200 | } | ||
| 201 | |||
| 202 | public void ParseDownloadUrl(XAttribute attrib) | ||
| 203 | { | ||
| 204 | this.DownloadUrl = this.Core.GetAttributeValue(this.SourceLineNumbers, attrib); | ||
| 205 | } | ||
| 206 | |||
| 207 | public void ParseHash(XAttribute attrib) | ||
| 208 | { | ||
| 209 | this.Hash = this.Core.GetAttributeValue(this.SourceLineNumbers, attrib); | ||
| 210 | } | ||
| 211 | |||
| 212 | public void ParseId(XAttribute attrib) | ||
| 213 | { | ||
| 214 | this.Id = this.Core.GetAttributeIdentifier(this.SourceLineNumbers, attrib); | ||
| 215 | } | ||
| 216 | |||
| 217 | public void ParseName(XAttribute attrib) | ||
| 218 | { | ||
| 219 | this.Name = this.Core.GetAttributeLongFilename(this.SourceLineNumbers, attrib, false, true); | ||
| 220 | if (!this.Core.IsValidLongFilename(this.Name, false, true)) | ||
| 221 | { | ||
| 222 | this.Core.Write(ErrorMessages.IllegalLongFilename(this.SourceLineNumbers, this.Element.Name.LocalName, "Name", this.Name)); | ||
| 223 | } | ||
| 224 | } | ||
| 225 | |||
| 226 | public void ParseProductName(XAttribute attrib) | ||
| 227 | { | ||
| 228 | this.ProductName = this.Core.GetAttributeValue(this.SourceLineNumbers, attrib); | ||
| 229 | } | ||
| 230 | |||
| 231 | public void ParseSize(XAttribute attrib) | ||
| 232 | { | ||
| 233 | this.Size = this.Core.GetAttributeLongValue(this.SourceLineNumbers, attrib, 1, Int64.MaxValue); | ||
| 234 | } | ||
| 235 | |||
| 236 | public void ParseSourceFile(XAttribute attrib) | ||
| 237 | { | ||
| 238 | this.SourceFile = this.Core.GetAttributeValue(this.SourceLineNumbers, attrib); | ||
| 239 | } | ||
| 240 | |||
| 241 | public void ParseVersion(XAttribute attrib) | ||
| 242 | { | ||
| 243 | this.Version = this.Core.GetAttributeValue(this.SourceLineNumbers, attrib); | ||
| 244 | } | ||
| 245 | |||
| 246 | } | ||
| 247 | } | ||
diff --git a/src/WixToolset.Core/CompilerCore.cs b/src/WixToolset.Core/CompilerCore.cs index 53e0f3fc..cfe3082e 100644 --- a/src/WixToolset.Core/CompilerCore.cs +++ b/src/WixToolset.Core/CompilerCore.cs | |||
| @@ -341,6 +341,46 @@ namespace WixToolset.Core | |||
| 341 | } | 341 | } |
| 342 | 342 | ||
| 343 | /// <summary> | 343 | /// <summary> |
| 344 | /// Creates group and ordering information. | ||
| 345 | /// </summary> | ||
| 346 | /// <param name="sourceLineNumbers">Source line numbers.</param> | ||
| 347 | /// <param name="parentType">Type of parent group, if known.</param> | ||
| 348 | /// <param name="parentId">Identifier of parent group, if known.</param> | ||
| 349 | /// <param name="type">Type of this item.</param> | ||
| 350 | /// <param name="id">Identifier for this item.</param> | ||
| 351 | /// <param name="previousType">Type of previous item, if known.</param> | ||
| 352 | /// <param name="previousId">Identifier of previous item, if known</param> | ||
| 353 | public void CreateGroupAndOrderingRows(SourceLineNumber sourceLineNumbers, | ||
| 354 | ComplexReferenceParentType parentType, string parentId, | ||
| 355 | ComplexReferenceChildType type, string id, | ||
| 356 | ComplexReferenceChildType previousType, string previousId) | ||
| 357 | { | ||
| 358 | if (this.EncounteredError) | ||
| 359 | { | ||
| 360 | return; | ||
| 361 | } | ||
| 362 | |||
| 363 | if (parentType != ComplexReferenceParentType.Unknown && parentId != null) | ||
| 364 | { | ||
| 365 | this.CreateWixGroupRow(sourceLineNumbers, parentType, parentId, type, id); | ||
| 366 | } | ||
| 367 | |||
| 368 | if (previousType != ComplexReferenceChildType.Unknown && previousId != null) | ||
| 369 | { | ||
| 370 | // TODO: Should we define our own enum for this, just to ensure there's no "cross-contamination"? | ||
| 371 | // TODO: Also, we could potentially include an 'Attributes' field to track things like | ||
| 372 | // 'before' vs. 'after', and explicit vs. inferred dependencies. | ||
| 373 | this.AddSymbol(new WixOrderingSymbol(sourceLineNumbers) | ||
| 374 | { | ||
| 375 | ItemType = type, | ||
| 376 | ItemIdRef = id, | ||
| 377 | DependsOnType = previousType, | ||
| 378 | DependsOnIdRef = previousId, | ||
| 379 | }); | ||
| 380 | } | ||
| 381 | } | ||
| 382 | |||
| 383 | /// <summary> | ||
| 344 | /// Creates a version 3 name-based UUID. | 384 | /// Creates a version 3 name-based UUID. |
| 345 | /// </summary> | 385 | /// </summary> |
| 346 | /// <param name="namespaceGuid">The namespace UUID.</param> | 386 | /// <param name="namespaceGuid">The namespace UUID.</param> |
diff --git a/src/WixToolset.Core/Compiler_Bundle.cs b/src/WixToolset.Core/Compiler_Bundle.cs index 189ac9b5..64fe2acc 100644 --- a/src/WixToolset.Core/Compiler_Bundle.cs +++ b/src/WixToolset.Core/Compiler_Bundle.cs | |||
| @@ -651,7 +651,7 @@ namespace WixToolset.Core | |||
| 651 | switch (child.Name.LocalName) | 651 | switch (child.Name.LocalName) |
| 652 | { | 652 | { |
| 653 | case "BootstrapperApplicationDll": | 653 | case "BootstrapperApplicationDll": |
| 654 | previousId = this.ParseBootstrapperApplicationDllElement(child, previousType, previousId); | 654 | previousId = this.ParseBootstrapperApplicationDllElement(child, id, previousType, previousId); |
| 655 | previousType = ComplexReferenceChildType.Payload; | 655 | previousType = ComplexReferenceChildType.Payload; |
| 656 | break; | 656 | break; |
| 657 | case "Payload": | 657 | case "Payload": |
| @@ -683,15 +683,21 @@ namespace WixToolset.Core | |||
| 683 | /// Parse the BoostrapperApplication element. | 683 | /// Parse the BoostrapperApplication element. |
| 684 | /// </summary> | 684 | /// </summary> |
| 685 | /// <param name="node">Element to parse</param> | 685 | /// <param name="node">Element to parse</param> |
| 686 | /// <param name="defaultId"></param> | ||
| 686 | /// <param name="previousType"></param> | 687 | /// <param name="previousType"></param> |
| 687 | /// <param name="previousId"></param> | 688 | /// <param name="previousId"></param> |
| 688 | private Identifier ParseBootstrapperApplicationDllElement(XElement node, ComplexReferenceChildType previousType, Identifier previousId) | 689 | private Identifier ParseBootstrapperApplicationDllElement(XElement node, Identifier defaultId, ComplexReferenceChildType previousType, Identifier previousId) |
| 689 | { | 690 | { |
| 690 | var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); | 691 | var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); |
| 692 | var compilerPayload = new CompilerPayload(this.Core, sourceLineNumbers, node) | ||
| 693 | { | ||
| 694 | Id = defaultId, | ||
| 695 | }; | ||
| 691 | var dpiAwareness = WixBootstrapperApplicationDpiAwarenessType.PerMonitorV2; | 696 | var dpiAwareness = WixBootstrapperApplicationDpiAwarenessType.PerMonitorV2; |
| 692 | 697 | ||
| 693 | // The BootstrapperApplicationDll element acts like a Payload element so delegate to the "Payload" attribute parsing code to parse and create a Payload entry. | 698 | // This list lets us evaluate extension attributes *after* all core attributes |
| 694 | this.ParsePayloadElementContent(node, ComplexReferenceParentType.Container, Compiler.BurnUXContainerId, previousType, previousId, true, out var id); | 699 | // have been parsed and dealt with, regardless of authoring order. |
| 700 | var extensionAttributes = new List<XAttribute>(); | ||
| 695 | 701 | ||
| 696 | foreach (var attrib in node.Attributes()) | 702 | foreach (var attrib in node.Attributes()) |
| 697 | { | 703 | { |
| @@ -699,6 +705,15 @@ namespace WixToolset.Core | |||
| 699 | { | 705 | { |
| 700 | switch (attrib.Name.LocalName) | 706 | switch (attrib.Name.LocalName) |
| 701 | { | 707 | { |
| 708 | case "Id": | ||
| 709 | compilerPayload.ParseId(attrib); | ||
| 710 | break; | ||
| 711 | case "Name": | ||
| 712 | compilerPayload.ParseName(attrib); | ||
| 713 | break; | ||
| 714 | case "SourceFile": | ||
| 715 | compilerPayload.ParseSourceFile(attrib); | ||
| 716 | break; | ||
| 702 | case "DpiAwareness": | 717 | case "DpiAwareness": |
| 703 | var dpiAwarenessValue = this.Core.GetAttributeValue(sourceLineNumbers, attrib); | 718 | var dpiAwarenessValue = this.Core.GetAttributeValue(sourceLineNumbers, attrib); |
| 704 | switch (dpiAwarenessValue) | 719 | switch (dpiAwarenessValue) |
| @@ -723,8 +738,28 @@ namespace WixToolset.Core | |||
| 723 | break; | 738 | break; |
| 724 | } | 739 | } |
| 725 | break; | 740 | break; |
| 741 | default: | ||
| 742 | this.Core.UnexpectedAttribute(node, attrib); | ||
| 743 | break; | ||
| 726 | } | 744 | } |
| 727 | } | 745 | } |
| 746 | else | ||
| 747 | { | ||
| 748 | extensionAttributes.Add(attrib); | ||
| 749 | } | ||
| 750 | } | ||
| 751 | |||
| 752 | compilerPayload.FinishCompilingPayload(); | ||
| 753 | |||
| 754 | // Now that the Id is known, we can parse the extension attributes. | ||
| 755 | var context = new Dictionary<string, string> | ||
| 756 | { | ||
| 757 | ["Id"] = compilerPayload.Id.Id, | ||
| 758 | }; | ||
| 759 | |||
| 760 | foreach (var extensionAttribute in extensionAttributes) | ||
| 761 | { | ||
| 762 | this.Core.ParseExtensionAttribute(node, extensionAttribute, context); | ||
| 728 | } | 763 | } |
| 729 | 764 | ||
| 730 | foreach (var child in node.Elements()) | 765 | foreach (var child in node.Elements()) |
| @@ -746,19 +781,20 @@ namespace WixToolset.Core | |||
| 746 | 781 | ||
| 747 | if (!this.Core.EncounteredError) | 782 | if (!this.Core.EncounteredError) |
| 748 | { | 783 | { |
| 784 | compilerPayload.CreatePayloadSymbol(ComplexReferenceParentType.Container, Compiler.BurnUXContainerId.Id, previousType, previousId?.Id); | ||
| 749 | this.Core.AddSymbol(new WixBundleContainerSymbol(sourceLineNumbers, Compiler.BurnUXContainerId) | 785 | this.Core.AddSymbol(new WixBundleContainerSymbol(sourceLineNumbers, Compiler.BurnUXContainerId) |
| 750 | { | 786 | { |
| 751 | Name = "bundle-ux.cab", | 787 | Name = "bundle-ux.cab", |
| 752 | Type = ContainerType.Attached | 788 | Type = ContainerType.Attached |
| 753 | }); | 789 | }); |
| 754 | 790 | ||
| 755 | this.Core.AddSymbol(new WixBootstrapperApplicationDllSymbol(sourceLineNumbers, id) | 791 | this.Core.AddSymbol(new WixBootstrapperApplicationDllSymbol(sourceLineNumbers, compilerPayload.Id) |
| 756 | { | 792 | { |
| 757 | DpiAwareness = dpiAwareness, | 793 | DpiAwareness = dpiAwareness, |
| 758 | }); | 794 | }); |
| 759 | } | 795 | } |
| 760 | 796 | ||
| 761 | return id; | 797 | return compilerPayload.Id; |
| 762 | } | 798 | } |
| 763 | 799 | ||
| 764 | /// <summary> | 800 | /// <summary> |
| @@ -1134,16 +1170,57 @@ namespace WixToolset.Core | |||
| 1134 | private void ParseBundleExtensionElement(XElement node) | 1170 | private void ParseBundleExtensionElement(XElement node) |
| 1135 | { | 1171 | { |
| 1136 | var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); | 1172 | var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); |
| 1173 | var compilerPayload = new CompilerPayload(this.Core, sourceLineNumbers, node); | ||
| 1137 | Identifier previousId = null; | 1174 | Identifier previousId = null; |
| 1138 | var previousType = ComplexReferenceChildType.Unknown; | 1175 | var previousType = ComplexReferenceChildType.Unknown; |
| 1139 | 1176 | ||
| 1140 | // The BundleExtension element acts like a Payload element so delegate to the "Payload" attribute parsing code to parse and create a Payload entry. | 1177 | // This list lets us evaluate extension attributes *after* all core attributes |
| 1141 | if (this.ParsePayloadElementContent(node, ComplexReferenceParentType.Container, Compiler.BurnUXContainerId, previousType, previousId, true, out var id)) | 1178 | // have been parsed and dealt with, regardless of authoring order. |
| 1179 | var extensionAttributes = new List<XAttribute>(); | ||
| 1180 | |||
| 1181 | foreach (var attrib in node.Attributes()) | ||
| 1142 | { | 1182 | { |
| 1143 | previousId = id; | 1183 | if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace) |
| 1144 | previousType = ComplexReferenceChildType.Payload; | 1184 | { |
| 1185 | switch (attrib.Name.LocalName) | ||
| 1186 | { | ||
| 1187 | case "Id": | ||
| 1188 | compilerPayload.ParseId(attrib); | ||
| 1189 | break; | ||
| 1190 | case "Name": | ||
| 1191 | compilerPayload.ParseName(attrib); | ||
| 1192 | break; | ||
| 1193 | case "SourceFile": | ||
| 1194 | compilerPayload.ParseSourceFile(attrib); | ||
| 1195 | break; | ||
| 1196 | default: | ||
| 1197 | this.Core.UnexpectedAttribute(node, attrib); | ||
| 1198 | break; | ||
| 1199 | } | ||
| 1200 | } | ||
| 1201 | else | ||
| 1202 | { | ||
| 1203 | extensionAttributes.Add(attrib); | ||
| 1204 | } | ||
| 1145 | } | 1205 | } |
| 1146 | 1206 | ||
| 1207 | compilerPayload.FinishCompilingPayload(); | ||
| 1208 | |||
| 1209 | // Now that the Id is known, we can parse the extension attributes. | ||
| 1210 | var context = new Dictionary<string, string> | ||
| 1211 | { | ||
| 1212 | ["Id"] = compilerPayload.Id.Id, | ||
| 1213 | }; | ||
| 1214 | |||
| 1215 | foreach (var extensionAttribute in extensionAttributes) | ||
| 1216 | { | ||
| 1217 | this.Core.ParseExtensionAttribute(node, extensionAttribute, context); | ||
| 1218 | } | ||
| 1219 | |||
| 1220 | compilerPayload.CreatePayloadSymbol(ComplexReferenceParentType.Container, Compiler.BurnUXContainerId.Id, previousType, previousId?.Id); | ||
| 1221 | previousId = compilerPayload.Id; | ||
| 1222 | previousType = ComplexReferenceChildType.Payload; | ||
| 1223 | |||
| 1147 | foreach (var child in node.Elements()) | 1224 | foreach (var child in node.Elements()) |
| 1148 | { | 1225 | { |
| 1149 | if (CompilerCore.WixNamespace == child.Name.Namespace) | 1226 | if (CompilerCore.WixNamespace == child.Name.Namespace) |
| @@ -1172,9 +1249,9 @@ namespace WixToolset.Core | |||
| 1172 | // Add the BundleExtension. | 1249 | // Add the BundleExtension. |
| 1173 | if (!this.Core.EncounteredError) | 1250 | if (!this.Core.EncounteredError) |
| 1174 | { | 1251 | { |
| 1175 | this.Core.AddSymbol(new WixBundleExtensionSymbol(sourceLineNumbers, id) | 1252 | this.Core.AddSymbol(new WixBundleExtensionSymbol(sourceLineNumbers, compilerPayload.Id) |
| 1176 | { | 1253 | { |
| 1177 | PayloadRef = id.Id, | 1254 | PayloadRef = compilerPayload.Id.Id, |
| 1178 | }); | 1255 | }); |
| 1179 | } | 1256 | } |
| 1180 | } | 1257 | } |
| @@ -1294,53 +1371,8 @@ namespace WixToolset.Core | |||
| 1294 | Debug.Assert(ComplexReferenceParentType.PayloadGroup == parentType || ComplexReferenceParentType.Package == parentType || ComplexReferenceParentType.Container == parentType); | 1371 | Debug.Assert(ComplexReferenceParentType.PayloadGroup == parentType || ComplexReferenceParentType.Package == parentType || ComplexReferenceParentType.Container == parentType); |
| 1295 | Debug.Assert(ComplexReferenceChildType.Unknown == previousType || ComplexReferenceChildType.PayloadGroup == previousType || ComplexReferenceChildType.Payload == previousType); | 1372 | Debug.Assert(ComplexReferenceChildType.Unknown == previousType || ComplexReferenceChildType.PayloadGroup == previousType || ComplexReferenceChildType.Payload == previousType); |
| 1296 | 1373 | ||
| 1297 | this.ParsePayloadElementContent(node, parentType, parentId, previousType, previousId, true, out var id); | ||
| 1298 | var context = new Dictionary<string, string> | ||
| 1299 | { | ||
| 1300 | ["Id"] = id?.Id | ||
| 1301 | }; | ||
| 1302 | |||
| 1303 | foreach (var child in node.Elements()) | ||
| 1304 | { | ||
| 1305 | if (CompilerCore.WixNamespace == child.Name.Namespace) | ||
| 1306 | { | ||
| 1307 | switch (child.Name.LocalName) | ||
| 1308 | { | ||
| 1309 | default: | ||
| 1310 | this.Core.UnexpectedElement(node, child); | ||
| 1311 | break; | ||
| 1312 | } | ||
| 1313 | } | ||
| 1314 | else | ||
| 1315 | { | ||
| 1316 | this.Core.ParseExtensionElement(node, child, context); | ||
| 1317 | } | ||
| 1318 | } | ||
| 1319 | |||
| 1320 | return id; | ||
| 1321 | } | ||
| 1322 | |||
| 1323 | /// <summary> | ||
| 1324 | /// Parse the attributes of the Payload element. | ||
| 1325 | /// </summary> | ||
| 1326 | /// <param name="node">Element to parse</param> | ||
| 1327 | /// <param name="parentType">ComplexReferenceParentType of parent element.</param> | ||
| 1328 | /// <param name="parentId">Identifier of parent element.</param> | ||
| 1329 | /// <param name="previousType"></param> | ||
| 1330 | /// <param name="previousId"></param> | ||
| 1331 | /// <param name="required"></param> | ||
| 1332 | /// <param name="id"></param> | ||
| 1333 | /// <returns>Whether SourceFile was specified.</returns> | ||
| 1334 | private bool ParsePayloadElementContent(XElement node, ComplexReferenceParentType parentType, Identifier parentId, ComplexReferenceChildType previousType, Identifier previousId, bool required, out Identifier id) | ||
| 1335 | { | ||
| 1336 | Debug.Assert(ComplexReferenceParentType.PayloadGroup == parentType || ComplexReferenceParentType.Package == parentType || ComplexReferenceParentType.Container == parentType); | ||
| 1337 | |||
| 1338 | var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); | 1374 | var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); |
| 1339 | var compressed = YesNoDefaultType.Default; | 1375 | var compilerPayload = new CompilerPayload(this.Core, sourceLineNumbers, node); |
| 1340 | id = null; | ||
| 1341 | string name = null; | ||
| 1342 | string sourceFile = null; | ||
| 1343 | string downloadUrl = null; | ||
| 1344 | 1376 | ||
| 1345 | // This list lets us evaluate extension attributes *after* all core attributes | 1377 | // This list lets us evaluate extension attributes *after* all core attributes |
| 1346 | // have been parsed and dealt with, regardless of authoring order. | 1378 | // have been parsed and dealt with, regardless of authoring order. |
| @@ -1350,32 +1382,32 @@ namespace WixToolset.Core | |||
| 1350 | { | 1382 | { |
| 1351 | if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace) | 1383 | if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace) |
| 1352 | { | 1384 | { |
| 1385 | var allowed = true; | ||
| 1353 | switch (attrib.Name.LocalName) | 1386 | switch (attrib.Name.LocalName) |
| 1354 | { | 1387 | { |
| 1355 | case "Id": | 1388 | case "Id": |
| 1356 | id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib); | 1389 | compilerPayload.ParseId(attrib); |
| 1357 | break; | 1390 | break; |
| 1358 | case "Compressed": | 1391 | case "Compressed": |
| 1359 | compressed = this.Core.GetAttributeYesNoDefaultValue(sourceLineNumbers, attrib); | 1392 | compilerPayload.ParseCompressed(attrib); |
| 1360 | break; | 1393 | break; |
| 1361 | case "Name": | 1394 | case "Name": |
| 1362 | name = this.Core.GetAttributeLongFilename(sourceLineNumbers, attrib, false, true); | 1395 | compilerPayload.ParseName(attrib); |
| 1363 | break; | 1396 | break; |
| 1364 | case "SourceFile": | 1397 | case "SourceFile": |
| 1365 | sourceFile = this.Core.GetAttributeValue(sourceLineNumbers, attrib); | 1398 | compilerPayload.ParseSourceFile(attrib); |
| 1366 | break; | 1399 | break; |
| 1367 | case "DownloadUrl": | 1400 | case "DownloadUrl": |
| 1368 | downloadUrl = this.Core.GetAttributeValue(sourceLineNumbers, attrib); | 1401 | compilerPayload.ParseDownloadUrl(attrib); |
| 1369 | break; | 1402 | break; |
| 1370 | case "DpiAwareness": | 1403 | default: |
| 1371 | if (node.Name.LocalName != "BootstrapperApplicationDll") | 1404 | allowed = false; |
| 1372 | { | 1405 | break; |
| 1373 | this.Core.UnexpectedAttribute(node, attrib); | 1406 | } |
| 1374 | } | 1407 | |
| 1375 | break; | 1408 | if (!allowed) |
| 1376 | default: | 1409 | { |
| 1377 | this.Core.UnexpectedAttribute(node, attrib); | 1410 | this.Core.UnexpectedAttribute(node, attrib); |
| 1378 | break; | ||
| 1379 | } | 1411 | } |
| 1380 | } | 1412 | } |
| 1381 | else | 1413 | else |
| @@ -1384,15 +1416,12 @@ namespace WixToolset.Core | |||
| 1384 | } | 1416 | } |
| 1385 | } | 1417 | } |
| 1386 | 1418 | ||
| 1387 | if (null == id) | 1419 | compilerPayload.FinishCompilingPayload(); |
| 1388 | { | ||
| 1389 | id = this.Core.CreateIdentifier("pay", sourceFile?.ToUpperInvariant() ?? String.Empty); | ||
| 1390 | } | ||
| 1391 | 1420 | ||
| 1392 | // Now that the PayloadId is known, we can parse the extension attributes. | 1421 | // Now that the PayloadId is known, we can parse the extension attributes. |
| 1393 | var context = new Dictionary<string, string> | 1422 | var context = new Dictionary<string, string> |
| 1394 | { | 1423 | { |
| 1395 | ["Id"] = id.Id | 1424 | ["Id"] = compilerPayload.Id.Id, |
| 1396 | }; | 1425 | }; |
| 1397 | 1426 | ||
| 1398 | foreach (var extensionAttribute in extensionAttributes) | 1427 | foreach (var extensionAttribute in extensionAttributes) |
| @@ -1400,36 +1429,32 @@ namespace WixToolset.Core | |||
| 1400 | this.Core.ParseExtensionAttribute(node, extensionAttribute, context); | 1429 | this.Core.ParseExtensionAttribute(node, extensionAttribute, context); |
| 1401 | } | 1430 | } |
| 1402 | 1431 | ||
| 1403 | // Let caller handle the children. | 1432 | foreach (var child in node.Elements()) |
| 1404 | |||
| 1405 | if (Compiler.BurnUXContainerId == parentId) | ||
| 1406 | { | 1433 | { |
| 1407 | if (compressed == YesNoDefaultType.No) | 1434 | if (CompilerCore.WixNamespace == child.Name.Namespace) |
| 1408 | { | 1435 | { |
| 1409 | this.Core.Write(WarningMessages.UxPayloadsOnlySupportEmbedding(sourceLineNumbers, sourceFile)); | 1436 | switch (child.Name.LocalName) |
| 1437 | { | ||
| 1438 | default: | ||
| 1439 | this.Core.UnexpectedElement(node, child); | ||
| 1440 | break; | ||
| 1441 | } | ||
| 1410 | } | 1442 | } |
| 1411 | 1443 | else | |
| 1412 | compressed = YesNoDefaultType.Yes; | ||
| 1413 | } | ||
| 1414 | |||
| 1415 | if (sourceFile == null) | ||
| 1416 | { | ||
| 1417 | if (required) | ||
| 1418 | { | 1444 | { |
| 1419 | this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "SourceFile")); | 1445 | this.Core.ParseExtensionElement(node, child, context); |
| 1420 | } | 1446 | } |
| 1421 | return false; | ||
| 1422 | } | 1447 | } |
| 1423 | 1448 | ||
| 1424 | this.CreatePayloadRow(sourceLineNumbers, id, name, sourceFile, downloadUrl, parentType, parentId, previousType, previousId, compressed, null, null, null); | 1449 | compilerPayload.CreatePayloadSymbol(parentType, parentId?.Id, previousType, previousId?.Id); |
| 1425 | 1450 | ||
| 1426 | return true; | 1451 | return compilerPayload.Id; |
| 1427 | } | 1452 | } |
| 1428 | 1453 | ||
| 1429 | private RemotePayload ParseRemotePayloadElement(XElement node) | 1454 | private CompilerPayload ParseRemotePayloadElement(XElement node) |
| 1430 | { | 1455 | { |
| 1431 | var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); | 1456 | var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); |
| 1432 | var remotePayload = new RemotePayload(); | 1457 | var remotePayload = new CompilerPayload(this.Core, sourceLineNumbers, node); |
| 1433 | 1458 | ||
| 1434 | foreach (var attrib in node.Attributes()) | 1459 | foreach (var attrib in node.Attributes()) |
| 1435 | { | 1460 | { |
| @@ -1438,19 +1463,19 @@ namespace WixToolset.Core | |||
| 1438 | switch (attrib.Name.LocalName) | 1463 | switch (attrib.Name.LocalName) |
| 1439 | { | 1464 | { |
| 1440 | case "Description": | 1465 | case "Description": |
| 1441 | remotePayload.Description = this.Core.GetAttributeValue(sourceLineNumbers, attrib); | 1466 | remotePayload.ParseDescription(attrib); |
| 1442 | break; | 1467 | break; |
| 1443 | case "Hash": | 1468 | case "Hash": |
| 1444 | remotePayload.Hash = this.Core.GetAttributeValue(sourceLineNumbers, attrib); | 1469 | remotePayload.ParseHash(attrib); |
| 1445 | break; | 1470 | break; |
| 1446 | case "ProductName": | 1471 | case "ProductName": |
| 1447 | remotePayload.ProductName = this.Core.GetAttributeValue(sourceLineNumbers, attrib); | 1472 | remotePayload.ParseProductName(attrib); |
| 1448 | break; | 1473 | break; |
| 1449 | case "Size": | 1474 | case "Size": |
| 1450 | remotePayload.Size = this.Core.GetAttributeLongValue(sourceLineNumbers, attrib, 0, Int64.MaxValue); | 1475 | remotePayload.ParseSize(attrib); |
| 1451 | break; | 1476 | break; |
| 1452 | case "Version": | 1477 | case "Version": |
| 1453 | remotePayload.Version = this.Core.GetAttributeValue(sourceLineNumbers, attrib); | 1478 | remotePayload.ParseVersion(attrib); |
| 1454 | break; | 1479 | break; |
| 1455 | default: | 1480 | default: |
| 1456 | this.Core.UnexpectedAttribute(node, attrib); | 1481 | this.Core.UnexpectedAttribute(node, attrib); |
| @@ -1492,57 +1517,6 @@ namespace WixToolset.Core | |||
| 1492 | } | 1517 | } |
| 1493 | 1518 | ||
| 1494 | /// <summary> | 1519 | /// <summary> |
| 1495 | /// Creates the row for a Payload. | ||
| 1496 | /// </summary> | ||
| 1497 | /// <param name="sourceLineNumbers"></param> | ||
| 1498 | /// <param name="id"></param> | ||
| 1499 | /// <param name="name"></param> | ||
| 1500 | /// <param name="sourceFile"></param> | ||
| 1501 | /// <param name="downloadUrl"></param> | ||
| 1502 | /// <param name="parentType">ComplexReferenceParentType of parent element</param> | ||
| 1503 | /// <param name="parentId">Identifier of parent element.</param> | ||
| 1504 | /// <param name="previousType"></param> | ||
| 1505 | /// <param name="previousId"></param> | ||
| 1506 | /// <param name="compressed"></param> | ||
| 1507 | /// <param name="displayName"></param> | ||
| 1508 | /// <param name="description"></param> | ||
| 1509 | /// <param name="remotePayload"></param> | ||
| 1510 | /// <returns></returns> | ||
| 1511 | private WixBundlePayloadSymbol CreatePayloadRow(SourceLineNumber sourceLineNumbers, Identifier id, string name, string sourceFile, string downloadUrl, ComplexReferenceParentType parentType, | ||
| 1512 | Identifier parentId, ComplexReferenceChildType previousType, Identifier previousId, YesNoDefaultType compressed, string displayName, string description, | ||
| 1513 | RemotePayload remotePayload) | ||
| 1514 | { | ||
| 1515 | WixBundlePayloadSymbol symbol = null; | ||
| 1516 | |||
| 1517 | if (!this.Core.EncounteredError) | ||
| 1518 | { | ||
| 1519 | symbol = this.Core.AddSymbol(new WixBundlePayloadSymbol(sourceLineNumbers, id) | ||
| 1520 | { | ||
| 1521 | Name = String.IsNullOrEmpty(name) ? Path.GetFileName(sourceFile) : name, | ||
| 1522 | SourceFile = new IntermediateFieldPathValue { Path = sourceFile }, | ||
| 1523 | DownloadUrl = downloadUrl, | ||
| 1524 | Compressed = (compressed == YesNoDefaultType.Yes) ? true : (compressed == YesNoDefaultType.No) ? (bool?)false : null, | ||
| 1525 | UnresolvedSourceFile = sourceFile, // duplicate of sourceFile but in a string column so it won't get resolved to a full path during binding. | ||
| 1526 | DisplayName = displayName, | ||
| 1527 | Description = description, | ||
| 1528 | }); | ||
| 1529 | |||
| 1530 | if (null != remotePayload) | ||
| 1531 | { | ||
| 1532 | symbol.Description = remotePayload.Description; | ||
| 1533 | symbol.DisplayName = remotePayload.ProductName; | ||
| 1534 | symbol.Hash = remotePayload.Hash; | ||
| 1535 | symbol.FileSize = remotePayload.Size; | ||
| 1536 | symbol.Version = remotePayload.Version; | ||
| 1537 | } | ||
| 1538 | |||
| 1539 | this.CreateGroupAndOrderingRows(sourceLineNumbers, parentType, parentId.Id, ComplexReferenceChildType.Payload, id.Id, previousType, previousId?.Id); | ||
| 1540 | } | ||
| 1541 | |||
| 1542 | return symbol; | ||
| 1543 | } | ||
| 1544 | |||
| 1545 | /// <summary> | ||
| 1546 | /// Parse PayloadGroup element. | 1520 | /// Parse PayloadGroup element. |
| 1547 | /// </summary> | 1521 | /// </summary> |
| 1548 | /// <param name="node">Element to parse</param> | 1522 | /// <param name="node">Element to parse</param> |
| @@ -1613,7 +1587,7 @@ namespace WixToolset.Core | |||
| 1613 | { | 1587 | { |
| 1614 | this.Core.AddSymbol(new WixBundlePayloadGroupSymbol(sourceLineNumbers, id)); | 1588 | this.Core.AddSymbol(new WixBundlePayloadGroupSymbol(sourceLineNumbers, id)); |
| 1615 | 1589 | ||
| 1616 | this.CreateGroupAndOrderingRows(sourceLineNumbers, parentType, parentId?.Id, ComplexReferenceChildType.PayloadGroup, id.Id, ComplexReferenceChildType.Unknown, null); | 1590 | this.Core.CreateGroupAndOrderingRows(sourceLineNumbers, parentType, parentId?.Id, ComplexReferenceChildType.PayloadGroup, id.Id, ComplexReferenceChildType.Unknown, null); |
| 1617 | } | 1591 | } |
| 1618 | } | 1592 | } |
| 1619 | 1593 | ||
| @@ -1661,52 +1635,12 @@ namespace WixToolset.Core | |||
| 1661 | 1635 | ||
| 1662 | this.Core.ParseForExtensionElements(node); | 1636 | this.Core.ParseForExtensionElements(node); |
| 1663 | 1637 | ||
| 1664 | this.CreateGroupAndOrderingRows(sourceLineNumbers, parentType, parentId?.Id, ComplexReferenceChildType.PayloadGroup, id?.Id, previousType, previousId?.Id); | 1638 | this.Core.CreateGroupAndOrderingRows(sourceLineNumbers, parentType, parentId?.Id, ComplexReferenceChildType.PayloadGroup, id?.Id, previousType, previousId?.Id); |
| 1665 | 1639 | ||
| 1666 | return id; | 1640 | return id; |
| 1667 | } | 1641 | } |
| 1668 | 1642 | ||
| 1669 | /// <summary> | 1643 | /// <summary> |
| 1670 | /// Creates group and ordering information. | ||
| 1671 | /// </summary> | ||
| 1672 | /// <param name="sourceLineNumbers">Source line numbers.</param> | ||
| 1673 | /// <param name="parentType">Type of parent group, if known.</param> | ||
| 1674 | /// <param name="parentId">Identifier of parent group, if known.</param> | ||
| 1675 | /// <param name="type">Type of this item.</param> | ||
| 1676 | /// <param name="id">Identifier for this item.</param> | ||
| 1677 | /// <param name="previousType">Type of previous item, if known.</param> | ||
| 1678 | /// <param name="previousId">Identifier of previous item, if known</param> | ||
| 1679 | private void CreateGroupAndOrderingRows(SourceLineNumber sourceLineNumbers, | ||
| 1680 | ComplexReferenceParentType parentType, string parentId, | ||
| 1681 | ComplexReferenceChildType type, string id, | ||
| 1682 | ComplexReferenceChildType previousType, string previousId) | ||
| 1683 | { | ||
| 1684 | if (this.Core.EncounteredError) | ||
| 1685 | { | ||
| 1686 | return; | ||
| 1687 | } | ||
| 1688 | |||
| 1689 | if (ComplexReferenceParentType.Unknown != parentType && null != parentId) | ||
| 1690 | { | ||
| 1691 | this.Core.CreateWixGroupRow(sourceLineNumbers, parentType, parentId, type, id); | ||
| 1692 | } | ||
| 1693 | |||
| 1694 | if (ComplexReferenceChildType.Unknown != previousType && null != previousId) | ||
| 1695 | { | ||
| 1696 | // TODO: Should we define our own enum for this, just to ensure there's no "cross-contamination"? | ||
| 1697 | // TODO: Also, we could potentially include an 'Attributes' field to track things like | ||
| 1698 | // 'before' vs. 'after', and explicit vs. inferred dependencies. | ||
| 1699 | this.Core.AddSymbol(new WixOrderingSymbol(sourceLineNumbers) | ||
| 1700 | { | ||
| 1701 | ItemType = type, | ||
| 1702 | ItemIdRef = id, | ||
| 1703 | DependsOnType = previousType, | ||
| 1704 | DependsOnIdRef = previousId | ||
| 1705 | }); | ||
| 1706 | } | ||
| 1707 | } | ||
| 1708 | |||
| 1709 | /// <summary> | ||
| 1710 | /// Parse ExitCode element. | 1644 | /// Parse ExitCode element. |
| 1711 | /// </summary> | 1645 | /// </summary> |
| 1712 | /// <param name="node">Element to parse</param> | 1646 | /// <param name="node">Element to parse</param> |
| @@ -2050,17 +1984,15 @@ namespace WixToolset.Core | |||
| 2050 | Debug.Assert(ComplexReferenceParentType.PackageGroup == parentType); | 1984 | Debug.Assert(ComplexReferenceParentType.PackageGroup == parentType); |
| 2051 | Debug.Assert(ComplexReferenceChildType.Unknown == previousType || ComplexReferenceChildType.PackageGroup == previousType || ComplexReferenceChildType.Package == previousType); | 1985 | Debug.Assert(ComplexReferenceChildType.Unknown == previousType || ComplexReferenceChildType.PackageGroup == previousType || ComplexReferenceChildType.Package == previousType); |
| 2052 | 1986 | ||
| 2053 | var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); | 1987 | var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);; |
| 2054 | Identifier id = null; | 1988 | var compilerPayload = new CompilerPayload(this.Core, sourceLineNumbers, node) |
| 2055 | string name = null; | 1989 | { |
| 2056 | string sourceFile = null; | 1990 | IsRequired = false, |
| 2057 | string downloadUrl = null; | 1991 | }; |
| 2058 | string after = null; | 1992 | string after = null; |
| 2059 | string installCondition = null; | 1993 | string installCondition = null; |
| 2060 | var cache = YesNoAlwaysType.Yes; // the default is to cache everything in tradeoff for stability over disk space. | 1994 | var cache = YesNoAlwaysType.Yes; // the default is to cache everything in tradeoff for stability over disk space. |
| 2061 | string cacheId = null; | 1995 | string cacheId = null; |
| 2062 | string description = null; | ||
| 2063 | string displayName = null; | ||
| 2064 | var logPathVariable = (packageType == WixBundlePackageType.Msu) ? String.Empty : null; | 1996 | var logPathVariable = (packageType == WixBundlePackageType.Msu) ? String.Empty : null; |
| 2065 | var rollbackPathVariable = (packageType == WixBundlePackageType.Msu) ? String.Empty : null; | 1997 | var rollbackPathVariable = (packageType == WixBundlePackageType.Msu) ? String.Empty : null; |
| 2066 | var permanent = YesNoType.NotSet; | 1998 | var permanent = YesNoType.NotSet; |
| @@ -2074,10 +2006,9 @@ namespace WixToolset.Core | |||
| 2074 | string protocol = null; | 2006 | string protocol = null; |
| 2075 | var installSize = CompilerConstants.IntegerNotSet; | 2007 | var installSize = CompilerConstants.IntegerNotSet; |
| 2076 | string msuKB = null; | 2008 | string msuKB = null; |
| 2077 | var compressed = YesNoDefaultType.Default; | ||
| 2078 | var enableFeatureSelection = YesNoType.NotSet; | 2009 | var enableFeatureSelection = YesNoType.NotSet; |
| 2079 | var forcePerMachine = YesNoType.NotSet; | 2010 | var forcePerMachine = YesNoType.NotSet; |
| 2080 | RemotePayload remotePayload = null; | 2011 | CompilerPayload remotePayload = null; |
| 2081 | var slipstream = YesNoType.NotSet; | 2012 | var slipstream = YesNoType.NotSet; |
| 2082 | 2013 | ||
| 2083 | var expectedNetFx4Args = new string[] { "/q", "/norestart", "/chainingpackage" }; | 2014 | var expectedNetFx4Args = new string[] { "/q", "/norestart", "/chainingpackage" }; |
| @@ -2094,20 +2025,16 @@ namespace WixToolset.Core | |||
| 2094 | switch (attrib.Name.LocalName) | 2025 | switch (attrib.Name.LocalName) |
| 2095 | { | 2026 | { |
| 2096 | case "Id": | 2027 | case "Id": |
| 2097 | id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib); | 2028 | compilerPayload.ParseId(attrib); |
| 2098 | break; | 2029 | break; |
| 2099 | case "Name": | 2030 | case "Name": |
| 2100 | name = this.Core.GetAttributeLongFilename(sourceLineNumbers, attrib, false, true); | 2031 | compilerPayload.ParseName(attrib); |
| 2101 | if (!this.Core.IsValidLongFilename(name, false, true)) | ||
| 2102 | { | ||
| 2103 | this.Core.Write(ErrorMessages.IllegalLongFilename(sourceLineNumbers, node.Name.LocalName, "Name", name)); | ||
| 2104 | } | ||
| 2105 | break; | 2032 | break; |
| 2106 | case "SourceFile": | 2033 | case "SourceFile": |
| 2107 | sourceFile = this.Core.GetAttributeValue(sourceLineNumbers, attrib); | 2034 | compilerPayload.ParseSourceFile(attrib); |
| 2108 | break; | 2035 | break; |
| 2109 | case "DownloadUrl": | 2036 | case "DownloadUrl": |
| 2110 | downloadUrl = this.Core.GetAttributeValue(sourceLineNumbers, attrib); | 2037 | compilerPayload.ParseDownloadUrl(attrib); |
| 2111 | break; | 2038 | break; |
| 2112 | case "After": | 2039 | case "After": |
| 2113 | after = this.Core.GetAttributeValue(sourceLineNumbers, attrib); | 2040 | after = this.Core.GetAttributeValue(sourceLineNumbers, attrib); |
| @@ -2139,10 +2066,10 @@ namespace WixToolset.Core | |||
| 2139 | cacheId = this.Core.GetAttributeValue(sourceLineNumbers, attrib); | 2066 | cacheId = this.Core.GetAttributeValue(sourceLineNumbers, attrib); |
| 2140 | break; | 2067 | break; |
| 2141 | case "Description": | 2068 | case "Description": |
| 2142 | description = this.Core.GetAttributeValue(sourceLineNumbers, attrib); | 2069 | compilerPayload.ParseDescription(attrib); |
| 2143 | break; | 2070 | break; |
| 2144 | case "DisplayName": | 2071 | case "DisplayName": |
| 2145 | displayName = this.Core.GetAttributeValue(sourceLineNumbers, attrib); | 2072 | compilerPayload.ParseDisplayName(attrib); |
| 2146 | break; | 2073 | break; |
| 2147 | case "EnableFeatureSelection": | 2074 | case "EnableFeatureSelection": |
| 2148 | enableFeatureSelection = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib); | 2075 | enableFeatureSelection = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib); |
| @@ -2200,7 +2127,7 @@ namespace WixToolset.Core | |||
| 2200 | allowed = (packageType == WixBundlePackageType.Msu); | 2127 | allowed = (packageType == WixBundlePackageType.Msu); |
| 2201 | break; | 2128 | break; |
| 2202 | case "Compressed": | 2129 | case "Compressed": |
| 2203 | compressed = this.Core.GetAttributeYesNoDefaultValue(sourceLineNumbers, attrib); | 2130 | compilerPayload.ParseCompressed(attrib); |
| 2204 | break; | 2131 | break; |
| 2205 | case "Slipstream": | 2132 | case "Slipstream": |
| 2206 | slipstream = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib); | 2133 | slipstream = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib); |
| @@ -2242,65 +2169,8 @@ namespace WixToolset.Core | |||
| 2242 | remotePayload = this.ParseRemotePayloadElement(child); | 2169 | remotePayload = this.ParseRemotePayloadElement(child); |
| 2243 | } | 2170 | } |
| 2244 | 2171 | ||
| 2245 | if (String.IsNullOrEmpty(sourceFile)) | 2172 | compilerPayload.FinishCompilingPackage(remotePayload); |
| 2246 | { | 2173 | var id = compilerPayload.Id; |
| 2247 | if (String.IsNullOrEmpty(name)) | ||
| 2248 | { | ||
| 2249 | this.Core.Write(ErrorMessages.ExpectedAttributesWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "Name", "SourceFile")); | ||
| 2250 | } | ||
| 2251 | else if (null == remotePayload) | ||
| 2252 | { | ||
| 2253 | sourceFile = Path.Combine("SourceDir", name); | ||
| 2254 | } | ||
| 2255 | } | ||
| 2256 | else if (null != remotePayload) | ||
| 2257 | { | ||
| 2258 | this.Core.Write(ErrorMessages.UnexpectedElementWithAttribute(sourceLineNumbers, node.Name.LocalName, "RemotePayload", "SourceFile")); | ||
| 2259 | } | ||
| 2260 | else if (sourceFile.EndsWith(Path.DirectorySeparatorChar.ToString(), StringComparison.Ordinal)) | ||
| 2261 | { | ||
| 2262 | if (String.IsNullOrEmpty(name)) | ||
| 2263 | { | ||
| 2264 | this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Name", "SourceFile", sourceFile)); | ||
| 2265 | } | ||
| 2266 | else | ||
| 2267 | { | ||
| 2268 | sourceFile = Path.Combine(sourceFile, Path.GetFileName(name)); | ||
| 2269 | } | ||
| 2270 | } | ||
| 2271 | |||
| 2272 | if (null == downloadUrl && null != remotePayload) | ||
| 2273 | { | ||
| 2274 | this.Core.Write(ErrorMessages.ExpectedAttributeWithElement(sourceLineNumbers, node.Name.LocalName, "DownloadUrl", "RemotePayload")); | ||
| 2275 | } | ||
| 2276 | |||
| 2277 | if (YesNoDefaultType.No != compressed && null != remotePayload) | ||
| 2278 | { | ||
| 2279 | compressed = YesNoDefaultType.No; | ||
| 2280 | this.Core.Write(WarningMessages.RemotePayloadsMustNotAlsoBeCompressed(sourceLineNumbers, node.Name.LocalName)); | ||
| 2281 | } | ||
| 2282 | |||
| 2283 | if (null == id) | ||
| 2284 | { | ||
| 2285 | if (!String.IsNullOrEmpty(name)) | ||
| 2286 | { | ||
| 2287 | id = this.Core.CreateIdentifierFromFilename(Path.GetFileName(name)); | ||
| 2288 | } | ||
| 2289 | else if (!String.IsNullOrEmpty(sourceFile)) | ||
| 2290 | { | ||
| 2291 | id = this.Core.CreateIdentifierFromFilename(Path.GetFileName(sourceFile)); | ||
| 2292 | } | ||
| 2293 | |||
| 2294 | if (null == id) | ||
| 2295 | { | ||
| 2296 | this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); | ||
| 2297 | id = Identifier.Invalid; | ||
| 2298 | } | ||
| 2299 | else if (!Common.IsIdentifier(id.Id)) | ||
| 2300 | { | ||
| 2301 | this.Core.Write(ErrorMessages.IllegalIdentifier(sourceLineNumbers, node.Name.LocalName, "Id", id.Id)); | ||
| 2302 | } | ||
| 2303 | } | ||
| 2304 | 2174 | ||
| 2305 | if (null == logPathVariable) | 2175 | if (null == logPathVariable) |
| 2306 | { | 2176 | { |
| @@ -2424,7 +2294,7 @@ namespace WixToolset.Core | |||
| 2424 | } | 2294 | } |
| 2425 | else | 2295 | else |
| 2426 | { | 2296 | { |
| 2427 | var context = new Dictionary<string, string>() { { "Id", id?.Id } }; | 2297 | var context = new Dictionary<string, string>() { { "Id", id.Id } }; |
| 2428 | this.Core.ParseExtensionElement(node, child, context); | 2298 | this.Core.ParseExtensionElement(node, child, context); |
| 2429 | } | 2299 | } |
| 2430 | } | 2300 | } |
| @@ -2432,8 +2302,7 @@ namespace WixToolset.Core | |||
| 2432 | if (!this.Core.EncounteredError) | 2302 | if (!this.Core.EncounteredError) |
| 2433 | { | 2303 | { |
| 2434 | // We create the package contents as a payload with this package as the parent | 2304 | // We create the package contents as a payload with this package as the parent |
| 2435 | this.CreatePayloadRow(sourceLineNumbers, id, name, sourceFile, downloadUrl, ComplexReferenceParentType.Package, id, | 2305 | compilerPayload.CreatePayloadSymbol(ComplexReferenceParentType.Package, id.Id); |
| 2436 | ComplexReferenceChildType.Unknown, null, compressed, displayName, description, remotePayload); | ||
| 2437 | 2306 | ||
| 2438 | this.Core.AddSymbol(new WixChainItemSymbol(sourceLineNumbers, id)); | 2307 | this.Core.AddSymbol(new WixChainItemSymbol(sourceLineNumbers, id)); |
| 2439 | 2308 | ||
| @@ -2801,7 +2670,7 @@ namespace WixToolset.Core | |||
| 2801 | previousId = afterId; | 2670 | previousId = afterId; |
| 2802 | } | 2671 | } |
| 2803 | 2672 | ||
| 2804 | this.CreateGroupAndOrderingRows(sourceLineNumbers, parentType, parentId, type, id, previousType, previousId); | 2673 | this.Core.CreateGroupAndOrderingRows(sourceLineNumbers, parentType, parentId, type, id, previousType, previousId); |
| 2805 | } | 2674 | } |
| 2806 | 2675 | ||
| 2807 | /// <summary> | 2676 | /// <summary> |
| @@ -3251,18 +3120,5 @@ namespace WixToolset.Core | |||
| 3251 | 3120 | ||
| 3252 | return WixBundleVariableType.String; | 3121 | return WixBundleVariableType.String; |
| 3253 | } | 3122 | } |
| 3254 | |||
| 3255 | private class RemotePayload | ||
| 3256 | { | ||
| 3257 | public string Description { get; set; } | ||
| 3258 | |||
| 3259 | public string Hash { get; set; } | ||
| 3260 | |||
| 3261 | public string ProductName { get; set; } | ||
| 3262 | |||
| 3263 | public long Size { get; set; } | ||
| 3264 | |||
| 3265 | public string Version { get; set; } | ||
| 3266 | } | ||
| 3267 | } | 3123 | } |
| 3268 | } | 3124 | } |
