Use Burn's parent switch with BundlePackages.
Sean Hall committed
Apr 1, 2022 at 19:29 UTC
32602bb04be4a01e4b857d2071e07dd4cc2b38d4
7 files changed
+57
-12
src/burn/engine/bundlepackageengine.cpp
+24
-6
@@ -23,6 +23,7 @@ static HRESULT ExecuteBundle(
23
__in BOOTSTRAPPER_ACTION_STATE action,
24
__in BOOTSTRAPPER_RELATION_TYPE relationType,
25
__in BURN_PACKAGE* pPackage,
26
+ __in_z_opt LPCWSTR wzParent,
27
__in_z_opt LPCWSTR wzIgnoreDependencies,
28
__in_z_opt LPCWSTR wzAncestors,
29
__in_z_opt LPCWSTR wzEngineWorkingDirectory,
@@ -239,7 +240,7 @@ extern "C" void BundlePackageEnginePackageUninitialize(
240
241
extern "C" HRESULT BundlePackageEngineDetectPackage(
242
__in BURN_PACKAGE* pPackage,
242
- __in BURN_REGISTRATION* /*pRegistration*/,
243
+ __in BURN_REGISTRATION* pRegistration,
244
__in BURN_USER_EXPERIENCE* pUserExperience
245
)
246
{
@@ -291,9 +292,8 @@ extern "C" HRESULT BundlePackageEngineDetectPackage(
292
pPackage->installRegistrationState = BOOTSTRAPPER_PACKAGE_STATE_ABSENT < pPackage->currentState ? BURN_PACKAGE_REGISTRATION_STATE_PRESENT : BURN_PACKAGE_REGISTRATION_STATE_ABSENT;
293
}
294
294
- // TODO: The bundle is registering itself as a dependent when installed as a chain package, which prevents us from uninstalling it.
295
- //hr = DependencyDetectChainPackage(pPackage, pRegistration);
296
- //ExitOnFailure(hr, "Failed to detect dependencies for BUNDLE package.");
295
+ hr = DependencyDetectChainPackage(pPackage, pRegistration);
296
+ ExitOnFailure(hr, "Failed to detect dependencies for BUNDLE package.");
297
298
// TODO: uninstalling compatible Bundles like MsiEngine supports?
299
@@ -447,6 +447,9 @@ extern "C" HRESULT BundlePackageEnginePlanAddPackage(
447
pAction->bundlePackage.pPackage = pPackage;
448
pAction->bundlePackage.action = pPackage->rollback;
449
450
+ hr = StrAllocString(&pAction->bundlePackage.sczParent, pPlan->wzBundleId, 0);
451
+ ExitOnFailure(hr, "Failed to allocate the parent.");
452
+
453
if (pPackage->Bundle.wzAncestors)
454
{
455
hr = StrAllocString(&pAction->bundlePackage.sczAncestors, pPackage->Bundle.wzAncestors, 0);
@@ -475,6 +478,9 @@ extern "C" HRESULT BundlePackageEnginePlanAddPackage(
478
pAction->bundlePackage.pPackage = pPackage;
479
pAction->bundlePackage.action = pPackage->execute;
480
481
+ hr = StrAllocString(&pAction->bundlePackage.sczParent, pPlan->wzBundleId, 0);
482
+ ExitOnFailure(hr, "Failed to allocate the parent.");
483
+
484
if (pPackage->Bundle.wzAncestors)
485
{
486
hr = StrAllocString(&pAction->bundlePackage.sczAncestors, pPackage->Bundle.wzAncestors, 0);
@@ -597,13 +603,14 @@ extern "C" HRESULT BundlePackageEngineExecutePackage(
603
)
604
{
605
BOOTSTRAPPER_ACTION_STATE action = pExecuteAction->bundlePackage.action;
606
+ LPCWSTR wzParent = pExecuteAction->bundlePackage.sczParent;
607
LPCWSTR wzIgnoreDependencies = pExecuteAction->bundlePackage.sczIgnoreDependencies;
608
LPCWSTR wzAncestors = pExecuteAction->bundlePackage.sczAncestors;
609
LPCWSTR wzEngineWorkingDirectory = pExecuteAction->bundlePackage.sczEngineWorkingDirectory;
610
BOOTSTRAPPER_RELATION_TYPE relationType = BOOTSTRAPPER_RELATION_CHAIN_PACKAGE;
611
BURN_PACKAGE* pPackage = pExecuteAction->bundlePackage.pPackage;
612
606
- return ExecuteBundle(pCache, pVariables, fRollback, pfnGenericMessageHandler, pvContext, action, relationType, pPackage, wzIgnoreDependencies, wzAncestors, wzEngineWorkingDirectory, pRestart);
613
+ return ExecuteBundle(pCache, pVariables, fRollback, pfnGenericMessageHandler, pvContext, action, relationType, pPackage, wzParent, wzIgnoreDependencies, wzAncestors, wzEngineWorkingDirectory, pRestart);
614
}
615
616
extern "C" HRESULT BundlePackageEngineExecuteRelatedBundle(
@@ -617,6 +624,7 @@ extern "C" HRESULT BundlePackageEngineExecuteRelatedBundle(
624
)
625
{
626
BOOTSTRAPPER_ACTION_STATE action = pExecuteAction->relatedBundle.action;
627
+ LPCWSTR wzParent = NULL;
628
LPCWSTR wzIgnoreDependencies = pExecuteAction->relatedBundle.sczIgnoreDependencies;
629
LPCWSTR wzAncestors = pExecuteAction->relatedBundle.sczAncestors;
630
LPCWSTR wzEngineWorkingDirectory = pExecuteAction->relatedBundle.sczEngineWorkingDirectory;
@@ -624,7 +632,7 @@ extern "C" HRESULT BundlePackageEngineExecuteRelatedBundle(
632
BOOTSTRAPPER_RELATION_TYPE relationType = ConvertRelationType(pRelatedBundle->planRelationType);
633
BURN_PACKAGE* pPackage = &pRelatedBundle->package;
634
627
- return ExecuteBundle(pCache, pVariables, fRollback, pfnGenericMessageHandler, pvContext, action, relationType, pPackage, wzIgnoreDependencies, wzAncestors, wzEngineWorkingDirectory, pRestart);
635
+ return ExecuteBundle(pCache, pVariables, fRollback, pfnGenericMessageHandler, pvContext, action, relationType, pPackage, wzParent, wzIgnoreDependencies, wzAncestors, wzEngineWorkingDirectory, pRestart);
636
}
637
638
extern "C" void BundlePackageEngineUpdateInstallRegistrationState(
@@ -721,6 +729,7 @@ static HRESULT ExecuteBundle(
729
__in BOOTSTRAPPER_ACTION_STATE action,
730
__in BOOTSTRAPPER_RELATION_TYPE relationType,
731
__in BURN_PACKAGE* pPackage,
732
+ __in_z_opt LPCWSTR wzParent,
733
__in_z_opt LPCWSTR wzIgnoreDependencies,
734
__in_z_opt LPCWSTR wzAncestors,
735
__in_z_opt LPCWSTR wzEngineWorkingDirectory,
@@ -848,6 +857,15 @@ static HRESULT ExecuteBundle(
857
ExitOnFailure(hr, "Failed to append relation type argument.");
858
}
859
860
+ if (wzParent)
861
+ {
862
+ hr = StrAllocConcatFormatted(&sczBaseCommand, L" -%ls", BURN_COMMANDLINE_SWITCH_PARENT);
863
+ ExitOnFailure(hr, "Failed to append the parent switch to the command line.");
864
+
865
+ hr = AppAppendCommandLineArgument(&sczBaseCommand, wzParent);
866
+ ExitOnFailure(hr, "Failed to append the parent to the command line.");
867
+ }
868
+
869
// Add the list of dependencies to ignore, if any, to the burn command line.
870
if (BOOTSTRAPPER_RELATION_CHAIN_PACKAGE == relationType)
871
{
src/burn/engine/elevation.cpp
+7
-1
@@ -949,6 +949,9 @@ extern "C" HRESULT ElevationExecuteBundlePackage(
949
hr = BuffWriteNumber(&pbData, &cbData, fRollback);
950
ExitOnFailure(hr, "Failed to write rollback.");
951
952
+ hr = BuffWriteString(&pbData, &cbData, pExecuteAction->bundlePackage.sczParent);
953
+ ExitOnFailure(hr, "Failed to write the parent to the message buffer.");
954
+
955
hr = BuffWriteString(&pbData, &cbData, pExecuteAction->bundlePackage.sczIgnoreDependencies);
956
ExitOnFailure(hr, "Failed to write the list of dependencies to ignore to the message buffer.");
957
@@ -2929,7 +2932,7 @@ static HRESULT OnExecuteBundlePackage(
2932
2933
// Deserialize message data.
2934
hr = BuffReadString(pbData, cbData, &iData, &sczPackage);
2932
- ExitOnFailure(hr, "Failed to read EXE package id.");
2935
+ ExitOnFailure(hr, "Failed to read BUNDLE package id.");
2936
2937
hr = BuffReadNumber(pbData, cbData, &iData, (DWORD*)&executeAction.bundlePackage.action);
2938
ExitOnFailure(hr, "Failed to read action.");
@@ -2937,6 +2940,9 @@ static HRESULT OnExecuteBundlePackage(
2940
hr = BuffReadNumber(pbData, cbData, &iData, &dwRollback);
2941
ExitOnFailure(hr, "Failed to read rollback.");
2942
2943
+ hr = BuffReadString(pbData, cbData, &iData, &executeAction.bundlePackage.sczParent);
2944
+ ExitOnFailure(hr, "Failed to read the parent.");
2945
+
2946
hr = BuffReadString(pbData, cbData, &iData, &sczIgnoreDependencies);
2947
ExitOnFailure(hr, "Failed to read the list of dependencies to ignore.");
2948
src/burn/engine/plan.cpp
+7
@@ -291,6 +291,13 @@ extern "C" void PlanUninitializeExecuteAction(
291
ReleaseStr(pExecuteAction->relatedBundle.sczEngineWorkingDirectory);
292
break;
293
294
+ case BURN_EXECUTE_ACTION_TYPE_BUNDLE_PACKAGE:
295
+ ReleaseStr(pExecuteAction->bundlePackage.sczParent);
296
+ ReleaseStr(pExecuteAction->bundlePackage.sczIgnoreDependencies);
297
+ ReleaseStr(pExecuteAction->bundlePackage.sczAncestors);
298
+ ReleaseStr(pExecuteAction->bundlePackage.sczEngineWorkingDirectory);
299
+ break;
300
+
301
case BURN_EXECUTE_ACTION_TYPE_EXE_PACKAGE:
302
ReleaseStr(pExecuteAction->exePackage.sczAncestors);
303
ReleaseStr(pExecuteAction->exePackage.sczEngineWorkingDirectory);
src/burn/engine/plan.h
+1
@@ -165,6 +165,7 @@ typedef struct _BURN_EXECUTE_ACTION
165
{
166
BURN_PACKAGE* pPackage;
167
BOOTSTRAPPER_ACTION_STATE action;
168
+ LPWSTR sczParent;
169
LPWSTR sczIgnoreDependencies;
170
LPWSTR sczAncestors;
171
LPWSTR sczEngineWorkingDirectory;
src/burn/test/BurnUnitTest/PlanTest.cpp
+7
-5
@@ -399,7 +399,7 @@ namespace Bootstrapper
399
ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
400
ValidateExecuteWaitCachePackage(pPlan, fRollback, dwIndex++, L"PackageA");
401
ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
402
- ValidateExecuteBundlePackage(pPlan, fRollback, dwIndex++, L"PackageA", BOOTSTRAPPER_ACTION_STATE_INSTALL);
402
+ ValidateExecuteBundlePackage(pPlan, fRollback, dwIndex++, L"PackageA", BOOTSTRAPPER_ACTION_STATE_INSTALL, L"{35192ED0-C70A-49B2-9D12-3B1FA39B5E6F}");
403
ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
404
ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageA", L"{35192ED0-C70A-49B2-9D12-3B1FA39B5E6F}", registerActions1, 1);
405
ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
@@ -407,7 +407,7 @@ namespace Bootstrapper
407
ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
408
ValidateExecuteWaitCachePackage(pPlan, fRollback, dwIndex++, L"PackageB");
409
ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
410
- ValidateExecuteBundlePackage(pPlan, fRollback, dwIndex++, L"PackageB", BOOTSTRAPPER_ACTION_STATE_INSTALL);
410
+ ValidateExecuteBundlePackage(pPlan, fRollback, dwIndex++, L"PackageB", BOOTSTRAPPER_ACTION_STATE_INSTALL, L"{35192ED0-C70A-49B2-9D12-3B1FA39B5E6F}");
411
ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
412
ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageB", L"{35192ED0-C70A-49B2-9D12-3B1FA39B5E6F}", registerActions1, 1);
413
ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
@@ -420,14 +420,14 @@ namespace Bootstrapper
420
dwExecuteCheckpointId = 2;
421
ValidateExecuteRollbackBoundaryStart(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE);
422
ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
423
- ValidateExecuteBundlePackage(pPlan, fRollback, dwIndex++, L"PackageA", BOOTSTRAPPER_ACTION_STATE_UNINSTALL);
423
+ ValidateExecuteBundlePackage(pPlan, fRollback, dwIndex++, L"PackageA", BOOTSTRAPPER_ACTION_STATE_UNINSTALL, L"{35192ED0-C70A-49B2-9D12-3B1FA39B5E6F}");
424
ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
425
ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageA", L"{35192ED0-C70A-49B2-9D12-3B1FA39B5E6F}", unregisterActions1, 1);
426
ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
427
ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
428
dwExecuteCheckpointId += 1; // cache checkpoints
429
ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
430
- ValidateExecuteBundlePackage(pPlan, fRollback, dwIndex++, L"PackageB", BOOTSTRAPPER_ACTION_STATE_UNINSTALL);
430
+ ValidateExecuteBundlePackage(pPlan, fRollback, dwIndex++, L"PackageB", BOOTSTRAPPER_ACTION_STATE_UNINSTALL, L"{35192ED0-C70A-49B2-9D12-3B1FA39B5E6F}");
431
ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
432
ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageB", L"{35192ED0-C70A-49B2-9D12-3B1FA39B5E6F}", unregisterActions1, 1);
433
ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
@@ -2799,13 +2799,15 @@ namespace Bootstrapper
2799
__in BOOL fRollback,
2800
__in DWORD dwIndex,
2801
__in LPCWSTR wzPackageId,
2802
- __in BOOTSTRAPPER_ACTION_STATE action
2802
+ __in BOOTSTRAPPER_ACTION_STATE action,
2803
+ __in LPCWSTR wzParent
2804
)
2805
{
2806
BURN_EXECUTE_ACTION* pAction = ValidateExecuteActionExists(pPlan, fRollback, dwIndex);
2807
Assert::Equal<DWORD>(BURN_EXECUTE_ACTION_TYPE_BUNDLE_PACKAGE, pAction->type);
2808
NativeAssert::StringEqual(wzPackageId, pAction->bundlePackage.pPackage->sczId);
2809
Assert::Equal<DWORD>(action, pAction->bundlePackage.action);
2810
+ NativeAssert::StringEqual(wzParent, pAction->bundlePackage.sczParent);
2811
Assert::Equal<BOOL>(FALSE, pAction->fDeleted);
2812
}
2813
src/test/burn/WixToolsetTest.BurnE2E/BundlePackageTests.cs
+6
@@ -2,6 +2,7 @@
2
3
namespace WixToolsetTest.BurnE2E
4
{
5
+ using System;
6
using System.IO;
7
using WixTestTools;
8
using Xunit;
@@ -67,8 +68,13 @@ namespace WixToolsetTest.BurnE2E
68
[Fact]
69
public void CanInstallV3BundlePackage()
70
{
71
+ var v3BundleName = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), "Package Cache", "{215a70db-ab35-48c7-be51-d66eaac87177}", "CustomV3Theme");
72
+ var v3Bundle = new BundleInstaller(this.TestContext, v3BundleName);
73
+ this.AddBundleInstaller(v3Bundle);
74
var v3BundlePackageBundle = this.CreateBundleInstaller("V3BundlePackageBundle");
75
76
+ Assert.False(File.Exists(v3Bundle.Bundle), "v3bundle.exe was already installed");
77
+
78
var logPath = v3BundlePackageBundle.Install();
79
v3BundlePackageBundle.VerifyRegisteredAndInPackageCache();
80
src/test/burn/WixToolsetTest.BurnE2E/BurnE2ETests.cs
+5
@@ -22,6 +22,11 @@ namespace WixToolsetTest.BurnE2E
22
false;
23
#endif
24
25
+ protected void AddBundleInstaller(BundleInstaller installer)
26
+ {
27
+ this.Installers.Push(installer);
28
+ }
29
+
30
protected BundleInstaller CreateBundleInstaller(string name)
31
{
32
var installer = new BundleInstaller(this.TestContext, name);