main
cs 143 lines 5.87 KB
Raw
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 WixToolsetTest.CoreIntegration
4 {
5 using System;
6 using System.Diagnostics;
7 using System.IO;
8 using WixInternal.Core.TestPackage;
9 using WixInternal.TestSupport;
10 using WixToolset.Core;
11 using WixToolset.Core.WindowsInstaller;
12 using WixToolset.Data;
13 using WixToolset.Extensibility;
14 using WixToolset.Extensibility.Data;
15 using WixToolset.Extensibility.Services;
16 using Xunit;
17 using static NuGet.Packaging.PackagingConstants;
18
19 public class DecompileFixture
20 {
21 private static void DecompileAndCompare(string msiName, bool extract, string expectedWxsName, params string[] sourceFolder)
22 {
23 var folder = TestData.Get(sourceFolder);
24
25 using (var fs = new DisposableFileSystem())
26 {
27 var intermediateFolder = fs.GetFolder();
28 var extractPath = Path.Combine(intermediateFolder, "$extracted");
29 var outputPath = Path.Combine(intermediateFolder, @"Actual.wxs");
30
31 var result = WixRunner.Execute(new[]
32 {
33 "msi", "decompile",
34 Path.Combine(folder, msiName),
35 "-intermediateFolder", intermediateFolder,
36 "-o", outputPath,
37 extract ? "-x" : String.Empty,
38 extract ? extractPath : String.Empty,
39 }, out var messages);
40
41 Assert.Equal(0, result);
42 Assert.Empty(messages);
43
44 if (extract)
45 {
46 Assert.NotEmpty(Directory.EnumerateFiles(extractPath, "*", SearchOption.AllDirectories));
47 }
48
49 WixAssert.CompareXml(Path.Combine(folder, expectedWxsName), outputPath);
50 }
51 }
52
53 [Fact]
54 public void CanDecompileSingleFileCompressed()
55 {
56 DecompileAndCompare("example.msi", extract: true, "Expected.wxs", "TestData", "DecompileSingleFileCompressed");
57 }
58
59 [Fact]
60 public void CanDecompile64BitSingleFileCompressed()
61 {
62 DecompileAndCompare("example.msi", extract: true, "Expected.wxs", "TestData", "DecompileSingleFileCompressed64");
63 }
64
65 [Fact]
66 public void CanDecompileNestedDirSearchUnderRegSearch()
67 {
68 DecompileAndCompare("NestedDirSearchUnderRegSearch.msi", extract: false, "DecompiledNestedDirSearchUnderRegSearch.wxs", "TestData", "AppSearch");
69 }
70
71 [Fact]
72 public void CanDecompileOldClassTableDefinition()
73 {
74 // The input MSI was not created using standard methods, it is an example of a real world database that needs to be decompiled.
75 // The Class/@Feature_ column has length of 32, the File/@Attributes has length of 2,
76 // and numerous foreign key relationships are missing.
77 DecompileAndCompare("OldClassTableDef.msi", extract: false, "DecompiledOldClassTableDef.wxs", "TestData", "Class");
78 }
79
80 [Fact]
81 public void CanDecompileSequenceTables()
82 {
83 DecompileAndCompare("SequenceTables.msi", extract: false, "DecompiledSequenceTables.wxs", "TestData", "SequenceTables");
84 }
85
86 [Fact]
87 public void CanDecompileShortcuts()
88 {
89 DecompileAndCompare("shortcuts.msi", extract: false, "DecompiledShortcuts.wxs", "TestData", "Shortcut");
90 }
91
92 [Fact]
93 public void CanDecompileNullComponent()
94 {
95 DecompileAndCompare("example.msi", extract: true, "Expected.wxs", "TestData", "DecompileNullComponent");
96 }
97
98 [Fact]
99 public void CanDecompileMergeModuleWithTargetDirComponent()
100 {
101 DecompileAndCompare("MergeModule1.msm", extract: true, "Expected.wxs", "TestData", "DecompileTargetDirMergeModule");
102 }
103
104 [Fact]
105 public void CanDecompileUI()
106 {
107 DecompileAndCompare("ui.msi", extract: false, "ExpectedUI.wxs", "TestData", "Decompile");
108 }
109
110 [Fact]
111 public void CanDecompileMergeModuleWithKeepModularizationIds()
112 {
113 using (var fs = new DisposableFileSystem())
114 {
115 var intermediateFolder = fs.GetFolder();
116 var outputFolder = fs.GetFolder();
117 var extractPath = Path.Combine(intermediateFolder, "$extracted");
118 var outputPath = Path.Combine(intermediateFolder, @"Actual.wxs");
119 var sourceFolder = TestData.Get("TestData", "DecompileTargetDirMergeModule");
120
121 var serviceProvider = WixToolsetServiceProviderFactory.CreateServiceProvider();
122 serviceProvider.AddWindowsInstallerBackend();
123 var extensionManager = serviceProvider.GetService<IExtensionManager>();
124 var context = serviceProvider.GetService<IWindowsInstallerDecompileContext>();
125
126 context.Extensions = Array.Empty<BaseWindowsInstallerDecompilerExtension>();
127 context.ExtensionData = extensionManager.GetServices<IExtensionData>();
128 context.DecompilePath = Path.Combine(sourceFolder, "MergeModule1.msm");
129 context.DecompileType = OutputType.Module;
130 context.KeepModularizationIds = true;
131 context.IntermediateFolder = intermediateFolder;
132 context.ExtractFolder = outputFolder;
133 context.CabinetExtractFolder = outputFolder;
134
135 var decompiler = serviceProvider.GetService<IWindowsInstallerDecompiler>();
136 var result = decompiler.Decompile(context);
137
138 result.Document.Save(outputPath);
139 WixAssert.CompareXml(Path.Combine(sourceFolder, "ExpectedModularizationGuids.wxs"), outputPath);
140 }
141 }
142 }
143 }