diff options
author | Rob Mensching <rob@firegiant.com> | 2022-03-16 10:30:35 -0700 |
---|---|---|
committer | Rob Mensching <rob@firegiant.com> | 2022-03-17 06:50:22 -0700 |
commit | 581c320e04949300d6c3bee71fb5fc1a557f9263 (patch) | |
tree | 485247f29fbd8f7a8272250b4e361292ce016ca3 | |
parent | b279d9c6d38058ff60b8461b35f33d5c056334c9 (diff) | |
download | wix-581c320e04949300d6c3bee71fb5fc1a557f9263.tar.gz wix-581c320e04949300d6c3bee71fb5fc1a557f9263.tar.bz2 wix-581c320e04949300d6c3bee71fb5fc1a557f9263.zip |
Warn when an MSI or cabinet installed by an MSI is too large
Fixes 6408
6 files changed, 65 insertions, 11 deletions
diff --git a/src/api/wix/WixToolset.Data/WarningMessages.cs b/src/api/wix/WixToolset.Data/WarningMessages.cs index f555fd93..0c026b68 100644 --- a/src/api/wix/WixToolset.Data/WarningMessages.cs +++ b/src/api/wix/WixToolset.Data/WarningMessages.cs | |||
@@ -673,6 +673,16 @@ namespace WixToolset.Data | |||
673 | return Message(null, Ids.InvalidEnvironmentVariable, "The {0} environment variable is set to an invalid value of '{1}'. The default value '{2}' will be used instead.", environmentVariable, value, defaultValue); | 673 | return Message(null, Ids.InvalidEnvironmentVariable, "The {0} environment variable is set to an invalid value of '{1}'. The default value '{2}' will be used instead.", environmentVariable, value, defaultValue); |
674 | } | 674 | } |
675 | 675 | ||
676 | public static Message WindowsInstallerFileTooLarge(SourceLineNumber sourceLineNumbers, string path, string fileDescription) | ||
677 | { | ||
678 | if (String.IsNullOrEmpty(fileDescription)) | ||
679 | { | ||
680 | fileDescription = "MSI or cabinet"; | ||
681 | } | ||
682 | |||
683 | return Message(sourceLineNumbers, Ids.WindowsInstallerFileTooLarge, "The Windows Installer does not support {0} files larger than 2GB in size. Reduce the size or number of files embedded in '{1}' or the installation will likely fail with an unexpected error.", fileDescription, path); | ||
684 | } | ||
685 | |||
676 | private static Message Message(SourceLineNumber sourceLineNumber, Ids id, string format, params object[] args) | 686 | private static Message Message(SourceLineNumber sourceLineNumber, Ids id, string format, params object[] args) |
677 | { | 687 | { |
678 | return new Message(sourceLineNumber, MessageLevel.Warning, (int)id, format, args); | 688 | return new Message(sourceLineNumber, MessageLevel.Warning, (int)id, format, args); |
@@ -809,6 +819,7 @@ namespace WixToolset.Data | |||
809 | DetectConditionRecommended = 1153, | 819 | DetectConditionRecommended = 1153, |
810 | CollidingModularizationTypes = 1156, | 820 | CollidingModularizationTypes = 1156, |
811 | InvalidEnvironmentVariable = 1157, | 821 | InvalidEnvironmentVariable = 1157, |
822 | WindowsInstallerFileTooLarge = 1158, | ||
812 | UnavailableBundleConditionVariable = 1159, | 823 | UnavailableBundleConditionVariable = 1159, |
813 | } | 824 | } |
814 | } | 825 | } |
diff --git a/src/wix/WixToolset.Core.Burn/Bundles/ProcessMsiPackageCommand.cs b/src/wix/WixToolset.Core.Burn/Bundles/ProcessMsiPackageCommand.cs index 327c9cc9..b950d06c 100644 --- a/src/wix/WixToolset.Core.Burn/Bundles/ProcessMsiPackageCommand.cs +++ b/src/wix/WixToolset.Core.Burn/Bundles/ProcessMsiPackageCommand.cs | |||
@@ -63,6 +63,8 @@ namespace WixToolset.Core.Burn.Bundles | |||
63 | var compressed = false; | 63 | var compressed = false; |
64 | try | 64 | try |
65 | { | 65 | { |
66 | this.CheckIfWindowsInstallerFileTooLarge(packagePayload.SourceLineNumbers, sourcePath, "MSI"); | ||
67 | |||
66 | using (var db = new Database(sourcePath, OpenDatabase.ReadOnly)) | 68 | using (var db = new Database(sourcePath, OpenDatabase.ReadOnly)) |
67 | { | 69 | { |
68 | // Read data out of the msi database... | 70 | // Read data out of the msi database... |
@@ -397,6 +399,8 @@ namespace WixToolset.Core.Burn.Bundles | |||
397 | Packaging = packagePayload.Packaging, | 399 | Packaging = packagePayload.Packaging, |
398 | ParentPackagePayloadRef = packagePayload.Id.Id, | 400 | ParentPackagePayloadRef = packagePayload.Id.Id, |
399 | }); | 401 | }); |
402 | |||
403 | this.CheckIfWindowsInstallerFileTooLarge(this.Facade.PackageSymbol.SourceLineNumbers, payloadSourceFile, "cabinet"); | ||
400 | } | 404 | } |
401 | } | 405 | } |
402 | } | 406 | } |
@@ -546,6 +550,22 @@ namespace WixToolset.Core.Burn.Bundles | |||
546 | return resolvedPath; | 550 | return resolvedPath; |
547 | } | 551 | } |
548 | 552 | ||
553 | private void CheckIfWindowsInstallerFileTooLarge(SourceLineNumber sourceLineNumber, string path, string description) | ||
554 | { | ||
555 | // Best effort check to see if the file is too large for the Windows Installer. | ||
556 | try | ||
557 | { | ||
558 | var fi = new FileInfo(path); | ||
559 | if (fi.Length > Int32.MaxValue) | ||
560 | { | ||
561 | this.Messaging.Write(WarningMessages.WindowsInstallerFileTooLarge(sourceLineNumber, path, description)); | ||
562 | } | ||
563 | } | ||
564 | catch | ||
565 | { | ||
566 | } | ||
567 | } | ||
568 | |||
549 | private static string GetProperty(View view, string property) | 569 | private static string GetProperty(View view, string property) |
550 | { | 570 | { |
551 | using (var queryRecord = new Record(1)) | 571 | using (var queryRecord = new Record(1)) |
diff --git a/src/wix/WixToolset.Core.WindowsInstaller/Bind/BindDatabaseCommand.cs b/src/wix/WixToolset.Core.WindowsInstaller/Bind/BindDatabaseCommand.cs index f251dcc9..69a954eb 100644 --- a/src/wix/WixToolset.Core.WindowsInstaller/Bind/BindDatabaseCommand.cs +++ b/src/wix/WixToolset.Core.WindowsInstaller/Bind/BindDatabaseCommand.cs | |||
@@ -513,6 +513,19 @@ namespace WixToolset.Core.WindowsInstaller.Bind | |||
513 | trackedFiles.AddRange(command.TrackedFiles); | 513 | trackedFiles.AddRange(command.TrackedFiles); |
514 | } | 514 | } |
515 | 515 | ||
516 | // Best effort check to see if the MSI file is too large for the Windows Installer. | ||
517 | try | ||
518 | { | ||
519 | var fi = new FileInfo(this.OutputPath); | ||
520 | if (fi.Length > Int32.MaxValue) | ||
521 | { | ||
522 | this.Messaging.Write(WarningMessages.WindowsInstallerFileTooLarge(null, this.OutputPath, "MSI")); | ||
523 | } | ||
524 | } | ||
525 | catch | ||
526 | { | ||
527 | } | ||
528 | |||
516 | var trackedInputFiles = this.TrackInputFiles(data, trackedFiles); | 529 | var trackedInputFiles = this.TrackInputFiles(data, trackedFiles); |
517 | trackedFiles.AddRange(trackedInputFiles); | 530 | trackedFiles.AddRange(trackedInputFiles); |
518 | 531 | ||
diff --git a/src/wix/WixToolset.Core.WindowsInstaller/Bind/CabinetBuilder.cs b/src/wix/WixToolset.Core.WindowsInstaller/Bind/CabinetBuilder.cs index 13b079ad..49eaad42 100644 --- a/src/wix/WixToolset.Core.WindowsInstaller/Bind/CabinetBuilder.cs +++ b/src/wix/WixToolset.Core.WindowsInstaller/Bind/CabinetBuilder.cs | |||
@@ -165,7 +165,18 @@ namespace WixToolset.Core.WindowsInstaller.Bind | |||
165 | var cab = new Cabinet(cabinetPath); | 165 | var cab = new Cabinet(cabinetPath); |
166 | cab.Compress(files, cabinetWorkItem.CompressionLevel, maxCabinetSize, cabinetWorkItem.MaxThreshold); | 166 | cab.Compress(files, cabinetWorkItem.CompressionLevel, maxCabinetSize, cabinetWorkItem.MaxThreshold); |
167 | 167 | ||
168 | // TODO: Handle newCabNamesCallBackAddress from compression. | 168 | // Best effort check to see if the cabinet is too large for the Windows Installer. |
169 | try | ||
170 | { | ||
171 | var fi = new FileInfo(cabinetPath); | ||
172 | if (fi.Length > Int32.MaxValue) | ||
173 | { | ||
174 | this.Messaging.Write(WarningMessages.WindowsInstallerFileTooLarge(cabinetWorkItem.SourceLineNumber, cabinetPath, "cabinet")); | ||
175 | } | ||
176 | } | ||
177 | catch | ||
178 | { | ||
179 | } | ||
169 | } | 180 | } |
170 | } | 181 | } |
171 | } | 182 | } |
diff --git a/src/wix/WixToolset.Core.WindowsInstaller/Bind/CabinetWorkItem.cs b/src/wix/WixToolset.Core.WindowsInstaller/Bind/CabinetWorkItem.cs index 1990ea78..b1a29834 100644 --- a/src/wix/WixToolset.Core.WindowsInstaller/Bind/CabinetWorkItem.cs +++ b/src/wix/WixToolset.Core.WindowsInstaller/Bind/CabinetWorkItem.cs | |||
@@ -14,23 +14,28 @@ namespace WixToolset.Core.WindowsInstaller.Bind | |||
14 | /// <summary> | 14 | /// <summary> |
15 | /// Instantiate a new CabinetWorkItem. | 15 | /// Instantiate a new CabinetWorkItem. |
16 | /// </summary> | 16 | /// </summary> |
17 | /// <param name="sourceLineNumber">Source line number that requires the cabinet creation.</param> | ||
17 | /// <param name="fileFacades">The collection of files in this cabinet.</param> | 18 | /// <param name="fileFacades">The collection of files in this cabinet.</param> |
18 | /// <param name="cabinetFile">The cabinet file.</param> | 19 | /// <param name="cabinetFile">The cabinet file.</param> |
19 | /// <param name="maxThreshold">Maximum threshold for each cabinet.</param> | 20 | /// <param name="maxThreshold">Maximum threshold for each cabinet.</param> |
20 | /// <param name="compressionLevel">The compression level of the cabinet.</param> | 21 | /// <param name="compressionLevel">The compression level of the cabinet.</param> |
21 | /// <param name="modularizationSuffix">Modularization suffix used when building a Merge Module.</param> | 22 | /// <param name="modularizationSuffix">Modularization suffix used when building a Merge Module.</param> |
22 | /// <!--<param name="binderFileManager">The binder file manager.</param>--> | 23 | public CabinetWorkItem(SourceLineNumber sourceLineNumber, string cabinetFile, IEnumerable<IFileFacade> fileFacades, int maxThreshold, CompressionLevel compressionLevel, string modularizationSuffix) |
23 | public CabinetWorkItem(IEnumerable<IFileFacade> fileFacades, string cabinetFile, int maxThreshold, CompressionLevel compressionLevel, string modularizationSuffix /*, BinderFileManager binderFileManager*/) | ||
24 | { | 24 | { |
25 | this.SourceLineNumber = sourceLineNumber; | ||
25 | this.CabinetFile = cabinetFile; | 26 | this.CabinetFile = cabinetFile; |
26 | this.CompressionLevel = compressionLevel; | 27 | this.CompressionLevel = compressionLevel; |
27 | this.ModularizationSuffix = modularizationSuffix; | 28 | this.ModularizationSuffix = modularizationSuffix; |
28 | this.FileFacades = fileFacades; | 29 | this.FileFacades = fileFacades; |
29 | //this.BinderFileManager = binderFileManager; | ||
30 | this.MaxThreshold = maxThreshold; | 30 | this.MaxThreshold = maxThreshold; |
31 | } | 31 | } |
32 | 32 | ||
33 | /// <summary> | 33 | /// <summary> |
34 | /// Source line that requires the cabinet creation. | ||
35 | /// </summary> | ||
36 | public SourceLineNumber SourceLineNumber { get; } | ||
37 | |||
38 | /// <summary> | ||
34 | /// Gets the cabinet file. | 39 | /// Gets the cabinet file. |
35 | /// </summary> | 40 | /// </summary> |
36 | /// <value>The cabinet file.</value> | 41 | /// <value>The cabinet file.</value> |
@@ -53,12 +58,6 @@ namespace WixToolset.Core.WindowsInstaller.Bind | |||
53 | /// <value>The collection of files in this cabinet.</value> | 58 | /// <value>The collection of files in this cabinet.</value> |
54 | public IEnumerable<IFileFacade> FileFacades { get; } | 59 | public IEnumerable<IFileFacade> FileFacades { get; } |
55 | 60 | ||
56 | // <summary> | ||
57 | // Gets the binder file manager. | ||
58 | // </summary> | ||
59 | // <value>The binder file manager.</value> | ||
60 | //public BinderFileManager BinderFileManager { get; private set; } | ||
61 | |||
62 | /// <summary> | 61 | /// <summary> |
63 | /// Gets the max threshold. | 62 | /// Gets the max threshold. |
64 | /// </summary> | 63 | /// </summary> |
diff --git a/src/wix/WixToolset.Core.WindowsInstaller/Bind/CreateCabinetsCommand.cs b/src/wix/WixToolset.Core.WindowsInstaller/Bind/CreateCabinetsCommand.cs index 4ac248cd..2516a6fa 100644 --- a/src/wix/WixToolset.Core.WindowsInstaller/Bind/CreateCabinetsCommand.cs +++ b/src/wix/WixToolset.Core.WindowsInstaller/Bind/CreateCabinetsCommand.cs | |||
@@ -190,7 +190,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind | |||
190 | if (CabinetBuildOption.BuildAndCopy == resolvedCabinet.BuildOption || CabinetBuildOption.BuildAndMove == resolvedCabinet.BuildOption) | 190 | if (CabinetBuildOption.BuildAndCopy == resolvedCabinet.BuildOption || CabinetBuildOption.BuildAndMove == resolvedCabinet.BuildOption) |
191 | { | 191 | { |
192 | // Default to the threshold for best smartcabbing (makes smallest cabinet). | 192 | // Default to the threshold for best smartcabbing (makes smallest cabinet). |
193 | cabinetWorkItem = new CabinetWorkItem(fileFacades, resolvedCabinet.Path, maxThreshold: 0, compressionLevel, this.ModularizationSuffix /*, this.FileManager*/); | 193 | cabinetWorkItem = new CabinetWorkItem(mediaSymbol.SourceLineNumbers, resolvedCabinet.Path, fileFacades, maxThreshold: 0, compressionLevel: compressionLevel, modularizationSuffix: this.ModularizationSuffix); |
194 | } | 194 | } |
195 | else // reuse the cabinet from the cabinet cache. | 195 | else // reuse the cabinet from the cabinet cache. |
196 | { | 196 | { |