From 164c29aff8d6581a3277c9fd0810ea56356c3e69 Mon Sep 17 00:00:00 2001 From: Bob Arnson Date: Tue, 11 Jul 2023 21:19:08 -0400 Subject: Partial fix for the weirdly broken... IWindowsInstallerDecompileContext.TreatProductAsModule. https://github.com/wixtoolset/issues/issues/7607 --- .../Data/IWindowsInstallerDecompileContext.cs | 3 +- .../Decompile/Decompiler.cs | 8 ++--- .../WindowsInstallerDecompiler.cs | 13 +++++-- .../DecompileFixture.cs | 41 ++++++++++++++++++++++ .../ExpectedModularizationGuids.wxs | 24 +++++++++++++ 5 files changed, 82 insertions(+), 7 deletions(-) create mode 100644 src/wix/test/WixToolsetTest.CoreIntegration/TestData/DecompileTargetDirMergeModule/ExpectedModularizationGuids.wxs (limited to 'src') diff --git a/src/api/wix/WixToolset.Extensibility/Data/IWindowsInstallerDecompileContext.cs b/src/api/wix/WixToolset.Extensibility/Data/IWindowsInstallerDecompileContext.cs index 7b974942..845c89a5 100644 --- a/src/api/wix/WixToolset.Extensibility/Data/IWindowsInstallerDecompileContext.cs +++ b/src/api/wix/WixToolset.Extensibility/Data/IWindowsInstallerDecompileContext.cs @@ -93,7 +93,8 @@ namespace WixToolset.Extensibility.Data bool SuppressUI { get; set; } /// - /// Gets or sets whether the decompiler should use module logic on a product output. + /// Gets or sets whether the decompiler should keep modularization + /// GUIDs (true) or remove them (default/false). /// bool TreatProductAsModule { get; set; } } diff --git a/src/wix/WixToolset.Core.WindowsInstaller/Decompile/Decompiler.cs b/src/wix/WixToolset.Core.WindowsInstaller/Decompile/Decompiler.cs index 183c319b..9701f958 100644 --- a/src/wix/WixToolset.Core.WindowsInstaller/Decompile/Decompiler.cs +++ b/src/wix/WixToolset.Core.WindowsInstaller/Decompile/Decompiler.cs @@ -1188,11 +1188,11 @@ namespace WixToolset.Core.WindowsInstaller.Decompile var fileName = xFile?.Attribute("Name")?.Value; // set the source (done here because it requires information from the Directory table) - if (OutputType.Module == this.OutputType) + if (OutputType.Module == this.OutputType && !this.TreatProductAsModule) { xFile.SetAttributeValue("Source", String.Concat(this.BaseSourcePath, Path.DirectorySeparatorChar, "File", Path.DirectorySeparatorChar, fileId, '.', this.ModularizationGuid.Substring(1, 36).Replace('-', '_'))); } - else if (fileCompressed == "yes" || (fileCompressed != "no" && this.Compressed) || (OutputType.Package == this.OutputType && this.TreatProductAsModule)) + else if (fileCompressed == "yes" || (fileCompressed != "no" && this.Compressed) || OutputType.Module == this.OutputType) { xFile.SetAttributeValue("Source", String.Concat(this.BaseSourcePath, Path.DirectorySeparatorChar, "File", Path.DirectorySeparatorChar, fileId)); } @@ -1898,7 +1898,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile private void FinalizeSequenceTables(TableIndexedCollection tables) { // finalize the normal sequence tables - if (OutputType.Package == this.OutputType && !this.TreatProductAsModule) + if (OutputType.Package == this.OutputType) { foreach (SequenceTable sequenceTable in Enum.GetValues(typeof(SequenceTable))) { @@ -2039,7 +2039,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile } } } - else if (OutputType.Module == this.OutputType || this.TreatProductAsModule) // finalize the Module sequence tables + else if (OutputType.Module == this.OutputType) // finalize the Module sequence tables { foreach (SequenceTable sequenceTable in Enum.GetValues(typeof(SequenceTable))) { diff --git a/src/wix/WixToolset.Core.WindowsInstaller/WindowsInstallerDecompiler.cs b/src/wix/WixToolset.Core.WindowsInstaller/WindowsInstallerDecompiler.cs index b41876b3..fb560d1c 100644 --- a/src/wix/WixToolset.Core.WindowsInstaller/WindowsInstallerDecompiler.cs +++ b/src/wix/WixToolset.Core.WindowsInstaller/WindowsInstallerDecompiler.cs @@ -92,8 +92,17 @@ namespace WixToolset.Core.WindowsInstaller var extractFilesFolder = context.SuppressExtractCabinets || (String.IsNullOrEmpty(context.CabinetExtractFolder) && String.IsNullOrEmpty(context.ExtractFolder)) ? null : String.IsNullOrEmpty(context.CabinetExtractFolder) ? Path.Combine(context.ExtractFolder, "File") : context.CabinetExtractFolder; - var outputType = context.TreatProductAsModule ? OutputType.Module : context.DecompileType; - var unbindCommand = new UnbindDatabaseCommand(this.Messaging, backendHelper, fileSystem, pathResolver, context.DecompilePath, null, outputType, context.ExtractFolder, extractFilesFolder, context.IntermediateFolder, enableDemodularization: true, skipSummaryInfo: false); + // IWindowsInstallerDecompileContext.TreatProductAsModule is broken. So broken, in fact, + // that it's been broken since WiX v3.0 in 2008. It was introduced (according to lore) + // to support Melt, which decompiles merge modules into fragments so you can consume + // merge modules without actually going through the black box that is mergemod.dll. But + // the name is wrong: It's not TreatProductAsModule; if anything it should instead be + // TreatModuleAsProduct, though even that's wrong (because you want a fragment, not a + // product/package). In WiX v5, rename to `KeepModularizeIds` (or something better) to + // reflect the functionality. + var demodularize = !context.TreatProductAsModule; + var sectionType = context.DecompileType; + var unbindCommand = new UnbindDatabaseCommand(this.Messaging, backendHelper, fileSystem, pathResolver, context.DecompilePath, null, sectionType, context.ExtractFolder, extractFilesFolder, context.IntermediateFolder, demodularize, skipSummaryInfo: false); var output = unbindCommand.Execute(); var extractedFilePaths = unbindCommand.ExportedFiles; diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/DecompileFixture.cs b/src/wix/test/WixToolsetTest.CoreIntegration/DecompileFixture.cs index 6a9de6df..01882fef 100644 --- a/src/wix/test/WixToolsetTest.CoreIntegration/DecompileFixture.cs +++ b/src/wix/test/WixToolsetTest.CoreIntegration/DecompileFixture.cs @@ -3,10 +3,18 @@ namespace WixToolsetTest.CoreIntegration { using System; + using System.Diagnostics; using System.IO; using WixInternal.Core.TestPackage; using WixInternal.TestSupport; + using WixToolset.Core; + using WixToolset.Core.WindowsInstaller; + using WixToolset.Data; + using WixToolset.Extensibility; + using WixToolset.Extensibility.Data; + using WixToolset.Extensibility.Services; using Xunit; + using static NuGet.Packaging.PackagingConstants; public class DecompileFixture { @@ -98,5 +106,38 @@ namespace WixToolsetTest.CoreIntegration { DecompileAndCompare("ui.msi", extract: false, "ExpectedUI.wxs", "TestData", "Decompile"); } + + [Fact] + public void CanDecompileMergeModuleWithTreatProductAsModule() + { + using (var fs = new DisposableFileSystem()) + { + var intermediateFolder = fs.GetFolder(); + var outputFolder = fs.GetFolder(); + var extractPath = Path.Combine(intermediateFolder, "$extracted"); + var outputPath = Path.Combine(intermediateFolder, @"Actual.wxs"); + var sourceFolder = TestData.Get("TestData", "DecompileTargetDirMergeModule"); + + var serviceProvider = WixToolsetServiceProviderFactory.CreateServiceProvider(); + serviceProvider.AddWindowsInstallerBackend(); + var extensionManager = serviceProvider.GetService(); + var context = serviceProvider.GetService(); + + context.Extensions = Array.Empty(); + context.ExtensionData = extensionManager.GetServices(); + context.DecompilePath = Path.Combine(sourceFolder, "MergeModule1.msm"); + context.DecompileType = OutputType.Module; + context.TreatProductAsModule = true; + context.IntermediateFolder = intermediateFolder; + context.ExtractFolder = outputFolder; + context.CabinetExtractFolder = outputFolder; + + var decompiler = serviceProvider.GetService(); + var result = decompiler.Decompile(context); + + result.Document.Save(outputPath); + WixAssert.CompareXml(Path.Combine(sourceFolder, "ExpectedModularizationGuids.wxs"), outputPath); + } + } } } diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/TestData/DecompileTargetDirMergeModule/ExpectedModularizationGuids.wxs b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/DecompileTargetDirMergeModule/ExpectedModularizationGuids.wxs new file mode 100644 index 00000000..aff9148c --- /dev/null +++ b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/DecompileTargetDirMergeModule/ExpectedModularizationGuids.wxs @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + -- cgit v1.2.3-55-g6feb