@joebigelow / wix-1 / commits / d24800eb

Allow MsiPackage ForcePerMachine to set the ALLUSERS property

Fixes 7232

Rob Mensching committed Feb 22, 2023 at 00:53 UTC d24800ebb5b9693041d41dbcb7d620e3441c822d
4 files changed +122 -50
src/wix/WixToolset.Core.Burn/Bundles/PerformBundleBackendValidationCommand.cs
+8 -1
@@ -130,7 +130,14 @@ namespace WixToolset.Core.Burn.Bundles
130
131 private void ValidateMsiProperty(WixBundleMsiPropertySymbol symbol)
132 {
133 - this.BackendHelper.ValidateBundleMsiPropertyName(symbol.SourceLineNumbers, "MsiProperty", "Name", symbol.Name);
133 + // Validate the MSI properties *except* for the ALLUSERS property when set during binding (most likely
134 + // by the MsiPackage/@ForcePerMachine attribute).
135 + var nameField = symbol.Fields[(int)WixBundleMsiPropertySymbolFields.Name];
136 + var name = nameField.AsString();
137 + if (name != "ALLUSERS" || nameField.Context != "wix.bind")
138 + {
139 + this.BackendHelper.ValidateBundleMsiPropertyName(symbol.SourceLineNumbers, "MsiProperty", "Name", name);
140 + }
141
142 if (symbol.Condition != null)
143 {
src/wix/test/WixToolsetTest.CoreIntegration/BundlePackageFixture.cs
+89 -49
@@ -51,16 +51,7 @@ namespace WixToolsetTest.CoreIntegration
51
52 Assert.True(File.Exists(chainBundlePath));
53
54 - string chainBundleId;
55 - using (var wixOutput = WixOutput.Read(chainPdbPath))
56 - {
57 -
58 - var intermediate = Intermediate.Load(wixOutput);
59 - var section = intermediate.Sections.Single();
60 -
61 - var bundleSymbol = section.Symbols.OfType<WixBundleSymbol>().Single();
62 - chainBundleId = bundleSymbol.BundleId;
63 - }
54 + var chainBundleId = GetBundleIdFromWixpdb(chainPdbPath);
55
56 // parent.exe
57 result = WixRunner.Execute(new[]
@@ -78,16 +69,7 @@ namespace WixToolsetTest.CoreIntegration
69
70 Assert.True(File.Exists(parentBundlePath));
71
81 - string parentBundleId;
82 - using (var wixOutput = WixOutput.Read(parentPdbPath))
83 - {
84 -
85 - var intermediate = Intermediate.Load(wixOutput);
86 - var section = intermediate.Sections.Single();
87 -
88 - var bundleSymbol = section.Symbols.OfType<WixBundleSymbol>().Single();
89 - parentBundleId = bundleSymbol.BundleId;
90 - }
72 + var parentBundleId = GetBundleIdFromWixpdb(parentPdbPath);
73
74 var extractResult = BundleExtractor.ExtractBAContainer(null, parentBundlePath, parentBaFolderPath, extractFolderPath);
75 extractResult.AssertSuccess();
@@ -140,16 +122,7 @@ namespace WixToolsetTest.CoreIntegration
122
123 Assert.True(File.Exists(grandparentBundlePath));
124
143 - string grandparentBundleId;
144 - using (var wixOutput = WixOutput.Read(grandparentPdbPath))
145 - {
146 -
147 - var intermediate = Intermediate.Load(wixOutput);
148 - var section = intermediate.Sections.Single();
149 -
150 - var bundleSymbol = section.Symbols.OfType<WixBundleSymbol>().Single();
151 - grandparentBundleId = bundleSymbol.BundleId;
152 - }
125 + var grandparentBundleId = GetBundleIdFromWixpdb(grandparentPdbPath);
126
127 var grandparentExtractResult = BundleExtractor.ExtractBAContainer(null, grandparentBundlePath, grandparentBaFolderPath, extractFolderPath);
128 grandparentExtractResult.AssertSuccess();
@@ -229,16 +202,8 @@ namespace WixToolsetTest.CoreIntegration
202 Assert.True(File.Exists(parentBundlePath));
203
204 var chainBundleId = "{216BDA7F-74BD-45E8-957B-500552F05629}";
232 - string parentBundleId;
233 - using (var wixOutput = WixOutput.Read(parentPdbPath))
234 - {
235 -
236 - var intermediate = Intermediate.Load(wixOutput);
237 - var section = intermediate.Sections.Single();
205
239 - var bundleSymbol = section.Symbols.OfType<WixBundleSymbol>().Single();
240 - parentBundleId = bundleSymbol.BundleId;
241 - }
206 + var parentBundleId = GetBundleIdFromWixpdb(parentPdbPath);
207
208 var extractResult = BundleExtractor.ExtractBAContainer(null, parentBundlePath, parentBaFolderPath, extractFolderPath);
209 extractResult.AssertSuccess();
@@ -316,16 +281,7 @@ namespace WixToolsetTest.CoreIntegration
281
282 Assert.True(File.Exists(parentBundlePath));
283
319 - string parentBundleId;
320 - using (var wixOutput = WixOutput.Read(parentPdbPath))
321 - {
322 -
323 - var intermediate = Intermediate.Load(wixOutput);
324 - var section = intermediate.Sections.Single();
325 -
326 - var bundleSymbol = section.Symbols.OfType<WixBundleSymbol>().Single();
327 - parentBundleId = bundleSymbol.BundleId;
328 - }
284 + var parentBundleId = GetBundleIdFromWixpdb(parentPdbPath);
285
286 var extractResult = BundleExtractor.ExtractBAContainer(null, parentBundlePath, baFolderPath, extractFolderPath);
287 extractResult.AssertSuccess();
@@ -363,5 +319,89 @@ namespace WixToolsetTest.CoreIntegration
319 }, packageElements);
320 }
321 }
322 +
323 + [Fact]
324 + public void CanBuildBundleWithAllUsersPackage()
325 + {
326 + var folder = TestData.Get("TestData");
327 +
328 + using (var fs = new DisposableFileSystem())
329 + {
330 + var baseFolder = fs.GetFolder();
331 + var dataPath = Path.Combine(folder, ".Data");
332 +
333 + var msiIntermediateFolder = Path.Combine(baseFolder, "obj", "msi");
334 + var msiBinFolder = Path.Combine(baseFolder, "bin", "msi");
335 + var msiPath = Path.Combine(msiBinFolder, "test.msi");
336 +
337 + var bundleIntermediateFolder = Path.Combine(baseFolder, "obj", "bundle");
338 + var bundleBinFolder = Path.Combine(baseFolder, "bin", "bundle");
339 + var bundlePath = Path.Combine(bundleBinFolder, "bundle.exe");
340 + var bundlePdbPath = Path.Combine(bundleBinFolder, "bundle.wixpdb");
341 +
342 + var baFolderPath = Path.Combine(baseFolder, "extract", "ba");
343 + var extractFolderPath = Path.Combine(baseFolder, "extract", "files");
344 +
345 + var result = WixRunner.Execute(new[]
346 + {
347 + "build",
348 + Path.Combine(folder, "BundleAllUsers", "AllUsersPackage.wxs"),
349 + "-bindpath", dataPath,
350 + "-intermediateFolder", msiIntermediateFolder,
351 + "-o", msiPath
352 + });
353 +
354 + result.AssertSuccess();
355 +
356 + result = WixRunner.Execute(new[]
357 + {
358 + "build",
359 + Path.Combine(folder, "BundleAllUsers", "BundleWithAllUsersPackage.wxs"),
360 + "-bindpath", dataPath,
361 + "-bindpath", msiBinFolder,
362 + "-intermediateFolder", bundleIntermediateFolder,
363 + "-o", bundlePath
364 + });
365 +
366 + result.AssertSuccess();
367 +
368 + var parentBundleId = GetBundleIdFromWixpdb(bundlePdbPath);
369 +
370 + var extractResult = BundleExtractor.ExtractBAContainer(null, bundlePath, baFolderPath, extractFolderPath);
371 + extractResult.AssertSuccess();
372 +
373 + var registrations = extractResult.GetManifestTestXmlLines("/burn:BurnManifest/burn:Registration");
374 + WixAssert.CompareLineByLine(new[]
375 + {
376 + $"<Registration Id='{parentBundleId}' ExecutableName='bundle.exe' PerMachine='yes' Tag='' Version='9.9' ProviderKey='{parentBundleId}'>" +
377 + "<Arp DisplayName='All Users Bundle' DisplayVersion='9.9' Publisher='Example Corporation' />" +
378 + "</Registration>"
379 + }, registrations);
380 +
381 + var ignoreAttributesByElementName = new Dictionary<string, List<string>>
382 + {
383 + { "WixPackageProperties", new List<string> { "DownloadSize", "PackageSize" } },
384 + };
385 +
386 + var packageElements = extractResult.GetBADataTestXmlLines("/ba:BootstrapperApplicationData/ba:WixPackageProperties", ignoreAttributesByElementName);
387 + WixAssert.CompareLineByLine(new[]
388 + {
389 + "<WixPackageProperties Package='test.msi' Vital='yes' DisplayName='All Users Package' DownloadSize='*' PackageSize='*' InstalledSize='28' PackageType='Msi' Permanent='no' LogPathVariable='WixBundleLog_test.msi' RollbackLogPathVariable='WixBundleRollbackLog_test.msi' Compressed='no' ProductCode='{33333333-3333-3333-3333-333333333333}' UpgradeCode='{4BE34BEE-CA23-488E-96A0-B15878E3654B}' Version='1.0' Cache='keep' />",
390 + }, packageElements);
391 + }
392 + }
393 +
394 + private static string GetBundleIdFromWixpdb(string bundlePdbPath)
395 + {
396 + using (var wixOutput = WixOutput.Read(bundlePdbPath))
397 + {
398 +
399 + var intermediate = Intermediate.Load(wixOutput);
400 + var section = intermediate.Sections.Single();
401 +
402 + var bundleSymbol = section.Symbols.OfType<WixBundleSymbol>().Single();
403 + return bundleSymbol.BundleId;
404 + }
405 + }
406 }
407 }
src/wix/test/WixToolsetTest.CoreIntegration/TestData/BundleAllUsers/AllUsersPackage.wxs new
+14
@@ -0,0 +1,14 @@
1 +<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
2 + <Package ProductCode="33333333-3333-3333-3333-333333333333" Name="All Users Package" Version="1.0" Manufacturer="Example Corporation" UpgradeCode="4BE34BEE-CA23-488E-96A0-B15878E3654B" Compressed="no" Scope="perUserOrMachine">
3 +
4 + <StandardDirectory Id="ProgramFilesFolder">
5 + <Directory Id="INSTALLFOLDER" Name="Example" />
6 + </StandardDirectory>
7 +
8 + <Feature Id="Main">
9 + <Component Directory="INSTALLFOLDER">
10 + <File Source="test.txt" />
11 + </Component>
12 + </Feature>
13 + </Package>
14 +</Wix>
src/wix/test/WixToolsetTest.CoreIntegration/TestData/BundleAllUsers/BundleWithAllUsersPackage.wxs new
+11
@@ -0,0 +1,11 @@
1 +<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
2 + <Bundle Name="All Users Bundle" Version="9.9" Manufacturer="Example Corporation" UpgradeCode="{4BE34BEE-CA23-488E-96A0-B15878E3654B}" Compressed="no">
3 + <BootstrapperApplication>
4 + <BootstrapperApplicationDll SourceFile="fakeba.dll" />
5 + </BootstrapperApplication>
6 +
7 + <Chain>
8 + <MsiPackage SourceFile="test.msi" ForcePerMachine="yes" />
9 + </Chain>
10 + </Bundle>
11 +</Wix>