From 8b959ca40baf44454d03fd14ef98482c52417681 Mon Sep 17 00:00:00 2001 From: Rob Mensching Date: Fri, 11 Mar 2022 16:43:48 -0800 Subject: Handle case when invalid icon or splash screen are added to bundle Fixes 5330 --- .../wix/WixToolset.Data/Symbols/WixBundleSymbol.cs | 8 ++--- .../Bundles/CreateBundleExeCommand.cs | 35 +++++++++++++++------- src/wix/WixToolset.Core.Burn/BurnBackendErrors.cs | 25 ++++++++++++++++ src/wix/WixToolset.Core/Compiler_Bundle.cs | 4 +-- .../BundleFixture.cs | 28 +++++++++++++++++ .../BundleWithInvalid/BundleWithInvalidIcon.wxs | 11 +++++++ 6 files changed, 94 insertions(+), 17 deletions(-) create mode 100644 src/wix/test/WixToolsetTest.CoreIntegration/TestData/BundleWithInvalid/BundleWithInvalidIcon.wxs diff --git a/src/api/wix/WixToolset.Data/Symbols/WixBundleSymbol.cs b/src/api/wix/WixToolset.Data/Symbols/WixBundleSymbol.cs index de5646d3..72192c15 100644 --- a/src/api/wix/WixToolset.Data/Symbols/WixBundleSymbol.cs +++ b/src/api/wix/WixToolset.Data/Symbols/WixBundleSymbol.cs @@ -183,15 +183,15 @@ namespace WixToolset.Data.Symbols set => this.Set((int)WixBundleSymbolFields.LogExtension, value); } - public string IconSourceFile + public IntermediateFieldPathValue IconSourceFile { - get => (string)this.Fields[(int)WixBundleSymbolFields.IconSourceFile]; + get => this.Fields[(int)WixBundleSymbolFields.IconSourceFile].AsPath(); set => this.Set((int)WixBundleSymbolFields.IconSourceFile, value); } - public string SplashScreenSourceFile + public IntermediateFieldPathValue SplashScreenSourceFile { - get => (string)this.Fields[(int)WixBundleSymbolFields.SplashScreenSourceFile]; + get => this.Fields[(int)WixBundleSymbolFields.SplashScreenSourceFile].AsPath(); set => this.Set((int)WixBundleSymbolFields.SplashScreenSourceFile, value); } diff --git a/src/wix/WixToolset.Core.Burn/Bundles/CreateBundleExeCommand.cs b/src/wix/WixToolset.Core.Burn/Bundles/CreateBundleExeCommand.cs index 54f1dfc9..8211bf83 100644 --- a/src/wix/WixToolset.Core.Burn/Bundles/CreateBundleExeCommand.cs +++ b/src/wix/WixToolset.Core.Burn/Bundles/CreateBundleExeCommand.cs @@ -259,11 +259,11 @@ namespace WixToolset.Core.Burn.Bundles return new Version(major, minor, build, revision); } - private static void UpdateBurnResources(string bundleTempPath, string outputPath, WixBundleSymbol bundleInfo, Version windowsAssemblyVersion, byte[] applicationManifestData) + private void UpdateBurnResources(string bundleTempPath, string outputPath, WixBundleSymbol bundleInfo, Version windowsAssemblyVersion, byte[] applicationManifestData) { const int burnLocale = 1033; - var resources = new Dtf.Resources.ResourceCollection(); - var version = new Dtf.Resources.VersionResource("#1", burnLocale); + var resources = new ResourceCollection(); + var version = new VersionResource("#1", burnLocale); version.Load(bundleTempPath); resources.Add(version); @@ -292,10 +292,10 @@ namespace WixToolset.Core.Burn.Bundles strings["CompanyName"] = String.Empty; } - if (!String.IsNullOrEmpty(bundleInfo.IconSourceFile)) + if (bundleInfo.IconSourceFile != null) { - var iconGroup = new Dtf.Resources.GroupIconResource("#1", burnLocale); - iconGroup.ReadFromFile(bundleInfo.IconSourceFile); + var iconGroup = new GroupIconResource("#1", burnLocale); + iconGroup.ReadFromFile(bundleInfo.IconSourceFile.Path); resources.Add(iconGroup); foreach (var icon in iconGroup.Icons) @@ -306,10 +306,10 @@ namespace WixToolset.Core.Burn.Bundles var splashScreenType = BURN_SPLASH_SCREEN_TYPE.BURN_SPLASH_SCREEN_TYPE_NONE; - if (!String.IsNullOrEmpty(bundleInfo.SplashScreenSourceFile)) + if (bundleInfo.SplashScreenSourceFile != null) { - var bitmap = new Dtf.Resources.BitmapResource("#1", burnLocale); - bitmap.ReadFromFile(bundleInfo.SplashScreenSourceFile); + var bitmap = new BitmapResource("#1", burnLocale); + bitmap.ReadFromFile(bundleInfo.SplashScreenSourceFile.Path); resources.Add(bitmap); splashScreenType = BURN_SPLASH_SCREEN_TYPE.BURN_SPLASH_SCREEN_TYPE_BITMAP_RESOURCE; @@ -321,13 +321,26 @@ namespace WixToolset.Core.Burn.Bundles ResourceId = 1, }; - var splashScreenConfigResource = new Dtf.Resources.Resource(ResourceType.RCData, "#1", burnLocale, splashScreenConfig.ToBytes()); + var splashScreenConfigResource = new Resource(ResourceType.RCData, "#1", burnLocale, splashScreenConfig.ToBytes()); resources.Add(splashScreenConfigResource); var manifestResource = new Resource(ResourceType.Manifest, "#1", burnLocale, applicationManifestData); resources.Add(manifestResource); - resources.Save(bundleTempPath); + try + { + resources.Save(bundleTempPath); + } + catch (IOException) + { + // If there was no icon or splash screen then this is unexpected so rethrow. + if (bundleInfo.IconSourceFile == null && bundleInfo.SplashScreenSourceFile == null) + { + throw; + } + + this.Messaging.Write(BurnBackendErrors.FailedToAddIconOrSplashScreenToBundle(bundleInfo.SourceLineNumbers, bundleInfo.IconSourceFile?.Path, bundleInfo.SplashScreenSourceFile?.Path)); + } } enum BURN_SPLASH_SCREEN_TYPE diff --git a/src/wix/WixToolset.Core.Burn/BurnBackendErrors.cs b/src/wix/WixToolset.Core.Burn/BurnBackendErrors.cs index 74dc4cd5..a710333e 100644 --- a/src/wix/WixToolset.Core.Burn/BurnBackendErrors.cs +++ b/src/wix/WixToolset.Core.Burn/BurnBackendErrors.cs @@ -2,6 +2,7 @@ namespace WixToolset.Core.Burn { + using System; using WixToolset.Data; internal static class BurnBackendErrors @@ -36,6 +37,29 @@ namespace WixToolset.Core.Burn return Message(sourceLineNumbers, Ids.ExternalPayloadCollision2, "The location of the symbol related to the previous error."); } + public static Message FailedToAddIconOrSplashScreenToBundle(SourceLineNumber sourceLineNumbers, string iconPath, string splashScreenPath) + { + var additionalDetail = String.Empty; + + if (String.IsNullOrEmpty(iconPath) && String.IsNullOrEmpty(splashScreenPath)) + { + } + else if (String.IsNullOrEmpty(iconPath)) + { + additionalDetail = $" Ensure the splash screen file is a bitmap file at '{splashScreenPath}'"; + } + else if (String.IsNullOrEmpty(splashScreenPath)) + { + additionalDetail = $" Ensure the bundle icon file is an icon file at '{iconPath}'"; + } + else + { + additionalDetail = $" Ensure the bundle icon file is an icon file at '{iconPath}' and the splash screen file is a bitmap file at '{splashScreenPath}'"; + } + + return Message(sourceLineNumbers, Ids.FailedToAddIconOrSplashScreenToBundle, "Failed to add resources to the bundle.{0}", additionalDetail); + } + public static Message PackageCachePayloadCollision(SourceLineNumber sourceLineNumbers, string payloadId, string payloadName, string packageId) { return Message(sourceLineNumbers, Ids.PackageCachePayloadCollision, "The Payload '{0}' has a duplicate Name '{1}' in package '{2}'. When caching the package, the file will get overwritten.", payloadId, payloadName, packageId); @@ -79,6 +103,7 @@ namespace WixToolset.Core.Burn TooManyAttachedContainers = 8008, IncompatibleWixBurnSection = 8009, UnsupportedRemotePackagePayload = 8010, + FailedToAddIconOrSplashScreenToBundle = 8011, } // last available is 8499. 8500 is BurnBackendWarnings. } } diff --git a/src/wix/WixToolset.Core/Compiler_Bundle.cs b/src/wix/WixToolset.Core/Compiler_Bundle.cs index dd263484..e1e26620 100644 --- a/src/wix/WixToolset.Core/Compiler_Bundle.cs +++ b/src/wix/WixToolset.Core/Compiler_Bundle.cs @@ -425,8 +425,8 @@ namespace WixToolset.Core UpdateUrl = updateUrl, CommandLineVariables = commandLineVariables, Compressed = YesNoDefaultType.Yes == compressed ? true : YesNoDefaultType.No == compressed ? (bool?)false : null, - IconSourceFile = iconSourceFile, - SplashScreenSourceFile = splashScreenSourceFile, + IconSourceFile = new IntermediateFieldPathValue { Path = iconSourceFile }, + SplashScreenSourceFile = new IntermediateFieldPathValue { Path = splashScreenSourceFile }, Condition = condition, Tag = tag, Platform = this.CurrentPlatform, diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/BundleFixture.cs b/src/wix/test/WixToolsetTest.CoreIntegration/BundleFixture.cs index 711b2fda..2328d762 100644 --- a/src/wix/test/WixToolsetTest.CoreIntegration/BundleFixture.cs +++ b/src/wix/test/WixToolsetTest.CoreIntegration/BundleFixture.cs @@ -291,6 +291,34 @@ namespace WixToolsetTest.CoreIntegration } } + [Fact] + public void CannotBuildBundleWithInvalidIcon() + { + var folder = TestData.Get(@"TestData"); + + using (var fs = new DisposableFileSystem()) + { + var baseFolder = fs.GetFolder(); + var intermediateFolder = Path.Combine(baseFolder, "obj"); + + var result = WixRunner.Execute(new[] + { + "build", + Path.Combine(folder, "BundleWithInvalid", "BundleWithInvalidIcon.wxs"), + "-bindpath", Path.Combine(folder, ".Data"), + "-bindpath", Path.Combine(folder, "SimpleBundle", "data"), + "-intermediateFolder", intermediateFolder, + "-o", Path.Combine(baseFolder, @"bin\test.exe") + }); + + var message = result.Messages.Where(m => m.Level == MessageLevel.Error).Select(m => m.ToString().Replace(folder, "")).ToArray(); + WixAssert.CompareLineByLine(new[] + { + @"Failed to add resources to the bundle. Ensure the bundle icon file is an icon file at '\.Data\burn.exe'" + }, message); + } + } + [Fact] public void CanBuildUncompressedBundle() { diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/TestData/BundleWithInvalid/BundleWithInvalidIcon.wxs b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/BundleWithInvalid/BundleWithInvalidIcon.wxs new file mode 100644 index 00000000..c767c816 --- /dev/null +++ b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/BundleWithInvalid/BundleWithInvalidIcon.wxs @@ -0,0 +1,11 @@ + + + + + + + + + + -- cgit v1.2.3-55-g6feb