main
cs 945 lines 44.5 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.Sdk
4 {
5 using System;
6 using System.Collections.Generic;
7 using System.IO;
8 using System.Linq;
9 using WixInternal.TestSupport;
10 using Xunit;
11
12 public class MsbuildFixture
13 {
14 public static readonly string WixMsbuildPath = Path.Combine(Path.GetDirectoryName(new Uri(typeof(MsbuildFixture).Assembly.CodeBase).LocalPath), "..", "..", "..", "publish", "WixToolset.Sdk");
15 public static readonly string WixPropsPath = Path.Combine(WixMsbuildPath, "Sdk", "Sdk.props");
16
17 [Theory]
18 [InlineData(BuildSystem.DotNetCoreSdk)]
19 [InlineData(BuildSystem.MSBuild)]
20 [InlineData(BuildSystem.MSBuild64)]
21 public void CanBuildSimpleBundle(BuildSystem buildSystem)
22 {
23 var sourceFolder = TestData.Get(@"TestData", "SimpleMsiPackage");
24
25 using (var fs = new TestDataFolderFileSystem())
26 {
27 fs.Initialize(sourceFolder);
28 var baseFolder = Path.Combine(fs.BaseFolder, "SimpleBundle");
29 var binFolder = Path.Combine(baseFolder, @"bin\");
30 var projectPath = Path.Combine(baseFolder, "SimpleBundle.wixproj");
31
32 var result = MsbuildUtilities.BuildProject(buildSystem, projectPath, new[] {
33 MsbuildUtilities.GetQuotedPropertySwitch(buildSystem, "WixMSBuildProps", MsbuildFixture.WixPropsPath),
34 "-p:SignOutput=true",
35 });
36 result.AssertSuccess();
37
38 var warnings = result.Output.Where(line => line.Contains(": warning")).ToArray();
39 WixAssert.StringCollectionEmpty(warnings);
40
41 var testMessages = result.Output.Where(line => line.Contains("TEST:")).Select(line => line.Trim()).ToArray();
42 WixAssert.CompareLineByLine(new[]
43 {
44 @"TEST: SignBundleEngine: obj\x86\Release\SimpleBundle-engine.exe",
45 @"TEST: SignBundle: obj\x86\Release\SimpleBundle.exe",
46 }, testMessages);
47
48 var paths = Directory.EnumerateFiles(binFolder, @"*.*", SearchOption.AllDirectories)
49 .Select(s => s.Substring(baseFolder.Length + 1))
50 .OrderBy(s => s)
51 .ToArray();
52 WixAssert.CompareLineByLine(new[]
53 {
54 @"bin\x86\Release\SimpleBundle.exe",
55 @"bin\x86\Release\SimpleBundle.wixpdb",
56 }, paths);
57 }
58 }
59
60 [Theory]
61 [InlineData(BuildSystem.DotNetCoreSdk)]
62 [InlineData(BuildSystem.MSBuild)]
63 [InlineData(BuildSystem.MSBuild64)]
64 public void CanBuildUncompressedBundle(BuildSystem buildSystem)
65 {
66 var sourceFolder = TestData.Get("TestData", "SimpleMsiPackage");
67
68 using (var fs = new TestDataFolderFileSystem())
69 {
70 fs.Initialize(sourceFolder);
71 var baseFolder = Path.Combine(fs.BaseFolder, "UncompressedBundle");
72 var binFolder = Path.Combine(baseFolder, @"bin\");
73 var projectPath = Path.Combine(baseFolder, "UncompressedBundle.wixproj");
74
75 var result = MsbuildUtilities.BuildProject(buildSystem, projectPath, new[] {
76 MsbuildUtilities.GetQuotedPropertySwitch(buildSystem, "WixMSBuildProps", MsbuildFixture.WixPropsPath),
77 "-p:SignOutput=true"
78 });
79 result.AssertSuccess();
80
81 var warnings = result.Output.Where(line => line.Contains(": warning")).ToArray();
82 WixAssert.StringCollectionEmpty(warnings);
83
84 var testMessages = result.Output.Where(line => line.Contains("TEST:")).Select(line => line.Trim()).ToArray();
85 WixAssert.CompareLineByLine(new[]
86 {
87 @"TEST: SignBundleEngine: obj\x86\Release\UncompressedBundle-engine.exe",
88 }, testMessages);
89
90 var paths = Directory.EnumerateFiles(binFolder, @"*.*", SearchOption.AllDirectories)
91 .Select(s => s.Substring(baseFolder.Length + 1))
92 .OrderBy(s => s)
93 .ToArray();
94 WixAssert.CompareLineByLine(new[]
95 {
96 @"bin\x86\Release\test.txt",
97 @"bin\x86\Release\UncompressedBundle.exe",
98 @"bin\x86\Release\UncompressedBundle.wixpdb",
99 }, paths);
100 }
101 }
102
103 [Theory]
104 [InlineData(BuildSystem.DotNetCoreSdk)]
105 [InlineData(BuildSystem.MSBuild)]
106 [InlineData(BuildSystem.MSBuild64)]
107 public void CanBuildSimpleMergeModule(BuildSystem buildSystem)
108 {
109 var sourceFolder = TestData.Get("TestData", "MergeModule", "SimpleMergeModule");
110
111 using (var fs = new TestDataFolderFileSystem())
112 {
113 fs.Initialize(sourceFolder);
114 var baseFolder = fs.BaseFolder;
115 var binFolder = Path.Combine(baseFolder, @"bin\");
116 var projectPath = Path.Combine(baseFolder, "SimpleMergeModule.wixproj");
117
118 var result = MsbuildUtilities.BuildProject(buildSystem, projectPath, new[] {
119 MsbuildUtilities.GetQuotedPropertySwitch(buildSystem, "WixMSBuildProps", MsbuildFixture.WixPropsPath)
120 });
121 result.AssertSuccess();
122
123 var warnings = result.Output.Where(line => line.Contains(": warning")).ToArray();
124 WixAssert.StringCollectionEmpty(warnings);
125
126 var paths = Directory.EnumerateFiles(binFolder, @"*.*", SearchOption.AllDirectories)
127 .Select(s => s.Substring(baseFolder.Length + 1))
128 .OrderBy(s => s)
129 .ToArray();
130 WixAssert.CompareLineByLine(new[]
131 {
132 @"bin\x86\Release\SimpleMergeModule.msm",
133 @"bin\x86\Release\SimpleMergeModule.wixpdb",
134 }, paths);
135 }
136 }
137
138 [Theory]
139 [InlineData(BuildSystem.DotNetCoreSdk)]
140 [InlineData(BuildSystem.MSBuild)]
141 [InlineData(BuildSystem.MSBuild64)]
142 public void CanBuildSimpleMsiPackage(BuildSystem buildSystem)
143 {
144 var sourceFolder = TestData.Get(@"TestData\SimpleMsiPackage\MsiPackage");
145
146 var baseFolder = String.Empty;
147
148 using (var fs = new TestDataFolderFileSystem())
149 {
150 fs.Initialize(sourceFolder);
151 baseFolder = fs.BaseFolder;
152
153 var binFolder = Path.Combine(baseFolder, @"bin\");
154 var projectPath = Path.Combine(baseFolder, "MsiPackage.wixproj");
155
156 var result = MsbuildUtilities.BuildProject(buildSystem, projectPath, new[] {
157 MsbuildUtilities.GetQuotedPropertySwitch(buildSystem, "WixMSBuildProps", MsbuildFixture.WixPropsPath),
158 "-p:SignOutput=true"
159 });
160 result.AssertSuccess();
161
162 var platformSwitches = result.Output.Where(line => line.Contains("-platform x86"));
163 Assert.Single(platformSwitches);
164
165 var warnings = result.Output.Where(line => line.Contains(": warning")).Select(line => ExtractWarningFromMessage(line, baseFolder)).ToArray();
166 WixAssert.CompareLineByLine(new[]
167 {
168 @"WIX1118: The variable 'Variable' with value 'DifferentValue' was previously declared with value 'Value'.",
169 @"WIX1102: The DefaultLanguage '1033' was used for file 'filcV1yrx0x8wJWj4qMzcH21jwkPko' which has no language or version. For unversioned files, specifying a value for DefaultLanguage is not neccessary and it will not be used when determining file versions. Remove the DefaultLanguage attribute to eliminate this warning.",
170 @"WIX1122: The installer database '<basefolder>\obj\x86\Release\en-US\MsiPackage.msi' has external cabs, but at least one of them is not signed. Please ensure that all external cabs are signed, if you mean to sign them. If you don't mean to sign them, there is no need to inscribe the MSI as part of your build.",
171 @"WIX1118: The variable 'Variable' with value 'DifferentValue' was previously declared with value 'Value'.",
172 @"WIX1102: The DefaultLanguage '1033' was used for file 'filcV1yrx0x8wJWj4qMzcH21jwkPko' which has no language or version. For unversioned files, specifying a value for DefaultLanguage is not neccessary and it will not be used when determining file versions. Remove the DefaultLanguage attribute to eliminate this warning.",
173 @"WIX1122: The installer database '<basefolder>\obj\x86\Release\en-US\MsiPackage.msi' has external cabs, but at least one of them is not signed. Please ensure that all external cabs are signed, if you mean to sign them. If you don't mean to sign them, there is no need to inscribe the MSI as part of your build."
174 }, warnings);
175
176 var testMessages = result.Output.Where(line => line.Contains("TEST:")).Select(line => ReplacePathsInMessage(line, baseFolder)).ToArray();
177 WixAssert.CompareLineByLine(new[]
178 {
179 @"TEST: SignCabs: <basefolder>\obj\x86\Release\en-US\cab1.cab",
180 @"TEST: SignMsi: obj\x86\Release\en-US\MsiPackage.msi",
181 }, testMessages);
182
183 var paths = Directory.EnumerateFiles(binFolder, @"*.*", SearchOption.AllDirectories)
184 .Select(s => s.Substring(baseFolder.Length + 1))
185 .OrderBy(s => s)
186 .ToArray();
187 WixAssert.CompareLineByLine(new[]
188 {
189 @"bin\x86\Release\en-US\cab1.cab",
190 @"bin\x86\Release\en-US\MsiPackage.msi",
191 @"bin\x86\Release\en-US\MsiPackage.wixpdb",
192 }, paths);
193 }
194 }
195
196 [Theory]
197 [InlineData(BuildSystem.DotNetCoreSdk)]
198 [InlineData(BuildSystem.MSBuild)]
199 [InlineData(BuildSystem.MSBuild64)]
200 public void CanBuildSimpleMsiPackageWithMergeModule(BuildSystem buildSystem)
201 {
202 var sourceFolder = TestData.Get(@"TestData", "MergeModule");
203
204 using (var fs = new TestDataFolderFileSystem())
205 {
206 fs.Initialize(sourceFolder);
207 var baseFolder = Path.Combine(fs.BaseFolder, "MergeMsiPackage");
208 var binFolder = Path.Combine(baseFolder, @"bin\");
209 var projectPath = Path.Combine(baseFolder, "MergeMsiPackage.wixproj");
210
211 var result = MsbuildUtilities.BuildProject(buildSystem, projectPath, new[] {
212 MsbuildUtilities.GetQuotedPropertySwitch(buildSystem, "WixMSBuildProps", MsbuildFixture.WixPropsPath)
213 });
214 result.AssertSuccess();
215
216 var warnings = result.Output.Where(line => line.Contains(": warning")).ToArray();
217 WixAssert.StringCollectionEmpty(warnings);
218
219 var paths = Directory.EnumerateFiles(binFolder, @"*.*", SearchOption.AllDirectories)
220 .Select(s => s.Substring(baseFolder.Length + 1))
221 .OrderBy(s => s)
222 .ToArray();
223 WixAssert.CompareLineByLine(new[]
224 {
225 @"bin\x86\Release\cab1.cab",
226 @"bin\x86\Release\MergeMsiPackage.msi",
227 @"bin\x86\Release\MergeMsiPackage.wixpdb",
228 }, paths);
229 }
230 }
231
232 [Theory]
233 [InlineData(BuildSystem.DotNetCoreSdk)]
234 [InlineData(BuildSystem.MSBuild)]
235 [InlineData(BuildSystem.MSBuild64)]
236 public void CanBuildMsiPackageWithBindVariables(BuildSystem buildSystem)
237 {
238 var sourceFolder = TestData.Get("TestData", "MsiPackageWithBindVariables");
239
240 var baseFolder = String.Empty;
241
242 using (var fs = new TestDataFolderFileSystem())
243 {
244 fs.Initialize(sourceFolder);
245 baseFolder = fs.BaseFolder;
246
247 var binFolder = Path.Combine(baseFolder, @"bin\");
248 var projectPath = Path.Combine(baseFolder, "MsiPackageWithBindVariables.wixproj");
249
250 var result = MsbuildUtilities.BuildProject(buildSystem, projectPath, new[] {
251 MsbuildUtilities.GetQuotedPropertySwitch(buildSystem, "WixMSBuildProps", MsbuildFixture.WixPropsPath)
252 });
253 result.AssertSuccess();
254
255 var trackingContents = File.ReadAllLines(Path.Combine(baseFolder, "obj", "Release", "MsiPackageWithBindVariables.wixproj.BindTracking-neutral.txt"));
256 var lines = trackingContents.Select(l => l.Replace(baseFolder, "<basefolder>")).ToArray();
257 WixAssert.CompareLineByLine(new[]
258 {
259 "BuiltContentOutput\t<basefolder>\\obj\\Release\\cab1.cab",
260 "BuiltPdbOutput\t<basefolder>\\obj\\Release\\MsiPackageWithBindVariables.wixpdb",
261 "BuiltTargetOutput\t<basefolder>\\obj\\Release\\MsiPackageWithBindVariables.msi",
262 "Input\tdata\\test.txt",
263 "Intermediate\t<basefolder>\\obj\\Release\\cab1.cab"
264 }, lines);
265
266 var paths = Directory.EnumerateFiles(binFolder, @"*.*", SearchOption.AllDirectories)
267 .Select(s => s.Substring(baseFolder.Length + 1))
268 .OrderBy(s => s)
269 .ToArray();
270 WixAssert.CompareLineByLine(new[]
271 {
272 @"bin\Release\cab1.cab",
273 @"bin\Release\MsiPackageWithBindVariables.msi",
274 @"bin\Release\MsiPackageWithBindVariables.wixpdb",
275 }, paths);
276 }
277 }
278
279 [Theory]
280 [InlineData(BuildSystem.DotNetCoreSdk)]
281 [InlineData(BuildSystem.MSBuild)]
282 [InlineData(BuildSystem.MSBuild64)]
283 public void CanBuildWithDefaultAndExplicitlyFullWixpdbs(BuildSystem buildSystem)
284 {
285 var expectedOutputs = new[]
286 {
287 @"bin\x86\Release\en-US\cab1.cab",
288 @"bin\x86\Release\en-US\MsiPackage.msi",
289 @"bin\x86\Release\en-US\MsiPackage.wixpdb",
290 };
291
292 this.AssertWixpdb(buildSystem, null, expectedOutputs);
293 this.AssertWixpdb(buildSystem, "Full", expectedOutputs);
294 }
295
296 [Theory]
297 [InlineData(BuildSystem.DotNetCoreSdk)]
298 [InlineData(BuildSystem.MSBuild)]
299 [InlineData(BuildSystem.MSBuild64)]
300 public void CanBuildWithNoWixpdb(BuildSystem buildSystem)
301 {
302 this.AssertWixpdb(buildSystem, "NONE", new[]
303 {
304 @"bin\x86\Release\en-US\cab1.cab",
305 @"bin\x86\Release\en-US\MsiPackage.msi",
306 });
307 }
308
309 [Theory]
310 [InlineData(BuildSystem.DotNetCoreSdk)]
311 [InlineData(BuildSystem.MSBuild)]
312 [InlineData(BuildSystem.MSBuild64)]
313 public void CanBuildWithWixpdbToDifferentFolder(BuildSystem buildSystem)
314 {
315 var expectedOutputFiles = new[]
316 {
317 @"bin\x86\Release\en-US\cab1.cab",
318 @"bin\x86\Release\en-US\MsiPackage.msi",
319 @"pdb\en-US\MsiPackage.wixpdb",
320 };
321
322 var sourceFolder = TestData.Get(@"TestData", "SimpleMsiPackage", "MsiPackage");
323
324 using (var fs = new TestDataFolderFileSystem())
325 {
326 fs.Initialize(sourceFolder);
327 var baseFolder = fs.BaseFolder;
328 var binFolder = Path.Combine(baseFolder, @"bin\");
329 var pdbFolder = Path.Combine(baseFolder, @"pdb\");
330 var projectPath = Path.Combine(baseFolder, "MsiPackage.wixproj");
331
332 var result = MsbuildUtilities.BuildProject(buildSystem, projectPath, new[]
333 {
334 MsbuildUtilities.GetQuotedPropertySwitch(buildSystem, "WixMSBuildProps", MsbuildFixture.WixPropsPath),
335 MsbuildUtilities.GetQuotedPropertySwitch(buildSystem, "PdbOutputDir", pdbFolder),
336 "-p:SuppressValidation=true"
337 });
338 result.AssertSuccess();
339
340 var paths = Directory.EnumerateFiles(binFolder, @"*.*", SearchOption.AllDirectories)
341 .Concat(Directory.EnumerateFiles(pdbFolder, @"*.*", SearchOption.AllDirectories))
342 .Select(s => s.Substring(baseFolder.Length + 1))
343 .OrderBy(s => s)
344 .ToArray();
345 WixAssert.CompareLineByLine(expectedOutputFiles, paths);
346 }
347 }
348
349 [Theory]
350 [InlineData(BuildSystem.DotNetCoreSdk)]
351 [InlineData(BuildSystem.MSBuild)]
352 [InlineData(BuildSystem.MSBuild64)]
353 public void CanBuild64BitMsiPackage(BuildSystem buildSystem)
354 {
355 var sourceFolder = TestData.Get(@"TestData\SimpleMsiPackage\MsiPackage");
356
357 using (var fs = new TestDataFolderFileSystem())
358 {
359 fs.Initialize(sourceFolder);
360 var baseFolder = fs.BaseFolder;
361 var binFolder = Path.Combine(baseFolder, @"bin\");
362 var projectPath = Path.Combine(baseFolder, "MsiPackage.wixproj");
363
364 var result = MsbuildUtilities.BuildProject(buildSystem, projectPath, new[]
365 {
366 MsbuildUtilities.GetQuotedPropertySwitch(buildSystem, "WixMSBuildProps", MsbuildFixture.WixPropsPath),
367 $"-p:Platform=x64",
368 });
369 result.AssertSuccess();
370
371 var platformSwitches = result.Output.Where(line => line.Contains("-platform x64"));
372 Assert.Single(platformSwitches);
373
374 var paths = Directory.EnumerateFiles(binFolder, @"*.*", SearchOption.AllDirectories)
375 .Select(s => s.Substring(baseFolder.Length + 1))
376 .OrderBy(s => s)
377 .ToArray();
378 WixAssert.CompareLineByLine(new[]
379 {
380 @"bin\x64\Release\en-US\cab1.cab",
381 @"bin\x64\Release\en-US\MsiPackage.msi",
382 @"bin\x64\Release\en-US\MsiPackage.wixpdb",
383 }, paths);
384 }
385 }
386
387 [Theory]
388 [InlineData(BuildSystem.DotNetCoreSdk)]
389 [InlineData(BuildSystem.MSBuild)]
390 [InlineData(BuildSystem.MSBuild64)]
391 public void CanBuildMsiPackageWithIceSuppressions(BuildSystem buildSystem)
392 {
393 var sourceFolder = TestData.Get("TestData", "MsiPackageWithIceError", "MsiPackage");
394
395 using (var fs = new TestDataFolderFileSystem())
396 {
397 fs.Initialize(sourceFolder);
398 var baseFolder = fs.BaseFolder;
399 var binFolder = Path.Combine(baseFolder, @"bin\");
400 var projectPath = Path.Combine(baseFolder, "MsiPackage.wixproj");
401
402 var result = MsbuildUtilities.BuildProject(buildSystem, projectPath, new[]
403 {
404 MsbuildUtilities.GetQuotedPropertySwitch(buildSystem, "WixMSBuildProps", MsbuildFixture.WixPropsPath),
405 MsbuildUtilities.GetQuotedPropertySwitch(buildSystem, "SuppressIces", "ICE12"),
406 }, suppressValidation: false);
407 result.AssertSuccess();
408 }
409 }
410
411 [Theory]
412 [InlineData(BuildSystem.DotNetCoreSdk)]
413 [InlineData(BuildSystem.MSBuild)]
414 [InlineData(BuildSystem.MSBuild64)]
415 public void CanBuildSimpleMsiPackageWithWarningSuppressions(BuildSystem buildSystem)
416 {
417 var sourceFolder = TestData.Get("TestData", "SimpleMsiPackage", "MsiPackage");
418
419 using (var fs = new TestDataFolderFileSystem())
420 {
421 fs.Initialize(sourceFolder);
422 var baseFolder = fs.BaseFolder;
423 var binFolder = Path.Combine(baseFolder, @"bin\");
424 var projectPath = Path.Combine(baseFolder, "MsiPackage.wixproj");
425
426 var result = MsbuildUtilities.BuildProject(buildSystem, projectPath, new[]
427 {
428 MsbuildUtilities.GetQuotedPropertySwitch(buildSystem, "WixMSBuildProps", MsbuildFixture.WixPropsPath),
429 MsbuildUtilities.GetQuotedPropertySwitch(buildSystem, "SuppressSpecificWarnings", "1118;1102"),
430 });
431 result.AssertSuccess();
432
433 var warnings = result.Output.Where(line => line.Contains(": warning")).ToArray();
434 WixAssert.StringCollectionEmpty(warnings);
435 }
436 }
437
438 [Theory]
439 [InlineData(BuildSystem.DotNetCoreSdk)]
440 [InlineData(BuildSystem.MSBuild)]
441 [InlineData(BuildSystem.MSBuild64)]
442 public void CanBuildSingleCultureWithFallbackMsiPackage(BuildSystem buildSystem)
443 {
444 var sourceFolder = TestData.Get(@"TestData", "SingleCultureWithFallbackMsiPackage");
445
446 using (var fs = new TestDataFolderFileSystem())
447 {
448 fs.Initialize(sourceFolder);
449 var baseFolder = fs.BaseFolder;
450 var binFolder = Path.Combine(baseFolder, @"bin\");
451 var projectPath = Path.Combine(baseFolder, "SingleCultureWithFallbackMsiPackage.wixproj");
452
453 var result = MsbuildUtilities.BuildProject(buildSystem, projectPath, new[]
454 {
455 MsbuildUtilities.GetQuotedPropertySwitch(buildSystem, "WixMSBuildProps", MsbuildFixture.WixPropsPath)
456 });
457 result.AssertSuccess();
458
459 var trackingContents = File.ReadAllLines(Path.Combine(baseFolder, "obj", "Release", "SingleCultureWithFallbackMsiPackage.wixproj.BindTracking-de-DE.txt"));
460 var lines = trackingContents.Select(l => l.Replace(baseFolder, "<basefolder>")).ToArray();
461 WixAssert.CompareLineByLine(new[]
462 {
463 "BuiltContentOutput\t<basefolder>\\obj\\Release\\de-DE\\cab1.cab",
464 "BuiltPdbOutput\t<basefolder>\\obj\\Release\\de-DE\\SingleCultureWithFallbackMsiPackage.wixpdb",
465 "BuiltTargetOutput\t<basefolder>\\obj\\Release\\de-DE\\SingleCultureWithFallbackMsiPackage.msi",
466 "Input\t<basefolder>\\data\\test.txt",
467 "Intermediate\t<basefolder>\\obj\\Release\\de-DE\\cab1.cab"
468 }, lines);
469 }
470 }
471
472 [Theory]
473 [InlineData(BuildSystem.DotNetCoreSdk)]
474 [InlineData(BuildSystem.MSBuild)]
475 [InlineData(BuildSystem.MSBuild64)]
476 public void CanBuildMultiCulturalMsiPackage(BuildSystem buildSystem)
477 {
478 var sourceFolder = TestData.Get(@"TestData", "MultiCulturalMsiPackage");
479
480 using (var fs = new TestDataFolderFileSystem())
481 {
482 fs.Initialize(sourceFolder);
483 var baseFolder = fs.BaseFolder;
484 var slnPath = Path.Combine(baseFolder, "MultiCulturalMsiPackage.sln");
485 var projectFolder = Path.Combine(baseFolder, "MsiPackage");
486
487 var result = MsbuildUtilities.BuildProject(buildSystem, slnPath, new[]
488 {
489 MsbuildUtilities.GetQuotedPropertySwitch(buildSystem, "WixMSBuildProps", MsbuildFixture.WixPropsPath)
490 });
491 result.AssertSuccess();
492
493 var trackingEnuContents = File.ReadAllLines(Path.Combine(projectFolder, "obj", "x64", "Release", "MsiPackage.wixproj.BindTracking-en-US.txt"));
494 var enuLines = trackingEnuContents.Select(l => l.Replace(projectFolder, "<basefolder>")).ToArray();
495 WixAssert.CompareLineByLine(new[]
496 {
497 "BuiltContentOutput\t<basefolder>\\obj\\x64\\Release\\en-US\\cab1.cab",
498 "BuiltPdbOutput\t<basefolder>\\obj\\x64\\Release\\en-US\\MsiPackage.wixpdb",
499 "BuiltTargetOutput\t<basefolder>\\obj\\x64\\Release\\en-US\\MsiPackage.msi",
500 "Input\t<basefolder>\\data\\test.txt",
501 "Intermediate\t<basefolder>\\obj\\x64\\Release\\en-US\\cab1.cab"
502 }, enuLines);
503
504 var trackingDeuContents = File.ReadAllLines(Path.Combine(projectFolder, "obj", "x64", "Release", "MsiPackage.wixproj.BindTracking-de-DE.txt"));
505 var deuLines = trackingDeuContents.Select(l => l.Replace(projectFolder, "<basefolder>")).ToArray();
506 WixAssert.CompareLineByLine(new[]
507 {
508 "BuiltContentOutput\t<basefolder>\\obj\\x64\\Release\\de-DE\\cab1.cab",
509 "BuiltPdbOutput\t<basefolder>\\obj\\x64\\Release\\de-DE\\MsiPackage.wixpdb",
510 "BuiltTargetOutput\t<basefolder>\\obj\\x64\\Release\\de-DE\\MsiPackage.msi",
511 "Input\t<basefolder>\\data\\test.txt",
512 "Intermediate\t<basefolder>\\obj\\x64\\Release\\de-DE\\cab1.cab"
513 }, deuLines);
514 }
515 }
516
517 [Theory]
518 [InlineData(BuildSystem.DotNetCoreSdk)]
519 [InlineData(BuildSystem.MSBuild)]
520 [InlineData(BuildSystem.MSBuild64)]
521 public void CanBuildSimpleMsiPackageAsWixipl(BuildSystem buildSystem)
522 {
523 var sourceFolder = TestData.Get(@"TestData\SimpleMsiPackage\MsiPackage");
524
525 using (var fs = new TestDataFolderFileSystem())
526 {
527 fs.Initialize(sourceFolder);
528 var baseFolder = fs.BaseFolder;
529 var binFolder = Path.Combine(baseFolder, @"bin\");
530 var projectPath = Path.Combine(baseFolder, "MsiPackage.wixproj");
531
532 var result = MsbuildUtilities.BuildProject(buildSystem, projectPath, new[]
533 {
534 MsbuildUtilities.GetQuotedPropertySwitch(buildSystem, "WixMSBuildProps", MsbuildFixture.WixPropsPath),
535 "-p:OutputType=IntermediatePostLink",
536 });
537 result.AssertSuccess();
538
539 var wixBuildCommands = MsbuildUtilities.GetToolCommandLines(result, "wix", "build", buildSystem);
540 Assert.Single(wixBuildCommands);
541
542 var path = Directory.EnumerateFiles(binFolder, @"*.*", SearchOption.AllDirectories)
543 .Select(s => s.Substring(baseFolder.Length + 1))
544 .Single();
545 WixAssert.StringEqual(@"bin\x86\Release\MsiPackage.wixipl", path);
546 }
547 }
548
549 [Theory]
550 [InlineData(BuildSystem.DotNetCoreSdk)]
551 [InlineData(BuildSystem.MSBuild)]
552 [InlineData(BuildSystem.MSBuild64)]
553 public void CanBuildSimpleWixlib(BuildSystem buildSystem)
554 {
555 var sourceFolder = TestData.Get(@"TestData", "Wixlib", "SimpleWixlib");
556
557 using (var fs = new TestDataFolderFileSystem())
558 {
559 fs.Initialize(sourceFolder);
560 var baseFolder = fs.BaseFolder;
561 var binFolder = Path.Combine(baseFolder, @"bin\");
562 var projectPath = Path.Combine(baseFolder, "SimpleWixlib.wixproj");
563
564 var result = MsbuildUtilities.BuildProject(buildSystem, projectPath, new[]
565 {
566 MsbuildUtilities.GetQuotedPropertySwitch(buildSystem, "WixMSBuildProps", MsbuildFixture.WixPropsPath),
567 });
568 result.AssertSuccess();
569
570 var wixBuildCommands = MsbuildUtilities.GetToolCommandLines(result, "wix", "build", buildSystem);
571 Assert.Single(wixBuildCommands);
572
573 var path = Directory.EnumerateFiles(binFolder, @"*.*", SearchOption.AllDirectories)
574 .Select(s => s.Substring(baseFolder.Length + 1))
575 .Single();
576 WixAssert.StringEqual(@"bin\Release\SimpleWixlib.wixlib", path);
577 }
578 }
579
580 [Theory]
581 [InlineData(BuildSystem.DotNetCoreSdk)]
582 [InlineData(BuildSystem.MSBuild)]
583 [InlineData(BuildSystem.MSBuild64)]
584 public void CanBuildPackageIncludingSimpleWixlib(BuildSystem buildSystem)
585 {
586 var sourceFolder = TestData.Get(@"TestData", "Wixlib");
587
588 using (var fs = new TestDataFolderFileSystem())
589 {
590 fs.Initialize(sourceFolder);
591 var baseFolder = fs.BaseFolder;
592 var binFolder = Path.Combine(baseFolder, "PackageIncludesWixlib", @"bin\");
593 var projectPath = Path.Combine(baseFolder, "PackageIncludesWixlib", "PackageIncludesWixlib.wixproj");
594
595 var result = MsbuildUtilities.BuildProject(buildSystem, projectPath, new[]
596 {
597 MsbuildUtilities.GetQuotedPropertySwitch(buildSystem, "WixMSBuildProps", MsbuildFixture.WixPropsPath),
598 });
599 result.AssertSuccess();
600
601 var paths = Directory.EnumerateFiles(binFolder, @"*.*", SearchOption.AllDirectories)
602 .Select(s => s.Substring(baseFolder.Length + 1))
603 .ToArray();
604 WixAssert.CompareLineByLine(new[]
605 {
606 @"PackageIncludesWixlib\bin\x86\Release\cab1.cab",
607 @"PackageIncludesWixlib\bin\x86\Release\PackageIncludesWixlib.msi",
608 @"PackageIncludesWixlib\bin\x86\Release\PackageIncludesWixlib.wixpdb",
609 }, paths);
610 }
611 }
612
613 [Theory]
614 [InlineData(BuildSystem.DotNetCoreSdk)]
615 [InlineData(BuildSystem.MSBuild)]
616 [InlineData(BuildSystem.MSBuild64)]
617 public void CanBuildAndCleanSimpleMsiPackage(BuildSystem buildSystem)
618 {
619 var sourceFolder = TestData.Get(@"TestData\SimpleMsiPackage\MsiPackage");
620
621 using (var fs = new TestDataFolderFileSystem())
622 {
623 fs.Initialize(sourceFolder);
624 var baseFolder = fs.BaseFolder;
625 var projectPath = Path.Combine(baseFolder, "MsiPackage.wixproj");
626
627 // Build
628 var result = MsbuildUtilities.BuildProject(buildSystem, projectPath, new[] {
629 MsbuildUtilities.GetQuotedPropertySwitch(buildSystem, "WixMSBuildProps", MsbuildFixture.WixPropsPath)
630 }, verbosityLevel: "diag");
631 result.AssertSuccess();
632
633 var buildOutput = String.Join("\r\n", result.Output);
634
635 var createdPaths = Directory.EnumerateFiles(baseFolder, @"*.*", SearchOption.AllDirectories)
636 .Select(s => s.Substring(baseFolder.Length + 1))
637 .OrderBy(s => s)
638 .ToArray();
639 Assert.NotEmpty(createdPaths);
640
641 // Clean
642 result = MsbuildUtilities.BuildProject(buildSystem, projectPath, new[]
643 {
644 MsbuildUtilities.GetQuotedPropertySwitch(buildSystem, "WixMSBuildProps", MsbuildFixture.WixPropsPath),
645 "-t:Clean",
646 }, verbosityLevel: "diag");
647 result.AssertSuccess();
648
649 var cleanOutput = String.Join("\r\n", result.Output);
650
651 // Clean is only expected to delete the files listed in {Project}.FileListAbsolute.txt,
652 // so this is not quite right but close enough.
653 var allowedFiles = new HashSet<string>
654 {
655 "MsiPackage.wixproj",
656 "MsiPackage.binlog",
657 "Package.en-us.wxl",
658 "Package.wxs",
659 "PackageComponents.wxs",
660 @"data\test.txt",
661 @"obj\x86\Release\MsiPackage.wixproj.FileListAbsolute.txt",
662 };
663
664 var remainingPaths = Directory.EnumerateFiles(baseFolder, @"*.*", SearchOption.AllDirectories)
665 .Select(s => s.Substring(baseFolder.Length + 1))
666 .Where(s => !allowedFiles.Contains(s))
667 .OrderBy(s => s)
668 .ToArray();
669 WixAssert.StringCollectionEmpty(remainingPaths);
670 }
671 }
672
673 [Theory]
674 [InlineData(BuildSystem.DotNetCoreSdk)]
675 [InlineData(BuildSystem.MSBuild)]
676 [InlineData(BuildSystem.MSBuild64)]
677 public void CanBuildMultiTargetingWixlibUsingRids(BuildSystem buildSystem)
678 {
679 var sourceFolder = TestData.Get(@"TestData", "MultiTargetingWixlib");
680
681 using (var fs = new TestDataFolderFileSystem())
682 {
683 fs.Initialize(sourceFolder);
684 var baseFolder = Path.Combine(fs.BaseFolder, "PackageUsingRids");
685 var binFolder = Path.Combine(baseFolder, @"bin\");
686 var filesFolder = Path.Combine(binFolder, "Release", @"PFiles\");
687 var projectPath = Path.Combine(baseFolder, "PackageUsingRids.wixproj");
688
689 var result = MsbuildUtilities.BuildProject(buildSystem, projectPath, new[] {
690 "-Restore",
691 MsbuildUtilities.GetQuotedPropertySwitch(buildSystem, "WixMSBuildProps", MsbuildFixture.WixPropsPath)
692 });
693 result.AssertSuccess();
694
695 var warnings = result.Output.Where(line => line.Contains(": warning")).ToArray();
696 WixAssert.StringCollectionEmpty(warnings);
697
698 var releaseFiles = Directory.EnumerateFiles(filesFolder, "*", SearchOption.AllDirectories);
699 var releaseFileSizes = releaseFiles.Select(p => PathAndSize(p, filesFolder)).OrderBy(s => s).ToArray();
700
701 WixAssert.CompareLineByLine(new[]
702 {
703 @"net472_x64\e_sqlite3.dll - 1601536",
704 @"net472_x86\e_sqlite3.dll - 1207296",
705 @"net6_x64\e_sqlite3.dll - 1601536",
706 @"net6_x86\e_sqlite3.dll - 1207296",
707 }, releaseFileSizes);
708 }
709 }
710
711 [Theory]
712 [InlineData(BuildSystem.DotNetCoreSdk)]
713 [InlineData(BuildSystem.MSBuild)]
714 [InlineData(BuildSystem.MSBuild64)]
715 public void CanBuildMultiTargetingWixlibUsingRidsWithReleaseAndDebug(BuildSystem buildSystem)
716 {
717 var sourceFolder = TestData.Get(@"TestData", "MultiTargetingWixlib");
718
719 using (var fs = new TestDataFolderFileSystem())
720 {
721 fs.Initialize(sourceFolder);
722 var baseFolder = Path.Combine(fs.BaseFolder, "PackageReleaseAndDebug");
723 var binFolder = Path.Combine(baseFolder, @"bin\");
724 var filesFolder = Path.Combine(binFolder, "Release", @"PFiles\");
725 var projectPath = Path.Combine(baseFolder, "PackageReleaseAndDebug.wixproj");
726
727 var result = MsbuildUtilities.BuildProject(buildSystem, projectPath, new[] {
728 "-Restore",
729 MsbuildUtilities.GetQuotedPropertySwitch(buildSystem, "WixMSBuildProps", MsbuildFixture.WixPropsPath)
730 });
731 result.AssertSuccess();
732
733 var warnings = result.Output.Where(line => line.Contains(": warning")).ToArray();
734 WixAssert.StringCollectionEmpty(warnings);
735
736 var releaseFiles = Directory.EnumerateFiles(filesFolder, "*", SearchOption.AllDirectories);
737 var releaseFileSizes = releaseFiles.Select(p => PathAndSize(p, filesFolder)).OrderBy(s => s).ToArray();
738
739 WixAssert.CompareLineByLine(new[]
740 {
741 @"debug_net472_x64\e_sqlite3.dll - 1601536",
742 @"debug_net472_x86\e_sqlite3.dll - 1207296",
743 @"debug_net6_x64\e_sqlite3.dll - 1601536",
744 @"debug_net6_x86\e_sqlite3.dll - 1207296",
745 @"release_net472_x64\e_sqlite3.dll - 1601536",
746 @"release_net472_x86\e_sqlite3.dll - 1207296",
747 @"release_net6_x64\e_sqlite3.dll - 1601536",
748 @"release_net6_x86\e_sqlite3.dll - 1207296",
749 }, releaseFileSizes);
750 }
751 }
752
753 [Theory]
754 [InlineData(BuildSystem.DotNetCoreSdk)]
755 [InlineData(BuildSystem.MSBuild)]
756 [InlineData(BuildSystem.MSBuild64)]
757 public void CannotBuildMultiTargetingWixlibUsingExplicitSubsetOfTfmAndRid(BuildSystem buildSystem)
758 {
759 var sourceFolder = TestData.Get(@"TestData", "MultiTargetingWixlib");
760
761 using (var fs = new TestDataFolderFileSystem())
762 {
763 fs.Initialize(sourceFolder);
764 var baseFolder = Path.Combine(fs.BaseFolder, "PackageUsingExplicitTfmAndRids");
765 var binFolder = Path.Combine(baseFolder, @"bin\");
766 var filesFolder = Path.Combine(binFolder, "Release", @"PFiles\");
767 var projectPath = Path.Combine(baseFolder, "PackageUsingExplicitTfmAndRids.wixproj");
768
769 var result = MsbuildUtilities.BuildProject(buildSystem, projectPath, new[] {
770 "-Restore",
771 MsbuildUtilities.GetQuotedPropertySwitch(buildSystem, "WixMSBuildProps", MsbuildFixture.WixPropsPath)
772 });
773
774 var errors = GetDistinctErrorMessages(result.Output, baseFolder);
775 WixAssert.CompareLineByLine(new[]
776 {
777 @"<basefolder>\Package.wxs(22): error WIX0103: Cannot find the File file '!(bindpath.TestExe.net472.win_x86)\e_sqlite3.dll'. The following paths were checked: !(bindpath.TestExe.net472.win_x86)\e_sqlite3.dll [<basefolder>\PackageUsingExplicitTfmAndRids.wixproj]",
778 }, errors);
779 }
780 }
781
782 [Theory]
783 [InlineData(BuildSystem.DotNetCoreSdk)]
784 [InlineData(BuildSystem.MSBuild)]
785 [InlineData(BuildSystem.MSBuild64)]
786 public void CanBuildWithWarningWhenExtensionIsMissing(BuildSystem buildSystem)
787 {
788 var sourceFolder = TestData.Get(@"TestData", "WixlibMissingExtension");
789
790 using (var fs = new TestDataFolderFileSystem())
791 {
792 fs.Initialize(sourceFolder);
793 var baseFolder = fs.BaseFolder;
794 var binFolder = Path.Combine(baseFolder, @"bin\");
795 var projectPath = Path.Combine(baseFolder, "WixlibMissingExtension.wixproj");
796
797 var result = MsbuildUtilities.BuildProject(buildSystem, projectPath, new[] {
798 MsbuildUtilities.GetQuotedPropertySwitch(buildSystem, "WixMSBuildProps", MsbuildFixture.WixPropsPath),
799 "-p:SignOutput=true",
800 });
801 result.AssertSuccess();
802
803 var warnings = result.Output.Where(line => line.Contains(": warning")).Select(line => ExtractWarningFromMessage(line, baseFolder)).ToArray();
804 WixAssert.CompareLineByLine(new[]
805 {
806 "WXE0001: Unable to find extension DoesNotExist.wixext.dll.",
807 "WXE0001: Unable to find extension DoesNotExist.wixext.dll.",
808 }, warnings);
809
810 var paths = Directory.EnumerateFiles(binFolder, @"*.*", SearchOption.AllDirectories)
811 .Select(s => s.Substring(baseFolder.Length + 1))
812 .OrderBy(s => s)
813 .ToArray();
814 WixAssert.CompareLineByLine(new[]
815 {
816 @"bin\Release\WixlibMissingExtension.wixlib",
817 }, paths);
818 }
819 }
820
821 [Theory]
822 [InlineData(BuildSystem.DotNetCoreSdk)]
823 [InlineData(BuildSystem.MSBuild)]
824 [InlineData(BuildSystem.MSBuild64)]
825 public void CanBuildPackageWithComma(BuildSystem buildSystem)
826 {
827 var sourceFolder = TestData.Get(@"TestData", "PackageWith,Comma");
828
829 using (var fs = new TestDataFolderFileSystem())
830 {
831 fs.Initialize(sourceFolder);
832 var baseFolder = fs.BaseFolder;
833 var binFolder = Path.Combine(baseFolder, @"bin\");
834 var projectPath = Path.Combine(baseFolder, "PackageWith,Comma.wixproj");
835
836 var result = MsbuildUtilities.BuildProject(buildSystem, projectPath, new[]
837 {
838 MsbuildUtilities.GetQuotedPropertySwitch(buildSystem, "WixMSBuildProps", MsbuildFixture.WixPropsPath),
839 });
840 result.AssertSuccess();
841
842 var paths = Directory.EnumerateFiles(binFolder, @"*.*", SearchOption.AllDirectories)
843 .Select(s => s.Substring(baseFolder.Length + 1))
844 .OrderBy(s => s)
845 .ToArray();
846 WixAssert.CompareLineByLine(new[]
847 {
848 @"bin\Release\cab1.cab",
849 @"bin\Release\PackageWith,Comma.msi",
850 @"bin\Release\PackageWith,Comma.wixpdb",
851 }, paths);
852 }
853 }
854
855 [Theory(Skip = "Depends on creating broken publish which is not supported at this time")]
856 [InlineData(BuildSystem.DotNetCoreSdk)]
857 [InlineData(BuildSystem.MSBuild)]
858 [InlineData(BuildSystem.MSBuild64)]
859 public void ReportsInnerExceptionForUnexpectedExceptions(BuildSystem buildSystem)
860 {
861 var sourceFolder = TestData.Get(@"TestData\SimpleMsiPackage\MsiPackage");
862
863 using (var fs = new TestDataFolderFileSystem())
864 {
865 fs.Initialize(sourceFolder);
866 var baseFolder = fs.BaseFolder;
867 var binFolder = Path.Combine(baseFolder, @"bin\");
868 var projectPath = Path.Combine(baseFolder, "MsiPackage.wixproj");
869
870 var result = MsbuildUtilities.BuildProject(buildSystem, projectPath, new[]
871 {
872 MsbuildUtilities.GetQuotedPropertySwitch(buildSystem, "WixToolDir", Path.Combine(MsbuildFixture.WixMsbuildPath, "broken", "net461")),
873 });
874 Assert.Equal(1, result.ExitCode);
875
876 var expectedMessage = "System.PlatformNotSupportedException: Could not find platform specific 'wixnative.exe' ---> System.IO.FileNotFoundException: Could not find internal piece of WiX Toolset from";
877 Assert.Contains(result.Output, m => m.Contains(expectedMessage));
878 }
879 }
880
881 private void AssertWixpdb(BuildSystem buildSystem, string debugType, string[] expectedOutputFiles)
882 {
883 var sourceFolder = TestData.Get("TestData", "SimpleMsiPackage", "MsiPackage");
884
885 using (var fs = new TestDataFolderFileSystem())
886 {
887 fs.Initialize(sourceFolder);
888 var baseFolder = fs.BaseFolder;
889 var binFolder = Path.Combine(baseFolder, @"bin\");
890 var projectPath = Path.Combine(baseFolder, "MsiPackage.wixproj");
891
892 var result = MsbuildUtilities.BuildProject(buildSystem, projectPath, new[]
893 {
894 MsbuildUtilities.GetQuotedPropertySwitch(buildSystem, "WixMSBuildProps", MsbuildFixture.WixPropsPath),
895 debugType == null ? String.Empty : $"-p:DebugType={debugType}",
896 "-p:SuppressValidation=true"
897 });
898 result.AssertSuccess();
899
900 var paths = Directory.EnumerateFiles(binFolder, @"*.*", SearchOption.AllDirectories)
901 .Select(s => s.Substring(baseFolder.Length + 1))
902 .OrderBy(s => s)
903 .ToArray();
904 WixAssert.CompareLineByLine(expectedOutputFiles, paths);
905 }
906 }
907
908 private static string ExtractWarningFromMessage(string message, string baseFolder)
909 {
910 const string prefix = ": warning ";
911
912 var start = message.IndexOf(prefix) + prefix.Length;
913 var end = message.LastIndexOf("[");
914
915 return ReplacePathsInMessage(message.Substring(start, end - start), baseFolder);
916 }
917
918 private static string[] GetDistinctErrorMessages(string[] output, string baseFolder)
919 {
920 return output.Where(l => l.Contains(": error ")).Select(line =>
921 {
922 var trimmed = ReplacePathsInMessage(line, baseFolder);
923
924 // If the message starts with a multi-proc build marker (like: "1>" or "2>") trim it.
925 if (trimmed[1] == '>')
926 {
927 trimmed = trimmed.Substring(2);
928 }
929
930 return trimmed;
931 }).Distinct().ToArray();
932 }
933
934 private static string ReplacePathsInMessage(string message, string baseFolder)
935 {
936 return message.Trim().Replace(baseFolder, "<basefolder>");
937 }
938
939 private static string PathAndSize(string path, string replace)
940 {
941 var fi = new FileInfo(path);
942 return $"{fi.FullName.Replace(replace, String.Empty)} - {fi.Length}";
943 }
944 }
945 }