main
cs 842 lines 41.3 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.Collections.Generic;
7 using System.IO;
8 using System.Linq;
9 using System.Text;
10 using System.Xml;
11 using Example.Extension;
12 using WixInternal.TestSupport;
13 using WixToolset.Core.Burn;
14 using WixInternal.Core.TestPackage;
15 using WixToolset.Data;
16 using WixToolset.Data.Burn;
17 using WixToolset.Data.Symbols;
18 using WixToolset.Dtf.Resources;
19 using Xunit;
20
21 public class BundleFixture
22 {
23 [Fact]
24 public void CanBuildBundleWithBindVariableVersion()
25 {
26 var folder = TestData.Get(@"TestData");
27
28 using (var fs = new DisposableFileSystem())
29 {
30 var baseFolder = fs.GetFolder();
31 var intermediateFolder = Path.Combine(baseFolder, "obj");
32 var exePath = Path.Combine(baseFolder, @"bin\test.exe");
33
34 var result = WixRunner.Execute(new[]
35 {
36 "build",
37 Path.Combine(folder, "BundleBindVariables", "BindVarBundleVersion.wxs"),
38 "-bindpath", Path.Combine(folder, "SimpleBundle", "data"),
39 "-bindpath", Path.Combine(folder, ".Data"),
40 "-intermediateFolder", intermediateFolder,
41 "-o", exePath,
42 });
43
44 result.AssertSuccess();
45
46 Assert.True(File.Exists(exePath));
47 }
48 }
49
50 [Fact]
51 public void CanBuildMultiFileBundle()
52 {
53 var folder = TestData.Get(@"TestData\SimpleBundle");
54
55 using (var fs = new DisposableFileSystem())
56 {
57 var baseFolder = fs.GetFolder();
58 var intermediateFolder = Path.Combine(baseFolder, "obj");
59
60 var result = WixRunner.Execute(new[]
61 {
62 "build",
63 Path.Combine(folder, "MultiFileBootstrapperApplication.wxs"),
64 Path.Combine(folder, "MultiFileBundle.wxs"),
65 "-loc", Path.Combine(folder, "Bundle.en-us.wxl"),
66 "-bindpath", Path.Combine(folder, "data"),
67 "-intermediateFolder", intermediateFolder,
68 "-o", Path.Combine(baseFolder, @"bin\test.exe")
69 });
70
71 result.AssertSuccess();
72
73 Assert.True(File.Exists(Path.Combine(baseFolder, @"bin\test.exe")));
74 Assert.True(File.Exists(Path.Combine(baseFolder, @"bin\test.wixpdb")));
75 }
76 }
77
78 [Fact]
79 public void CanBuildSimpleBundle()
80 {
81 var folder = TestData.Get(@"TestData\SimpleBundle");
82
83 using (var fs = new DisposableFileSystem())
84 {
85 var baseFolder = fs.GetFolder();
86 var intermediateFolder = Path.Combine(baseFolder, "obj");
87 var exePath = Path.Combine(baseFolder, @"bin\test.exe");
88 var pdbPath = Path.Combine(baseFolder, @"bin\test.wixpdb");
89 var baFolderPath = Path.Combine(baseFolder, "ba");
90 var extractFolderPath = Path.Combine(baseFolder, "extract");
91
92 var result = WixRunner.Execute(new[]
93 {
94 "build",
95 Path.Combine(folder, "Bundle.wxs"),
96 "-loc", Path.Combine(folder, "Bundle.en-us.wxl"),
97 "-bindpath", Path.Combine(folder, "data"),
98 "-intermediateFolder", intermediateFolder,
99 "-o", exePath,
100 });
101
102 result.AssertSuccess();
103 Assert.Empty(result.Messages.Where(m => m.Level == MessageLevel.Warning));
104
105 Assert.True(File.Exists(exePath));
106 Assert.True(File.Exists(pdbPath));
107
108 using (var wixOutput = WixOutput.Read(pdbPath))
109 {
110
111 var intermediate = Intermediate.Load(wixOutput);
112 var section = intermediate.Sections.Single();
113
114 var bundleSymbol = section.Symbols.OfType<WixBundleSymbol>().Single();
115 WixAssert.StringEqual("1.0.0.0", bundleSymbol.Version);
116
117 var previousVersion = bundleSymbol.Fields[(int)WixBundleSymbolFields.Version].PreviousValue;
118 WixAssert.StringEqual("!(bind.packageVersion.test.msi)", previousVersion.AsString());
119
120 var msiSymbol = section.Symbols.OfType<WixBundlePackageSymbol>().Single();
121 WixAssert.StringEqual("test.msi", msiSymbol.Id.Id);
122
123 var extractResult = BundleExtractor.ExtractBAContainer(null, exePath, baFolderPath, extractFolderPath);
124 extractResult.AssertSuccess();
125
126 var burnManifestData = wixOutput.GetData(BurnConstants.BurnManifestWixOutputStreamName);
127 var extractedBurnManifestData = File.ReadAllText(Path.Combine(baFolderPath, "manifest.xml"), Encoding.UTF8);
128 WixAssert.StringEqual(extractedBurnManifestData, burnManifestData);
129
130 var baManifestData = wixOutput.GetData(BurnConstants.BootstrapperApplicationDataWixOutputStreamName);
131 var extractedBaManifestData = File.ReadAllText(Path.Combine(baFolderPath, "BootstrapperApplicationData.xml"), Encoding.UTF8);
132 WixAssert.StringEqual(extractedBaManifestData, baManifestData);
133
134 var bextManifestData = wixOutput.GetData(BurnConstants.BootstrapperExtensionDataWixOutputStreamName);
135 var extractedBextManifestData = File.ReadAllText(Path.Combine(baFolderPath, "BootstrapperExtensionData.xml"), Encoding.UTF8);
136 WixAssert.StringEqual(extractedBextManifestData, bextManifestData);
137
138 foreach (XmlAttribute attribute in extractResult.ManifestDocument.DocumentElement.Attributes)
139 {
140 switch (attribute.LocalName)
141 {
142 case "EngineVersion":
143 Assert.True(Version.TryParse(attribute.Value, out var _));
144 break;
145 case "ProtocolVersion":
146 WixAssert.StringEqual("1", attribute.Value);
147 break;
148 case "Win64":
149 WixAssert.StringEqual("no", attribute.Value);
150 break;
151 case "xmlns":
152 WixAssert.StringEqual("http://wixtoolset.org/schemas/v4/2008/Burn", attribute.Value);
153 break;
154 default:
155 Assert.Fail($"Attribute: '{attribute.LocalName}', Value: '{attribute.Value}'");
156 break;
157 }
158 }
159
160 var logElements = extractResult.GetManifestTestXmlLines("/burn:BurnManifest/burn:Log");
161 WixAssert.CompareLineByLine(new[]
162 {
163 "<Log PathVariable='WixBundleLog' Prefix='~TestBundle' Extension='log' />",
164 }, logElements);
165
166 var registrationElements = extractResult.GetManifestTestXmlLines("/burn:BurnManifest/burn:Registration");
167 WixAssert.CompareLineByLine(new[]
168 {
169 $"<Registration Id='{bundleSymbol.BundleId}' ExecutableName='test.exe' PerMachine='yes' Tag='' Version='1.0.0.0' ProviderKey='{bundleSymbol.BundleId}'>" +
170 "<Arp DisplayName='~TestBundle' DisplayVersion='1.0.0.0' InProgressDisplayName='~InProgressTestBundle' Publisher='Example Corporation' />" +
171 "</Registration>",
172 }, registrationElements);
173
174 var ignoreAttributesByElementName = new Dictionary<string, List<string>>() { { "Payload", new List<string> { "FileSize", "Hash" } } };
175 var msiPayloads = extractResult.GetManifestTestXmlLines("/burn:BurnManifest/burn:Payload[@Id='test.msi']", ignoreAttributesByElementName);
176 WixAssert.CompareLineByLine(new[]
177 {
178 "<Payload Id='test.msi' FilePath='test.msi' FileSize='*' Hash='*' Packaging='embedded' SourcePath='a0' Container='WixAttachedContainer' />",
179 }, msiPayloads);
180
181 var msiProperties = extractResult.GetManifestTestXmlLines("/burn:BurnManifest/burn:Chain/burn:MsiPackage[@Id='test.msi']/burn:MsiProperty", ignoreAttributesByElementName);
182 WixAssert.CompareLineByLine(new[]
183 {
184 "<MsiProperty Id='TEST' Value='1' />",
185 "<MsiProperty Id='TESTBLANK' Value='' />",
186 "<MsiProperty Id='ARPSYSTEMCOMPONENT' Value='1' />",
187 "<MsiProperty Id='MSIFASTINSTALL' Value='7' />",
188 }, msiProperties);
189 }
190
191 var manifestResource = new Resource(ResourceType.Manifest, "#1", 1033);
192 manifestResource.Load(exePath);
193 var actualManifestData = Encoding.UTF8.GetString(manifestResource.Data);
194 WixAssert.StringEqual("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\r\n" +
195 "<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">" +
196 "<assemblyIdentity name=\"WixToolset.Burn\" version=\"5.0.0.0\" type=\"win32\"></assemblyIdentity><description>WiX Toolset Bootstrapper Engine</description>" +
197 "<trustInfo xmlns=\"urn:schemas-microsoft-com:asm.v3\"><security><requestedPrivileges><requestedExecutionLevel level=\"asInvoker\" uiAccess=\"false\"></requestedExecutionLevel></requestedPrivileges></security></trustInfo>" +
198 "<application xmlns=\"urn:schemas-microsoft-com:asm.v3\"><windowsSettings>" +
199 "<dpiAware xmlns=\"http://schemas.microsoft.com/SMI/2005/WindowsSettings\">true/pm</dpiAware>" +
200 "<dpiAwareness xmlns=\"http://schemas.microsoft.com/SMI/2016/WindowsSettings\">PerMonitorV2, PerMonitor, System</dpiAwareness>" +
201 "<longPathAware xmlns=\"http://schemas.microsoft.com/SMI/2016/WindowsSettings\">true</longPathAware>" +
202 "</windowsSettings></application>" +
203 "<ms_compatibility:compatibility xmlns:ms_compatibility=\"urn:schemas-microsoft-com:compatibility.v1\" xmlns=\"urn:schemas-microsoft-com:compatibility.v1\">" +
204 "<ms_compatibility:application xmlns:ms_compatibility=\"urn:schemas-microsoft-com:compatibility.v1\">" +
205 "<ms_compatibility:supportedOS xmlns:ms_compatibility=\"urn:schemas-microsoft-com:compatibility.v1\" Id=\"{e2011457-1546-43c5-a5fe-008deee3d3f0}\"></ms_compatibility:supportedOS>" +
206 "<ms_compatibility:supportedOS xmlns:ms_compatibility=\"urn:schemas-microsoft-com:compatibility.v1\" Id=\"{35138b9a-5d96-4fbd-8e2d-a2440225f93a}\"></ms_compatibility:supportedOS>" +
207 "<ms_compatibility:supportedOS xmlns:ms_compatibility=\"urn:schemas-microsoft-com:compatibility.v1\" Id=\"{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}\"></ms_compatibility:supportedOS>" +
208 "<ms_compatibility:supportedOS xmlns:ms_compatibility=\"urn:schemas-microsoft-com:compatibility.v1\" Id=\"{1f676c76-80e1-4239-95bb-83d0f6d0da78}\"></ms_compatibility:supportedOS>" +
209 "<ms_compatibility:supportedOS xmlns:ms_compatibility=\"urn:schemas-microsoft-com:compatibility.v1\" Id=\"{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}\"></ms_compatibility:supportedOS>" +
210 "</ms_compatibility:application></ms_compatibility:compatibility>" +
211 "</assembly>", actualManifestData);
212 }
213 }
214
215 [Fact]
216 public void CanBuildX64Bundle()
217 {
218 var folder = TestData.Get(@"TestData\SimpleBundle");
219
220 using (var fs = new DisposableFileSystem())
221 {
222 var baseFolder = fs.GetFolder();
223 var intermediateFolder = Path.Combine(baseFolder, "obj");
224 var exePath = Path.Combine(baseFolder, @"bin\test.exe");
225 var pdbPath = Path.Combine(baseFolder, @"bin\test.wixpdb");
226 var baFolderPath = Path.Combine(baseFolder, "ba");
227 var attachedFolderPath = Path.Combine(baseFolder, "attached");
228 var extractFolderPath = Path.Combine(baseFolder, "extract");
229
230 var result = WixRunner.Execute(new[]
231 {
232 "build",
233 "-arch", "x64",
234 Path.Combine(folder, "Bundle.wxs"),
235 "-loc", Path.Combine(folder, "Bundle.en-us.wxl"),
236 "-bindpath", Path.Combine(folder, "data"),
237 "-intermediateFolder", intermediateFolder,
238 "-o", exePath,
239 });
240
241 result.AssertSuccess();
242
243 Assert.True(File.Exists(exePath));
244 Assert.True(File.Exists(pdbPath));
245
246 var manifestResource = new Resource(ResourceType.Manifest, "#1", 1033);
247 manifestResource.Load(exePath);
248 var actualManifestData = Encoding.UTF8.GetString(manifestResource.Data);
249 WixAssert.StringEqual("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\r\n" +
250 "<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">" +
251 "<assemblyIdentity name=\"WixToolset.Burn\" version=\"5.0.0.0\" type=\"win32\"></assemblyIdentity><description>WiX Toolset Bootstrapper Engine</description>" +
252 "<trustInfo xmlns=\"urn:schemas-microsoft-com:asm.v3\"><security><requestedPrivileges><requestedExecutionLevel level=\"asInvoker\" uiAccess=\"false\"></requestedExecutionLevel></requestedPrivileges></security></trustInfo>" +
253 "<application xmlns=\"urn:schemas-microsoft-com:asm.v3\"><windowsSettings>" +
254 "<dpiAware xmlns=\"http://schemas.microsoft.com/SMI/2005/WindowsSettings\">true/pm</dpiAware>" +
255 "<dpiAwareness xmlns=\"http://schemas.microsoft.com/SMI/2016/WindowsSettings\">PerMonitorV2, PerMonitor, System</dpiAwareness>" +
256 "<longPathAware xmlns=\"http://schemas.microsoft.com/SMI/2016/WindowsSettings\">true</longPathAware>" +
257 "</windowsSettings></application>" +
258 "<ms_compatibility:compatibility xmlns:ms_compatibility=\"urn:schemas-microsoft-com:compatibility.v1\" xmlns=\"urn:schemas-microsoft-com:compatibility.v1\">" +
259 "<ms_compatibility:application xmlns:ms_compatibility=\"urn:schemas-microsoft-com:compatibility.v1\">" +
260 "<ms_compatibility:supportedOS xmlns:ms_compatibility=\"urn:schemas-microsoft-com:compatibility.v1\" Id=\"{e2011457-1546-43c5-a5fe-008deee3d3f0}\"></ms_compatibility:supportedOS>" +
261 "<ms_compatibility:supportedOS xmlns:ms_compatibility=\"urn:schemas-microsoft-com:compatibility.v1\" Id=\"{35138b9a-5d96-4fbd-8e2d-a2440225f93a}\"></ms_compatibility:supportedOS>" +
262 "<ms_compatibility:supportedOS xmlns:ms_compatibility=\"urn:schemas-microsoft-com:compatibility.v1\" Id=\"{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}\"></ms_compatibility:supportedOS>" +
263 "<ms_compatibility:supportedOS xmlns:ms_compatibility=\"urn:schemas-microsoft-com:compatibility.v1\" Id=\"{1f676c76-80e1-4239-95bb-83d0f6d0da78}\"></ms_compatibility:supportedOS>" +
264 "<ms_compatibility:supportedOS xmlns:ms_compatibility=\"urn:schemas-microsoft-com:compatibility.v1\" Id=\"{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}\"></ms_compatibility:supportedOS>" +
265 "</ms_compatibility:application></ms_compatibility:compatibility>" +
266 "</assembly>", actualManifestData);
267
268 var extractResult = BundleExtractor.ExtractAllContainers(null, exePath, baFolderPath, attachedFolderPath, extractFolderPath);
269 extractResult.AssertSuccess();
270
271 foreach (XmlAttribute attribute in extractResult.ManifestDocument.DocumentElement.Attributes)
272 {
273 switch (attribute.LocalName)
274 {
275 case "EngineVersion":
276 Assert.True(Version.TryParse(attribute.Value, out var _));
277 break;
278 case "ProtocolVersion":
279 WixAssert.StringEqual("1", attribute.Value);
280 break;
281 case "Win64":
282 WixAssert.StringEqual("yes", attribute.Value);
283 break;
284 case "xmlns":
285 WixAssert.StringEqual("http://wixtoolset.org/schemas/v4/2008/Burn", attribute.Value);
286 break;
287 default:
288 Assert.Fail($"Attribute: '{attribute.LocalName}', Value: '{attribute.Value}'");
289 break;
290 }
291 }
292 }
293 }
294
295 [Fact]
296 public void CanBuildSimpleBundleUsingExtensionBA()
297 {
298 var folder = TestData.Get(@"TestData\SimpleBundle");
299
300 using (var fs = new DisposableFileSystem())
301 {
302 var baseFolder = fs.GetFolder();
303 var intermediateFolder = Path.Combine(baseFolder, "obj");
304
305 var result = WixRunner.Execute(new[]
306 {
307 "build",
308 Path.Combine(folder, "MultiFileBundle.wxs"),
309 "-loc", Path.Combine(folder, "Bundle.en-us.wxl"),
310 "-ext", ExtensionPaths.ExampleExtensionPath,
311 "-bindpath", Path.Combine(folder, "data"),
312 "-intermediateFolder", intermediateFolder,
313 "-o", Path.Combine(baseFolder, @"bin\test.exe")
314 });
315
316 result.AssertSuccess();
317
318 Assert.True(File.Exists(Path.Combine(baseFolder, @"bin\test.exe")));
319 Assert.True(File.Exists(Path.Combine(baseFolder, @"bin\test.wixpdb")));
320 }
321 }
322
323 [Fact]
324 public void CanBuildSimpleBundleUsingInclude()
325 {
326 var folder = TestData.Get(@"TestData", "IncludePath");
327 var dataFolder = TestData.Get(@"TestData", "SimpleBundle", "data");
328
329 using (var fs = new DisposableFileSystem())
330 {
331 var baseFolder = fs.GetFolder();
332 var intermediateFolder = Path.Combine(baseFolder, "obj");
333 var exePath = Path.Combine(baseFolder, @"bin\test.exe");
334 var pdbPath = Path.Combine(baseFolder, @"bin\test.wixpdb");
335
336 var result = WixRunner.Execute(new[]
337 {
338 "build",
339 Path.Combine(folder, "Bundle.wxs"),
340 "-loc", Path.Combine(folder, "Bundle.en-us.wxl"),
341 "-bindpath", dataFolder,
342 "-intermediateFolder", intermediateFolder,
343 "-o", exePath,
344 });
345
346 result.AssertSuccess();
347
348 using (var wixOutput = WixOutput.Read(pdbPath))
349 {
350
351 var intermediate = Intermediate.Load(wixOutput);
352 var section = intermediate.Sections.Single();
353
354 var bundleSymbol = section.Symbols.OfType<WixBundleSymbol>().Single();
355 WixAssert.StringEqual("~IncludeTestBundle", bundleSymbol.Name);
356 }
357 }
358 }
359
360 [Fact]
361 public void CanBuildSingleExeBundle()
362 {
363 var folder = TestData.Get(@"TestData");
364
365 using (var fs = new DisposableFileSystem())
366 {
367 var baseFolder = fs.GetFolder();
368 var intermediateFolder = Path.Combine(baseFolder, "obj");
369 var exePath = Path.Combine(baseFolder, @"bin\test.exe");
370
371 var result = WixRunner.Execute(new[]
372 {
373 "build",
374 Path.Combine(folder, "SingleExeBundle", "SingleExePackageGroup.wxs"),
375 Path.Combine(folder, "BundleWithPackageGroupRef", "Bundle.wxs"),
376 "-bindpath", Path.Combine(folder, "SimpleBundle", "data"),
377 "-bindpath", Path.Combine(folder, ".Data"),
378 "-intermediateFolder", intermediateFolder,
379 "-o", exePath,
380 });
381
382 result.AssertSuccess();
383
384 Assert.True(File.Exists(exePath));
385 }
386 }
387
388 [Fact]
389 public void CanBuildSingleExeRemotePayloadBundle()
390 {
391 var folder = TestData.Get(@"TestData");
392
393 using (var fs = new DisposableFileSystem())
394 {
395 var baseFolder = fs.GetFolder();
396 var intermediateFolder = Path.Combine(baseFolder, "obj");
397 var exePath = Path.Combine(baseFolder, @"bin\test.exe");
398 var pdbPath = Path.Combine(baseFolder, @"bin\test.wixpdb");
399
400 var result = WixRunner.Execute(new[]
401 {
402 "build",
403 Path.Combine(folder, "SingleExeBundle", "SingleExeRemotePayload.wxs"),
404 Path.Combine(folder, "BundleWithPackageGroupRef", "Bundle.wxs"),
405 "-bindpath", Path.Combine(folder, "SimpleBundle", "data"),
406 "-intermediateFolder", intermediateFolder,
407 "-o", exePath,
408 });
409
410 result.AssertSuccess();
411
412 Assert.True(File.Exists(exePath));
413 Assert.True(File.Exists(pdbPath));
414
415 using (var wixOutput = WixOutput.Read(pdbPath))
416 {
417 var intermediate = Intermediate.Load(wixOutput);
418 var section = intermediate.Sections.Single();
419
420 var packageSymbol = section.Symbols.OfType<WixBundlePackageSymbol>().Where(x => x.Id.Id == "NetFx462Web").Single();
421 Assert.Equal(Int64.MaxValue, packageSymbol.InstallSize);
422
423 var payloadSymbol = section.Symbols.OfType<WixBundlePayloadSymbol>().Where(x => x.Id.Id == "NetFx462Web").Single();
424 Assert.Equal(Int64.MaxValue, payloadSymbol.FileSize);
425 }
426 }
427 }
428
429 [Fact]
430 public void CannotBuildBundleMissingMsiSource()
431 {
432 var folder = TestData.Get(@"TestData");
433
434 using (var fs = new DisposableFileSystem())
435 {
436 var baseFolder = fs.GetFolder();
437 var intermediateFolder = Path.Combine(baseFolder, "obj");
438
439 var result = WixRunner.Execute(new[]
440 {
441 "build",
442 Path.Combine(folder, "BundleWithMissingSource", "BundleMissingMsiSource.wxs"),
443 "-bindpath", Path.Combine(folder, ".Data"),
444 "-intermediateFolder", intermediateFolder,
445 "-o", Path.Combine(baseFolder, @"bin\test.exe")
446 });
447
448 var message = result.Messages.Where(m => m.Level == MessageLevel.Error).Select(m => m.ToString().Replace(folder, "<testdata>")).ToArray();
449 WixAssert.CompareLineByLine(new[]
450 {
451 @"The MsiPackage element's Name or SourceFile attribute was not found; one of these is required."
452 }, message);
453 }
454 }
455
456 [Fact]
457 public void CannotBuildBundleMissingMsuSource()
458 {
459 var folder = TestData.Get(@"TestData");
460
461 using (var fs = new DisposableFileSystem())
462 {
463 var baseFolder = fs.GetFolder();
464 var intermediateFolder = Path.Combine(baseFolder, "obj");
465
466 var result = WixRunner.Execute(new[]
467 {
468 "build",
469 Path.Combine(folder, "BundleWithMissingSource", "BundleMissingMsuSource.wxs"),
470 "-bindpath", Path.Combine(folder, ".Data"),
471 "-intermediateFolder", intermediateFolder,
472 "-o", Path.Combine(baseFolder, @"bin\test.exe")
473 });
474
475 var message = result.Messages.Where(m => m.Level == MessageLevel.Error).Select(m => m.ToString().Replace(folder, "<testdata>")).ToArray();
476 WixAssert.CompareLineByLine(new[]
477 {
478 @"The MsuPackage element's Name or SourceFile attribute was not found; one of these is required."
479 }, message);
480 }
481 }
482
483 [Fact]
484 public void CannotBuildBundleWithInvalidIcon()
485 {
486 var folder = TestData.Get(@"TestData");
487
488 using (var fs = new DisposableFileSystem())
489 {
490 var baseFolder = fs.GetFolder();
491 var intermediateFolder = Path.Combine(baseFolder, "obj");
492
493 var result = WixRunner.Execute(new[]
494 {
495 "build",
496 Path.Combine(folder, "BundleWithInvalid", "BundleWithInvalidIcon.wxs"),
497 "-bindpath", Path.Combine(folder, ".Data"),
498 "-bindpath", Path.Combine(folder, "SimpleBundle", "data"),
499 "-intermediateFolder", intermediateFolder,
500 "-o", Path.Combine(baseFolder, @"bin\test.exe")
501 });
502
503 var message = result.Messages.Where(m => m.Level == MessageLevel.Error).Select(m => m.ToString().Replace(folder, "<testdata>")).ToArray();
504 WixAssert.CompareLineByLine(new[]
505 {
506 @"Failed to update resources in the bundle. Ensure the bundle icon file is an icon file at '<testdata>\.Data\burn.exe'. Detail: Failed to save resource. Error: 87"
507 }, message);
508 }
509 }
510
511 [Fact]
512 public void CannotBuildBundleWithInvalidUpgradeCode()
513 {
514 var folder = TestData.Get(@"TestData");
515
516 using (var fs = new DisposableFileSystem())
517 {
518 var baseFolder = fs.GetFolder();
519 var intermediateFolder = Path.Combine(baseFolder, "obj");
520
521 var result = WixRunner.Execute(new[]
522 {
523 "build",
524 Path.Combine(folder, "BundleLocalized", "BundleWithLocalizedUpgradeCode.wxs"),
525 "-loc", Path.Combine(folder, "BundleLocalized", "BundleWithInvalidUpgradeCode.wxl"),
526 "-bindpath", Path.Combine(folder, ".Data"),
527 "-bindpath", Path.Combine(folder, "SimpleBundle", "data"),
528 "-intermediateFolder", intermediateFolder,
529 "-o", Path.Combine(baseFolder, @"bin\test.exe")
530 });
531
532 var message = result.Messages.Where(m => m.Level == MessageLevel.Error).Select(m => m.ToString().Replace(folder, "<testdata>")).ToArray();
533 WixAssert.CompareLineByLine(new[]
534 {
535 "The Bundle/@UpgradeCode attribute's value, 'NOT-A-GUID', is not a legal guid value."
536 }, message);
537 }
538 }
539
540 [Fact]
541 public void CanBuildUncompressedBundle()
542 {
543 var folder = TestData.Get(@"TestData") + Path.DirectorySeparatorChar;
544
545 using (var fs = new DisposableFileSystem())
546 {
547 var baseFolder = fs.GetFolder() + Path.DirectorySeparatorChar;
548 var intermediateFolder = Path.Combine(baseFolder, "obj");
549 var exePath = Path.Combine(baseFolder, @"bin\test.exe");
550 var trackingFile = Path.Combine(intermediateFolder, "trackingFile.txt");
551
552 var result = WixRunner.Execute(new[]
553 {
554 "build",
555 Path.Combine(folder, "BundleUncompressed", "UncompressedBundle.wxs"),
556 "-bindpath", Path.Combine(folder, "SimpleBundle", "data"),
557 "-bindpath", Path.Combine(folder, ".Data"),
558 "-intermediateFolder", intermediateFolder,
559 "-o", exePath,
560 "-trackingFile", trackingFile
561 });
562
563 result.AssertSuccess();
564
565 Assert.True(File.Exists(exePath));
566 Assert.True(File.Exists(Path.Combine(Path.GetDirectoryName(exePath), "test.txt")));
567
568 var trackedLines = File.ReadAllLines(trackingFile).Select(s => s.Replace(baseFolder, null, StringComparison.OrdinalIgnoreCase).Replace(folder, null, StringComparison.OrdinalIgnoreCase))
569 .OrderBy(s => s)
570 .ToArray();
571 WixAssert.CompareLineByLine(new[]
572 {
573 "BuiltPdbOutput\tbin\\test.wixpdb",
574 "BuiltTargetOutput\tbin\\test.exe",
575 "CopiedOutput\tbin\\test.txt",
576 "Input\tSimpleBundle\\data\\fakeba.dll",
577 "Input\tSimpleBundle\\data\\MsiPackage\\test.txt"
578 }, trackedLines);
579 }
580 }
581
582 [Fact]
583 public void CannotBuildWithDuplicateCacheIds()
584 {
585 var folder = TestData.Get(@"TestData");
586
587 using (var fs = new DisposableFileSystem())
588 {
589 var baseFolder = fs.GetFolder();
590 var intermediateFolder = Path.Combine(baseFolder, "obj");
591 var exePath = Path.Combine(baseFolder, @"bin\test.exe");
592
593 var result = WixRunner.Execute(new[]
594 {
595 "build",
596 Path.Combine(folder, "BadInput", "DuplicateCacheIds.wxs"),
597 Path.Combine(folder, "BundleWithPackageGroupRef", "Bundle.wxs"),
598 "-bindpath", Path.Combine(folder, "SimpleBundle", "data"),
599 "-bindpath", Path.Combine(folder, ".Data"),
600 "-intermediateFolder", intermediateFolder,
601 "-o", exePath,
602 });
603
604 Assert.Equal(8001, result.ExitCode);
605 }
606 }
607
608 [Fact]
609 public void CannotBuildWithDuplicatePayloadNames()
610 {
611 var folder = TestData.Get(@"TestData");
612
613 using (var fs = new DisposableFileSystem())
614 {
615 var baseFolder = fs.GetFolder();
616 var intermediateFolder = Path.Combine(baseFolder, "obj");
617 var exePath = Path.Combine(baseFolder, @"bin", "test.exe");
618
619 var result = WixRunner.Execute(new[]
620 {
621 "build",
622 Path.Combine(folder, "BadInput", "DuplicatePayloadNames.wxs"),
623 Path.Combine(folder, "BundleWithPackageGroupRef", "Bundle.wxs"),
624 "-bindpath", Path.Combine(folder, "SimpleBundle", "data"),
625 "-bindpath", Path.Combine(folder, ".Data"),
626 "-intermediateFolder", intermediateFolder,
627 "-o", exePath,
628 });
629
630 var messages = result.Messages.Select(WixMessageFormatter.FormatMessage).OrderBy(m => m).ToArray();
631 WixAssert.CompareLineByLine(new string[]
632 {
633 "Error 8002: The Payload 'DuplicatePayloadNames.wxs' has a duplicate Name 'fakeba.dll' in the BA container. When extracting the container at runtime, the file will get overwritten.",
634 "Error 8002: The Payload 'uxmKgAFS4cS31ZH_Myfqo5J4kHixQ' has a duplicate Name 'BootstrapperExtensionData.xml' in the BA container. When extracting the container at runtime, the file will get overwritten.",
635 "Error 8002: The Payload 'uxTxMXPVMXwQrPTMIGa5WGt93w0Ns' has a duplicate Name 'BootstrapperApplicationData.xml' in the BA container. When extracting the container at runtime, the file will get overwritten.",
636 "Error 8003: The location of the payload related to the previous error.",
637 "Error 8003: The location of the payload related to the previous error.",
638 "Error 8003: The location of the payload related to the previous error.",
639 "Error 8004: The external Container 'MsiPackagesContainer' has a duplicate Name 'ContainerCollision'. When building the bundle or laying out the bundle, the file will get overwritten.",
640 "Error 8004: The external Payload 'HiddenPersistedBundleVariable.wxs' has a duplicate Name 'PayloadCollision'. When building the bundle or laying out the bundle, the file will get overwritten.",
641 "Error 8005: The location of the symbol related to the previous error.",
642 "Error 8005: The location of the symbol related to the previous error.",
643 "Error 8006: The Payload 'test.msi' has a duplicate Name 'test.msi' in package 'test.msi'. When caching the package, the file will get overwritten.",
644 "Error 8007: The location of the payload related to the previous error.",
645 "Error 8500: The Payload 'Auto2' has a duplicate Name 'burn.exe' in the attached container. When extracting the bundle with `wix burn extract`, the file will get overwritten.",
646 "Error 8501: The location of the payload related to the previous error."
647 }, messages);
648 }
649 }
650
651 [Fact]
652 public void CannotBuildWithOrphanPayload()
653 {
654 var folder = TestData.Get(@"TestData");
655
656 using (var fs = new DisposableFileSystem())
657 {
658 var baseFolder = fs.GetFolder();
659 var intermediateFolder = Path.Combine(baseFolder, "obj");
660 var exePath = Path.Combine(baseFolder, @"bin\test.exe");
661
662 var result = WixRunner.Execute(new[]
663 {
664 "build",
665 Path.Combine(folder, "BadInput", "OrphanPayload.wxs"),
666 Path.Combine(folder, "BundleWithPackageGroupRef", "Bundle.wxs"),
667 Path.Combine(folder, "BundleWithPackageGroupRef", "MinimalPackageGroup.wxs"),
668 "-bindpath", Path.Combine(folder, "SimpleBundle", "data"),
669 "-bindpath", Path.Combine(folder, ".Data"),
670 "-intermediateFolder", intermediateFolder,
671 "-o", exePath,
672 });
673
674 Assert.Equal(7000, result.ExitCode);
675 }
676 }
677
678 [Fact]
679 public void CannotBuildWithPackageInMultipleContainers()
680 {
681 var folder = TestData.Get(@"TestData");
682
683 using (var fs = new DisposableFileSystem())
684 {
685 var baseFolder = fs.GetFolder();
686 var intermediateFolder = Path.Combine(baseFolder, "obj");
687 var exePath = Path.Combine(baseFolder, @"bin\test.exe");
688
689 var result = WixRunner.Execute(new[]
690 {
691 "build",
692 Path.Combine(folder, "BadInput", "PackageInMultipleContainers.wxs"),
693 Path.Combine(folder, "BundleWithPackageGroupRef", "Bundle.wxs"),
694 Path.Combine(folder, "BundleWithPackageGroupRef", "MinimalPackageGroup.wxs"),
695 "-bindpath", Path.Combine(folder, "SimpleBundle", "data"),
696 "-bindpath", Path.Combine(folder, ".Data"),
697 "-intermediateFolder", intermediateFolder,
698 "-o", exePath,
699 });
700
701 Assert.Equal(7001, result.ExitCode);
702 }
703 }
704
705 [Fact]
706 public void CanBuildWithSubfolderContainer()
707 {
708 var folder = TestData.Get(@"TestData");
709
710 using (var fs = new DisposableFileSystem())
711 {
712 var baseFolder = fs.GetFolder();
713 var intermediateFolder = Path.Combine(baseFolder, "obj");
714 var exePath = Path.Combine(baseFolder, @"bin", "test.exe");
715 var containerPath = Path.Combine(baseFolder, "bin", "Data", "c1");
716
717 var result = WixRunner.Execute(new[]
718 {
719 "build",
720 Path.Combine(folder, "Bundle", "SubfolderContainer.wxs"),
721 Path.Combine(folder, "BundleWithPackageGroupRef", "Bundle.wxs"),
722 "-bindpath", Path.Combine(folder, "SimpleBundle", "data"),
723 "-bindpath", Path.Combine(folder, ".Data"),
724 "-intermediateFolder", intermediateFolder,
725 "-o", exePath,
726 });
727
728 result.AssertSuccess();
729
730 Assert.True(File.Exists(containerPath), $"Failed to find external container: {containerPath}");
731 }
732 }
733
734 [Fact]
735 public void CannotBuildWithUnscheduledPackage()
736 {
737 var folder = TestData.Get(@"TestData");
738
739 using (var fs = new DisposableFileSystem())
740 {
741 var baseFolder = fs.GetFolder();
742 var intermediateFolder = Path.Combine(baseFolder, "obj");
743 var exePath = Path.Combine(baseFolder, @"bin\test.exe");
744
745 var result = WixRunner.Execute(new[]
746 {
747 "build",
748 Path.Combine(folder, "BadInput", "UnscheduledPackage.wxs"),
749 Path.Combine(folder, "BundleWithPackageGroupRef", "Bundle.wxs"),
750 "-bindpath", Path.Combine(folder, "SimpleBundle", "data"),
751 "-bindpath", Path.Combine(folder, ".Data"),
752 "-intermediateFolder", intermediateFolder,
753 "-o", exePath,
754 });
755
756 Assert.Equal(7003, result.ExitCode);
757 }
758 }
759
760 [Fact]
761 public void CannotBuildWithUnscheduledRollbackBoundary()
762 {
763 var folder = TestData.Get(@"TestData");
764
765 using (var fs = new DisposableFileSystem())
766 {
767 var baseFolder = fs.GetFolder();
768 var intermediateFolder = Path.Combine(baseFolder, "obj");
769 var exePath = Path.Combine(baseFolder, @"bin\test.exe");
770
771 var result = WixRunner.Execute(new[]
772 {
773 "build",
774 Path.Combine(folder, "BadInput", "UnscheduledRollbackBoundary.wxs"),
775 Path.Combine(folder, "BundleWithPackageGroupRef", "Bundle.wxs"),
776 "-bindpath", Path.Combine(folder, "SimpleBundle", "data"),
777 "-bindpath", Path.Combine(folder, ".Data"),
778 "-intermediateFolder", intermediateFolder,
779 "-o", exePath,
780 });
781
782 Assert.Equal(7004, result.ExitCode);
783 }
784 }
785
786 [Fact]
787 public void CannotBuildWithMissingBootstrapperApplication()
788 {
789 var folder = TestData.Get(@"TestData");
790
791 using (var fs = new DisposableFileSystem())
792 {
793 var baseFolder = fs.GetFolder();
794 var intermediateFolder = Path.Combine(baseFolder, "obj");
795 var exePath = Path.Combine(baseFolder, "bin", "test.exe");
796
797 var result = WixRunner.Execute(new[]
798 {
799 "build",
800 Path.Combine(folder, "BundleWithInvalid", "BundleWithMissingBA.wxs"),
801 "-bindpath", Path.Combine(folder, ".Data"),
802 "-intermediateFolder", intermediateFolder,
803 "-o", exePath,
804 });
805
806 var messages = result.Messages.Select(WixMessageFormatter.FormatMessage).ToArray();
807
808 WixAssert.CompareLineByLine(new[]
809 {
810 "Error 8015: A BundleApplication is required to build a bundle."
811 }, messages);
812 }
813 }
814
815 [Fact]
816 public void CanBuildBundleWithMsiPackageWithoutComponents()
817 {
818 var folder = TestData.Get(@"TestData\BundleWithComponentlessPackage");
819
820 using (var fs = new DisposableFileSystem())
821 {
822 var baseFolder = fs.GetFolder();
823 var intermediateFolder = Path.Combine(baseFolder, "obj");
824
825 var result = WixRunner.Execute(new[]
826 {
827 "build",
828 Path.Combine(folder, "Bundle.wxs"),
829 "-loc", Path.Combine(folder, "Bundle.en-us.wxl"),
830 "-bindpath", Path.Combine(folder, "data"),
831 "-intermediateFolder", intermediateFolder,
832 "-o", Path.Combine(baseFolder, @"bin\test.exe")
833 });
834
835 result.AssertSuccess();
836
837 Assert.True(File.Exists(Path.Combine(baseFolder, @"bin\test.exe")));
838 Assert.True(File.Exists(Path.Combine(baseFolder, @"bin\test.wixpdb")));
839 }
840 }
841 }
842 }