@joebigelow / wix / commits / 72e20f68

Add RepairCondition.

Fixes 6758

Sean Hall committed Apr 22, 2022 at 16:55 UTC 72e20f682c0d64102e86439ba5527dd0d71932ae
33 files changed +237 -17
src/api/burn/WixToolset.BootstrapperCore.Native/inc/BootstrapperApplication.h
+1
@@ -1243,6 +1243,7 @@ struct BA_ONPLANPACKAGEBEGIN_ARGS
1243 BOOTSTRAPPER_PACKAGE_CONDITION_RESULT installCondition;
1244 BOOTSTRAPPER_REQUEST_STATE recommendedState;
1245 BOOTSTRAPPER_CACHE_TYPE recommendedCacheType;
1246 + BOOTSTRAPPER_PACKAGE_CONDITION_RESULT repairCondition;
1247 };
1248
1249 struct BA_ONPLANPACKAGEBEGIN_RESULTS
src/api/burn/WixToolset.Mba.Core/BootstrapperApplication.cs
+2 -2
@@ -1598,9 +1598,9 @@ namespace WixToolset.Mba.Core
1598 return args.HResult;
1599 }
1600
1601 - int IBootstrapperApplication.OnPlanPackageBegin(string wzPackageId, PackageState state, bool fCached, BOOTSTRAPPER_PACKAGE_CONDITION_RESULT installCondition, RequestState recommendedState, BOOTSTRAPPER_CACHE_TYPE recommendedCacheType, ref RequestState pRequestedState, ref BOOTSTRAPPER_CACHE_TYPE pRequestedCacheType, ref bool fCancel)
1601 + int IBootstrapperApplication.OnPlanPackageBegin(string wzPackageId, PackageState state, bool fCached, BOOTSTRAPPER_PACKAGE_CONDITION_RESULT installCondition, BOOTSTRAPPER_PACKAGE_CONDITION_RESULT repairCondition, RequestState recommendedState, BOOTSTRAPPER_CACHE_TYPE recommendedCacheType, ref RequestState pRequestedState, ref BOOTSTRAPPER_CACHE_TYPE pRequestedCacheType, ref bool fCancel)
1602 {
1603 - PlanPackageBeginEventArgs args = new PlanPackageBeginEventArgs(wzPackageId, state, fCached, installCondition, recommendedState, recommendedCacheType, pRequestedState, pRequestedCacheType, fCancel);
1603 + PlanPackageBeginEventArgs args = new PlanPackageBeginEventArgs(wzPackageId, state, fCached, installCondition, repairCondition, recommendedState, recommendedCacheType, pRequestedState, pRequestedCacheType, fCancel);
1604 this.OnPlanPackageBegin(args);
1605
1606 pRequestedState = args.State;
src/api/burn/WixToolset.Mba.Core/EventArgs.cs
+7 -1
@@ -783,13 +783,14 @@ namespace WixToolset.Mba.Core
783 public class PlanPackageBeginEventArgs : CancellableHResultEventArgs
784 {
785 /// <summary />
786 - public PlanPackageBeginEventArgs(string packageId, PackageState currentState, bool cached, BOOTSTRAPPER_PACKAGE_CONDITION_RESULT installCondition, RequestState recommendedState, BOOTSTRAPPER_CACHE_TYPE recommendedCacheType, RequestState state, BOOTSTRAPPER_CACHE_TYPE cacheType, bool cancelRecommendation)
786 + public PlanPackageBeginEventArgs(string packageId, PackageState currentState, bool cached, BOOTSTRAPPER_PACKAGE_CONDITION_RESULT installCondition, BOOTSTRAPPER_PACKAGE_CONDITION_RESULT repairCondition, RequestState recommendedState, BOOTSTRAPPER_CACHE_TYPE recommendedCacheType, RequestState state, BOOTSTRAPPER_CACHE_TYPE cacheType, bool cancelRecommendation)
787 : base(cancelRecommendation)
788 {
789 this.PackageId = packageId;
790 this.CurrentState = currentState;
791 this.Cached = cached;
792 this.InstallCondition = installCondition;
793 + this.RepairCondition = repairCondition;
794 this.RecommendedState = recommendedState;
795 this.RecommendedCacheType = recommendedCacheType;
796 this.State = state;
@@ -816,6 +817,11 @@ namespace WixToolset.Mba.Core
817 /// </summary>
818 public BOOTSTRAPPER_PACKAGE_CONDITION_RESULT InstallCondition { get; private set; }
819
820 + /// <summary>
821 + /// Gets the evaluated result of the package's repair condition.
822 + /// </summary>
823 + public BOOTSTRAPPER_PACKAGE_CONDITION_RESULT RepairCondition { get; private set; }
824 +
825 /// <summary>
826 /// Gets the recommended requested state for the package.
827 /// </summary>
src/api/burn/WixToolset.Mba.Core/IBootstrapperApplication.cs
+1
@@ -314,6 +314,7 @@ namespace WixToolset.Mba.Core
314 [MarshalAs(UnmanagedType.U4)] PackageState state,
315 [MarshalAs(UnmanagedType.Bool)] bool fCached,
316 [MarshalAs(UnmanagedType.U4)] BOOTSTRAPPER_PACKAGE_CONDITION_RESULT installCondition,
317 + [MarshalAs(UnmanagedType.U4)] BOOTSTRAPPER_PACKAGE_CONDITION_RESULT repairCondition,
318 [MarshalAs(UnmanagedType.U4)] RequestState recommendedState,
319 [MarshalAs(UnmanagedType.U4)] BOOTSTRAPPER_CACHE_TYPE recommendedCacheType,
320 [MarshalAs(UnmanagedType.U4)] ref RequestState pRequestedState,
src/api/burn/WixToolset.Mba.Core/IPackageInfo.cs
+6 -1
@@ -42,6 +42,11 @@ namespace WixToolset.Mba.Core
42 /// </summary>
43 string InstallCondition { get; }
44
45 + /// <summary>
46 + ///
47 + /// </summary>
48 + string RepairCondition { get; }
49 +
50 /// <summary>
51 ///
52 /// </summary>
@@ -87,4 +92,4 @@ namespace WixToolset.Mba.Core
92 /// </summary>
93 bool Vital { get; }
94 }
90 -}
\ No newline at end of file
95 +}
src/api/burn/WixToolset.Mba.Core/PackageInfo.cs
+5
@@ -101,6 +101,9 @@ namespace WixToolset.Mba.Core
101 /// <inheritdoc/>
102 public string InstallCondition { get; internal set; }
103
104 + /// <inheritdoc/>
105 + public string RepairCondition { get; internal set; }
106 +
107 /// <inheritdoc/>
108 public BOOTSTRAPPER_CACHE_TYPE CacheType { get; internal set; }
109
@@ -174,6 +177,8 @@ namespace WixToolset.Mba.Core
177
178 package.InstallCondition = BootstrapperApplicationData.GetAttribute(node, "InstallCondition");
179
180 + package.RepairCondition = BootstrapperApplicationData.GetAttribute(node, "RepairCondition");
181 +
182 packagesById.Add(package.Id, package);
183 }
184
src/api/burn/balutil/balinfo.cpp
+7
@@ -304,6 +304,7 @@ DAPI_(void) BalInfoUninitialize(
304 ReleaseStr(pBundle->packages.rgPackages[i].sczUpgradeCode);
305 ReleaseStr(pBundle->packages.rgPackages[i].sczVersion);
306 ReleaseStr(pBundle->packages.rgPackages[i].sczInstallCondition);
307 + ReleaseStr(pBundle->packages.rgPackages[i].sczRepairCondition);
308 ReleaseStr(pBundle->packages.rgPackages[i].sczPrereqLicenseFile);
309 ReleaseStr(pBundle->packages.rgPackages[i].sczPrereqLicenseUrl);
310 }
@@ -484,6 +485,12 @@ static HRESULT ParsePackagesFromXml(
485 ExitOnFailure(hr, "Failed to get install condition for package.");
486 }
487
488 + hr = XmlGetAttributeEx(pNode, L"RepairCondition", &prgPackages[iPackage].sczRepairCondition);
489 + if (E_NOTFOUND != hr)
490 + {
491 + ExitOnFailure(hr, "Failed to get repair condition for package.");
492 + }
493 +
494 hr = XmlGetAttributeEx(pNode, L"Cache", &scz);
495 ExitOnFailure(hr, "Failed to get cache type for package.");
496
src/api/burn/balutil/inc/BalBaseBAFunctions.h
+1
@@ -276,6 +276,7 @@ public: // IBootstrapperApplication
276 __in BOOTSTRAPPER_PACKAGE_STATE /*state*/,
277 __in BOOL /*fCached*/,
278 __in BOOTSTRAPPER_PACKAGE_CONDITION_RESULT /*installCondition*/,
279 + __in BOOTSTRAPPER_PACKAGE_CONDITION_RESULT /*repairCondition*/,
280 __in BOOTSTRAPPER_REQUEST_STATE /*recommendedState*/,
281 __in BOOTSTRAPPER_CACHE_TYPE /*recommendedCacheType*/,
282 __inout BOOTSTRAPPER_REQUEST_STATE* /*pRequestState*/,
src/api/burn/balutil/inc/BalBaseBootstrapperApplication.h
+1
@@ -290,6 +290,7 @@ public: // IBootstrapperApplication
290 __in BOOTSTRAPPER_PACKAGE_STATE /*state*/,
291 __in BOOL /*fCached*/,
292 __in BOOTSTRAPPER_PACKAGE_CONDITION_RESULT /*installCondition*/,
293 + __in BOOTSTRAPPER_PACKAGE_CONDITION_RESULT /*repairCondition*/,
294 __in BOOTSTRAPPER_REQUEST_STATE /*recommendedState*/,
295 __in BOOTSTRAPPER_CACHE_TYPE /*recommendedCacheType*/,
296 __inout BOOTSTRAPPER_REQUEST_STATE* /*pRequestState*/,
src/api/burn/balutil/inc/BalBaseBootstrapperApplicationProc.h
+1 -1
@@ -195,7 +195,7 @@ static HRESULT BalBaseBAProcOnPlanPackageBegin(
195 __inout BA_ONPLANPACKAGEBEGIN_RESULTS* pResults
196 )
197 {
198 - return pBA->OnPlanPackageBegin(pArgs->wzPackageId, pArgs->state, pArgs->fCached, pArgs->installCondition, pArgs->recommendedState, pArgs->recommendedCacheType, &pResults->requestedState, &pResults->requestedCacheType, &pResults->fCancel);
198 + return pBA->OnPlanPackageBegin(pArgs->wzPackageId, pArgs->state, pArgs->fCached, pArgs->installCondition, pArgs->repairCondition, pArgs->recommendedState, pArgs->recommendedCacheType, &pResults->requestedState, &pResults->requestedCacheType, &pResults->fCancel);
199 }
200
201 static HRESULT BalBaseBAProcOnPlanCompatibleMsiPackageBegin(
src/api/burn/balutil/inc/IBootstrapperApplication.h
+1
@@ -182,6 +182,7 @@ DECLARE_INTERFACE_IID_(IBootstrapperApplication, IUnknown, "53C31D56-49C0-426B-A
182 __in BOOTSTRAPPER_PACKAGE_STATE state,
183 __in BOOL fCached,
184 __in BOOTSTRAPPER_PACKAGE_CONDITION_RESULT installCondition,
185 + __in BOOTSTRAPPER_PACKAGE_CONDITION_RESULT repairCondition,
186 __in BOOTSTRAPPER_REQUEST_STATE recommendedState,
187 __in BOOTSTRAPPER_CACHE_TYPE recommendedCacheType,
188 __inout BOOTSTRAPPER_REQUEST_STATE* pRequestedState,
src/api/burn/balutil/inc/balinfo.h
+1
@@ -49,6 +49,7 @@ typedef struct _BAL_INFO_PACKAGE
49 LPWSTR sczUpgradeCode;
50 LPWSTR sczVersion;
51 LPWSTR sczInstallCondition;
52 + LPWSTR sczRepairCondition;
53 BOOTSTRAPPER_CACHE_TYPE cacheType;
54 BOOL fPrereqPackage;
55 LPWSTR sczPrereqLicenseFile;
src/api/wix/WixToolset.Data/Symbols/WixBundlePackageSymbol.cs
+8
@@ -14,6 +14,7 @@ namespace WixToolset.Data
14 new IntermediateFieldDefinition(nameof(WixBundlePackageSymbolFields.PayloadRef), IntermediateFieldType.String),
15 new IntermediateFieldDefinition(nameof(WixBundlePackageSymbolFields.Attributes), IntermediateFieldType.Number),
16 new IntermediateFieldDefinition(nameof(WixBundlePackageSymbolFields.InstallCondition), IntermediateFieldType.String),
17 + new IntermediateFieldDefinition(nameof(WixBundlePackageSymbolFields.RepairCondition), IntermediateFieldType.String),
18 new IntermediateFieldDefinition(nameof(WixBundlePackageSymbolFields.Cache), IntermediateFieldType.String),
19 new IntermediateFieldDefinition(nameof(WixBundlePackageSymbolFields.CacheId), IntermediateFieldType.String),
20 new IntermediateFieldDefinition(nameof(WixBundlePackageSymbolFields.PerMachine), IntermediateFieldType.Bool),
@@ -42,6 +43,7 @@ namespace WixToolset.Data.Symbols
43 PayloadRef,
44 Attributes,
45 InstallCondition,
46 + RepairCondition,
47 Cache,
48 CacheId,
49 PerMachine,
@@ -124,6 +126,12 @@ namespace WixToolset.Data.Symbols
126 set => this.Set((int)WixBundlePackageSymbolFields.InstallCondition, value);
127 }
128
129 + public string RepairCondition
130 + {
131 + get => (string)this.Fields[(int)WixBundlePackageSymbolFields.RepairCondition];
132 + set => this.Set((int)WixBundlePackageSymbolFields.RepairCondition, value);
133 + }
134 +
135 public BundleCacheType? Cache
136 {
137 get => Enum.TryParse((string)this.Fields[(int)WixBundlePackageSymbolFields.Cache], true, out BundleCacheType value) ? value : (BundleCacheType?)null;
src/burn/engine/package.cpp
+5
@@ -178,6 +178,10 @@ extern "C" HRESULT PackagesParseFromXml(
178 hr = XmlGetAttributeEx(pixnNode, L"InstallCondition", &pPackage->sczInstallCondition);
179 ExitOnOptionalXmlQueryFailure(hr, fFoundXml, "Failed to get @InstallCondition.");
180
181 + // @RepairCondition
182 + hr = XmlGetAttributeEx(pixnNode, L"RepairCondition", &pPackage->sczRepairCondition);
183 + ExitOnOptionalXmlQueryFailure(hr, fFoundXml, "Failed to get @RepairCondition.");
184 +
185 // @RollbackBoundaryForward
186 hr = XmlGetAttributeEx(pixnNode, L"RollbackBoundaryForward", &scz);
187 ExitOnOptionalXmlQueryFailure(hr, fFoundXml, "Failed to get @RollbackBoundaryForward.");
@@ -362,6 +366,7 @@ extern "C" void PackageUninitialize(
366 ReleaseStr(pPackage->sczLogPathVariable);
367 ReleaseStr(pPackage->sczRollbackLogPathVariable);
368 ReleaseStr(pPackage->sczInstallCondition);
369 + ReleaseStr(pPackage->sczRepairCondition);
370 ReleaseStr(pPackage->sczCacheId);
371
372 if (pPackage->rgDependencyProviders)
src/burn/engine/package.h
+1
@@ -250,6 +250,7 @@ typedef struct _BURN_PACKAGE
250 LPWSTR sczRollbackLogPathVariable; // name of the variable that will be set to the rollback path.
251
252 LPWSTR sczInstallCondition;
253 + LPWSTR sczRepairCondition;
254 BOOL fPerMachine;
255 BOOL fPermanent;
256 BOOL fVital;
src/burn/engine/plan.cpp
+19 -5
@@ -347,6 +347,7 @@ extern "C" HRESULT PlanDefaultPackageRequestState(
347 __in BOOTSTRAPPER_PACKAGE_STATE currentState,
348 __in BOOTSTRAPPER_ACTION action,
349 __in BOOTSTRAPPER_PACKAGE_CONDITION_RESULT installCondition,
350 + __in BOOTSTRAPPER_PACKAGE_CONDITION_RESULT repairCondition,
351 __in BOOTSTRAPPER_RELATION_TYPE relationType,
352 __out BOOTSTRAPPER_REQUEST_STATE* pRequestState
353 )
@@ -408,6 +409,10 @@ extern "C" HRESULT PlanDefaultPackageRequestState(
409 {
410 defaultRequestState = BOOTSTRAPPER_REQUEST_STATE_PRESENT <= defaultRequestState ? BOOTSTRAPPER_REQUEST_STATE_NONE : defaultRequestState;
411 }
412 + else if (BOOTSTRAPPER_ACTION_REPAIR == action && BOOTSTRAPPER_PACKAGE_CONDITION_FALSE == repairCondition)
413 + {
414 + defaultRequestState = BOOTSTRAPPER_REQUEST_STATE_PRESENT;
415 + }
416 }
417
418 *pRequestState = defaultRequestState;
@@ -905,7 +910,8 @@ static HRESULT InitializePackage(
910 {
911 HRESULT hr = S_OK;
912 BOOTSTRAPPER_PACKAGE_CONDITION_RESULT installCondition = BOOTSTRAPPER_PACKAGE_CONDITION_DEFAULT;
908 - BOOL fInstallCondition = FALSE;
913 + BOOTSTRAPPER_PACKAGE_CONDITION_RESULT repairCondition = BOOTSTRAPPER_PACKAGE_CONDITION_DEFAULT;
914 + BOOL fEvaluatedCondition = FALSE;
915 BOOL fBeginCalled = FALSE;
916 BOOTSTRAPPER_RELATION_TYPE relationType = pPlan->pCommand->relationType;
917
@@ -927,20 +933,28 @@ static HRESULT InitializePackage(
933
934 if (pPackage->sczInstallCondition && *pPackage->sczInstallCondition)
935 {
930 - hr = ConditionEvaluate(pVariables, pPackage->sczInstallCondition, &fInstallCondition);
936 + hr = ConditionEvaluate(pVariables, pPackage->sczInstallCondition, &fEvaluatedCondition);
937 ExitOnFailure(hr, "Failed to evaluate install condition.");
938
933 - installCondition = fInstallCondition ? BOOTSTRAPPER_PACKAGE_CONDITION_TRUE : BOOTSTRAPPER_PACKAGE_CONDITION_FALSE;
939 + installCondition = fEvaluatedCondition ? BOOTSTRAPPER_PACKAGE_CONDITION_TRUE : BOOTSTRAPPER_PACKAGE_CONDITION_FALSE;
940 + }
941 +
942 + if (pPackage->sczRepairCondition && *pPackage->sczRepairCondition)
943 + {
944 + hr = ConditionEvaluate(pVariables, pPackage->sczRepairCondition, &fEvaluatedCondition);
945 + ExitOnFailure(hr, "Failed to evaluate repair condition.");
946 +
947 + repairCondition = fEvaluatedCondition ? BOOTSTRAPPER_PACKAGE_CONDITION_TRUE : BOOTSTRAPPER_PACKAGE_CONDITION_FALSE;
948 }
949
950 // Remember the default requested state so the engine doesn't get blamed for planning the wrong thing if the BA changes it.
937 - hr = PlanDefaultPackageRequestState(pPackage->type, pPackage->currentState, pPlan->action, installCondition, relationType, &pPackage->defaultRequested);
951 + hr = PlanDefaultPackageRequestState(pPackage->type, pPackage->currentState, pPlan->action, installCondition, repairCondition, relationType, &pPackage->defaultRequested);
952 ExitOnFailure(hr, "Failed to set default package state.");
953
954 pPackage->requested = pPackage->defaultRequested;
955 fBeginCalled = TRUE;
956
943 - hr = UserExperienceOnPlanPackageBegin(pUX, pPackage->sczId, pPackage->currentState, pPackage->fCached, installCondition, &pPackage->requested, &pPackage->cacheType);
957 + hr = UserExperienceOnPlanPackageBegin(pUX, pPackage->sczId, pPackage->currentState, pPackage->fCached, installCondition, repairCondition, &pPackage->requested, &pPackage->cacheType);
958 ExitOnRootFailure(hr, "BA aborted plan package begin.");
959
960 if (BURN_PACKAGE_TYPE_MSI == pPackage->type)
src/burn/engine/plan.h
+1
@@ -342,6 +342,7 @@ HRESULT PlanDefaultPackageRequestState(
342 __in BOOTSTRAPPER_PACKAGE_STATE currentState,
343 __in BOOTSTRAPPER_ACTION action,
344 __in BOOTSTRAPPER_PACKAGE_CONDITION_RESULT installCondition,
345 + __in BOOTSTRAPPER_PACKAGE_CONDITION_RESULT repairCondition,
346 __in BOOTSTRAPPER_RELATION_TYPE relationType,
347 __out BOOTSTRAPPER_REQUEST_STATE* pRequestState
348 );
src/burn/engine/userexperience.cpp
+2
@@ -2169,6 +2169,7 @@ EXTERN_C BAAPI UserExperienceOnPlanPackageBegin(
2169 __in BOOTSTRAPPER_PACKAGE_STATE state,
2170 __in BOOL fCached,
2171 __in BOOTSTRAPPER_PACKAGE_CONDITION_RESULT installCondition,
2172 + __in BOOTSTRAPPER_PACKAGE_CONDITION_RESULT repairCondition,
2173 __inout BOOTSTRAPPER_REQUEST_STATE* pRequestedState,
2174 __inout BOOTSTRAPPER_CACHE_TYPE* pRequestedCacheType
2175 )
@@ -2182,6 +2183,7 @@ EXTERN_C BAAPI UserExperienceOnPlanPackageBegin(
2183 args.state = state;
2184 args.fCached = fCached;
2185 args.installCondition = installCondition;
2186 + args.repairCondition = repairCondition;
2187 args.recommendedState = *pRequestedState;
2188 args.recommendedCacheType = *pRequestedCacheType;
2189
src/burn/engine/userexperience.h
+1
@@ -501,6 +501,7 @@ BAAPI UserExperienceOnPlanPackageBegin(
501 __in BOOTSTRAPPER_PACKAGE_STATE state,
502 __in BOOL fCached,
503 __in BOOTSTRAPPER_PACKAGE_CONDITION_RESULT installCondition,
504 + __in BOOTSTRAPPER_PACKAGE_CONDITION_RESULT repairCondition,
505 __inout BOOTSTRAPPER_REQUEST_STATE* pRequestedState,
506 __inout BOOTSTRAPPER_CACHE_TYPE* pRequestedCacheType
507 );
src/burn/test/BurnUnitTest/PlanTest.cpp
+95
@@ -458,6 +458,101 @@ namespace Bootstrapper
458 ValidateNonPermanentPackageExpectedStates(&pEngineState->packages.rgPackages[2], L"PackageB", BURN_PACKAGE_REGISTRATION_STATE_PRESENT, BURN_PACKAGE_REGISTRATION_STATE_PRESENT);
459 }
460
461 + [Fact]
462 + void MultipleBundlePackageRepairTest()
463 + {
464 + HRESULT hr = S_OK;
465 + BURN_ENGINE_STATE engineState = { };
466 + BURN_ENGINE_STATE* pEngineState = &engineState;
467 + BURN_PLAN* pPlan = &engineState.plan;
468 +
469 + InitializeEngineStateForCorePlan(wzMultipleBundlePackageManifestFileName, pEngineState);
470 + DetectAttachedContainerAsAttached(pEngineState);
471 + DetectPackagesAsPresentAndCached(pEngineState);
472 +
473 + hr = CorePlan(pEngineState, BOOTSTRAPPER_ACTION_REPAIR);
474 + NativeAssert::Succeeded(hr, "CorePlan failed");
475 +
476 + Assert::Equal<DWORD>(BOOTSTRAPPER_ACTION_REPAIR, pPlan->action);
477 + NativeAssert::StringEqual(L"{35192ED0-C70A-49B2-9D12-3B1FA39B5E6F}", pPlan->wzBundleId);
478 + NativeAssert::StringEqual(L"{35192ED0-C70A-49B2-9D12-3B1FA39B5E6F}", pPlan->wzBundleProviderKey);
479 + Assert::Equal<BOOL>(FALSE, pPlan->fEnabledForwardCompatibleBundle);
480 + Assert::Equal<BOOL>(TRUE, pPlan->fPerMachine);
481 + Assert::Equal<BOOL>(TRUE, pPlan->fCanAffectMachineState);
482 + Assert::Equal<BOOL>(FALSE, pPlan->fDisableRollback);
483 + Assert::Equal<BOOL>(FALSE, pPlan->fDisallowRemoval);
484 + Assert::Equal<BOOL>(FALSE, pPlan->fDowngrade);
485 + Assert::Equal<DWORD>(BURN_REGISTRATION_ACTION_OPERATIONS_CACHE_BUNDLE | BURN_REGISTRATION_ACTION_OPERATIONS_WRITE_PROVIDER_KEY, pPlan->dwRegistrationOperations);
486 +
487 + BOOL fRollback = FALSE;
488 + DWORD dwIndex = 0;
489 + Assert::Equal(dwIndex, pPlan->cRegistrationActions);
490 +
491 + fRollback = TRUE;
492 + dwIndex = 0;
493 + Assert::Equal(dwIndex, pPlan->cRollbackRegistrationActions);
494 +
495 + fRollback = FALSE;
496 + dwIndex = 0;
497 + ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 2);
498 + ValidateCachePackage(pPlan, fRollback, dwIndex++, L"PackageB");
499 + ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++);
500 + Assert::Equal(dwIndex, pPlan->cCacheActions);
501 +
502 + fRollback = TRUE;
503 + dwIndex = 0;
504 + Assert::Equal(dwIndex, pPlan->cRollbackCacheActions);
505 +
506 + Assert::Equal(18575450ull, pPlan->qwEstimatedSize);
507 + Assert::Equal(52254105ull, pPlan->qwCacheSizeTotal);
508 +
509 + fRollback = FALSE;
510 + dwIndex = 0;
511 + DWORD dwExecuteCheckpointId = 1;
512 + ValidateExecuteRollbackBoundaryStart(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE);
513 + ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageA", L"{35192ED0-C70A-49B2-9D12-3B1FA39B5E6F}", registerActions1, 1);
514 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
515 + dwExecuteCheckpointId += 1; // cache checkpoints
516 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
517 + ValidateExecuteWaitCachePackage(pPlan, fRollback, dwIndex++, L"PackageB");
518 + ValidateExecuteBundlePackage(pPlan, fRollback, dwIndex++, L"PackageB", BOOTSTRAPPER_ACTION_STATE_REPAIR, L"{35192ED0-C70A-49B2-9D12-3B1FA39B5E6F}");
519 + ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageB", L"{35192ED0-C70A-49B2-9D12-3B1FA39B5E6F}", registerActions1, 1);
520 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
521 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
522 + ValidateExecuteRollbackBoundaryEnd(pPlan, fRollback, dwIndex++);
523 + Assert::Equal(dwIndex, pPlan->cExecuteActions);
524 +
525 + fRollback = TRUE;
526 + dwIndex = 0;
527 + dwExecuteCheckpointId = 1;
528 + ValidateExecuteRollbackBoundaryStart(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE);
529 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
530 + dwExecuteCheckpointId += 1; // cache checkpoints
531 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
532 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
533 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
534 + ValidateExecuteRollbackBoundaryEnd(pPlan, fRollback, dwIndex++);
535 + Assert::Equal(dwIndex, pPlan->cRollbackActions);
536 +
537 + Assert::Equal(1ul, pPlan->cExecutePackagesTotal);
538 + Assert::Equal(2ul, pPlan->cOverallProgressTicksTotal);
539 +
540 + dwIndex = 0;
541 + Assert::Equal(dwIndex, pPlan->cRestoreRelatedBundleActions);
542 +
543 + dwIndex = 0;
544 + ValidateCleanAction(pPlan, dwIndex++, L"NetFx48Web");
545 + Assert::Equal(dwIndex, pPlan->cCleanActions);
546 +
547 + UINT uIndex = 0;
548 + ValidatePlannedProvider(pPlan, uIndex++, L"{35192ED0-C70A-49B2-9D12-3B1FA39B5E6F}", NULL);
549 + Assert::Equal(uIndex, pPlan->cPlannedProviders);
550 +
551 + Assert::Equal(3ul, pEngineState->packages.cPackages);
552 + ValidateNonPermanentPackageExpectedStates(&pEngineState->packages.rgPackages[1], L"PackageA", BURN_PACKAGE_REGISTRATION_STATE_PRESENT, BURN_PACKAGE_REGISTRATION_STATE_PRESENT);
553 + ValidateNonPermanentPackageExpectedStates(&pEngineState->packages.rgPackages[2], L"PackageB", BURN_PACKAGE_REGISTRATION_STATE_PRESENT, BURN_PACKAGE_REGISTRATION_STATE_PRESENT);
554 + }
555 +
556 [Fact]
557 void OrphanCompatiblePackageTest()
558 {
src/burn/test/BurnUnitTest/TestData/PlanTest/BundlePackage_Multiple_manifest.xml
+1 -1
@@ -1 +1 @@
1 -<?xml version="1.0" encoding="utf-8"?><BurnManifest xmlns="http://wixtoolset.org/schemas/v4/2008/Burn"><Log PathVariable="WixBundleLog" Prefix="~BundlePackageTests_MultipleBundlePackagesBundle" Extension=".log" /><RelatedBundle Id="{86D214FB-8D74-456C-99B3-6557ECA6159C}" Action="Upgrade" /><Variable Id="TestGroupName" Value="BundlePackageTests" Type="string" Hidden="no" Persisted="no" /><Variable Id="WixBundleInProgressName" Hidden="no" Persisted="yes" /><Variable Id="WixBundleName" Hidden="no" Persisted="yes" /><Variable Id="WixBundleOriginalSource" Hidden="no" Persisted="yes" /><Variable Id="WixBundleOriginalSourceFolder" Hidden="no" Persisted="yes" /><Variable Id="WixBundleLastUsedSource" Hidden="no" Persisted="yes" /><RegistrySearch Id="NETFRAMEWORK45" Variable="NETFRAMEWORK45" Root="HKLM" Key="SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full" Value="Release" Type="value" VariableType="string" /><UX><Payload Id="WixManagedBootstrapperApplicationHost" FilePath="mbahost.dll" SourcePath="u30" /><Payload Id="payO60IVK4ATGzPpMz3rwVbUWl6DyU" FilePath="WixToolset.Mba.Host.config" SourcePath="u0" /><Payload Id="payxj4zDAKL2NVlz4ohp0GvwFHepyI" FilePath="TestBA.dll" SourcePath="u1" /><Payload Id="pay1hOSAUC8_D633cD2TXpIXCL30OU" FilePath="mbanative.dll" SourcePath="u2" /><Payload Id="payujy6Izl_BlUNfHt2eI.ADfjYAv4" FilePath="WixToolset.Mba.Core.dll" SourcePath="u3" /><Payload Id="payR4EbR4OTDZpPEycWaSSM_gZRBWM" FilePath="mbapreq.thm" SourcePath="u4" /><Payload Id="paylVCy2Ecl8pHPdJTCQZryUG4T9us" FilePath="mbapreq.png" SourcePath="u5" /><Payload Id="payTaG4B_lob1aLcKFaOqSSG3MPMpU" FilePath="mbapreq.wxl" SourcePath="u6" /><Payload Id="payZwIGuiezVTitZOoZKxyh2DdRSGs" FilePath="1028\mbapreq.wxl" SourcePath="u7" /><Payload Id="pay.herBWX.LlOh8jLsx24aWdunV_0" FilePath="1029\mbapreq.wxl" SourcePath="u8" /><Payload Id="pay8DkMszYsoxxdgX14huLDMYXylQg" FilePath="1030\mbapreq.wxl" SourcePath="u9" /><Payload Id="payPaHpoTeOdkW.TK99IDwktNLhTAg" FilePath="1031\mbapreq.wxl" SourcePath="u10" /><Payload Id="pay45AtAzterLTMzZgdxxtuYvaiXwU" FilePath="1032\mbapreq.wxl" SourcePath="u11" /><Payload Id="payA2VEKIqhePyNIEmr14eyH3JoVLc" FilePath="1035\mbapreq.wxl" SourcePath="u12" /><Payload Id="payvre23ObscjzhcaFIifUAkXMdPa8" FilePath="1036\mbapreq.wxl" SourcePath="u13" /><Payload Id="paytxUV3vuBbG2c.a9c.d_sZX2x6wA" FilePath="1038\mbapreq.wxl" SourcePath="u14" /><Payload Id="payYvMWRK9xelo5.sQn7jRkJIaBp9A" FilePath="1040\mbapreq.wxl" SourcePath="u15" /><Payload Id="pay68KKSApyQimbA25t6kSbqhdeH10" FilePath="1041\mbapreq.wxl" SourcePath="u16" /><Payload Id="paypiqxaHpYZqx.9eDVjQrj1igLbRY" FilePath="1042\mbapreq.wxl" SourcePath="u17" /><Payload Id="payTO0YwZzxKpbqdrBVUcVRTu3BFe8" FilePath="1043\mbapreq.wxl" SourcePath="u18" /><Payload Id="payIXg2ldBJukRzhqWolJVOEbTmF34" FilePath="1044\mbapreq.wxl" SourcePath="u19" /><Payload Id="payOHIZbSkIvrpwKkkXI173tv3u3B4" FilePath="1045\mbapreq.wxl" SourcePath="u20" /><Payload Id="payQRQ_UZl_R2UtV0xDXB2yeH2bg3E" FilePath="1046\mbapreq.wxl" SourcePath="u21" /><Payload Id="payhrejLLBfc1i27iN._QPhQ4K337I" FilePath="1049\mbapreq.wxl" SourcePath="u22" /><Payload Id="payqEzaDNzxB68vGp29jgDcCos6dvg" FilePath="1051\mbapreq.wxl" SourcePath="u23" /><Payload Id="paydz8Vk8xSTyYohgGXTSIxWGXL5.Q" FilePath="1053\mbapreq.wxl" SourcePath="u24" /><Payload Id="pay0HRUZTlbC3taSOffJBsEj92Br8Y" FilePath="1055\mbapreq.wxl" SourcePath="u25" /><Payload Id="payIvUOkc_EMH7laMFehefNolV8hZo" FilePath="1060\mbapreq.wxl" SourcePath="u26" /><Payload Id="payLFhOb.rHuk4sW5CYAPMShG0NjGI" FilePath="2052\mbapreq.wxl" SourcePath="u27" /><Payload Id="payqIKCmERK7Nhxx_nNXvRxdKqKDbI" FilePath="2070\mbapreq.wxl" SourcePath="u28" /><Payload Id="payqeWUzIVaEqjuRXN0z8ECC3Y4tCc" FilePath="3082\mbapreq.wxl" SourcePath="u29" /><Payload Id="paylfeHEjJSSTnNzY9QMZM2Ye3Ipy4" FilePath="mbapreq.dll" SourcePath="u31" /><Payload Id="payDPxs6uy8nbky.R7zhir2RRAfc.c" FilePath="WixToolset.Mba.Host.dll" SourcePath="u32" /><Payload Id="uxTxMXPVMXwQrPTMIGa5WGt93w0Ns" FilePath="BootstrapperApplicationData.xml" SourcePath="u33" /><Payload Id="uxYRbgitOs0K878jn5L_z7LdJ21KI" FilePath="BundleExtensionData.xml" SourcePath="u34" /></UX><Container Id="WixAttachedContainer" FileSize="15696370" Hash="0F9966B421400E481D394DB4C4D7F0F92548E5BEB79B98880C926E817E8C1F381EC8A17053E2E66AE7132A3C9ECE441629E6A1FB3452C5C9282280C40252F141" FilePath="MultipleBundlePackagesBundle.exe" AttachedIndex="1" Attached="yes" Primary="yes" /><Payload Id="NetFx48Web" FilePath="redist\ndp48-web.exe" FileSize="1439328" CertificateRootPublicKeyIdentifier="F49F9B33E25E33CCA0BFB15A62B7C29FFAB3880B" CertificateRootThumbprint="ABDCA79AF9DD48A0EA702AD45260B3C03093FB4B" DownloadUrl="https://go.microsoft.com/fwlink/?LinkId=2085155" Packaging="external" SourcePath="redist\ndp48-web.exe" /><Payload Id="PackageA" FilePath="BundleA.exe" FileSize="5241635" Hash="20E1AFF76DE4693CB2876DC6BCCA0152DB16BE49AEDE2CD581C03FC39AB89DEA12BC25CB435F06E4D7D2B4443CE8A8935D5E92E2E49A4981B60A273980E4B29B" Packaging="embedded" SourcePath="a0" Container="WixAttachedContainer" /><Payload Id="PackageB" FilePath="BundleB_x64.exe" FileSize="10450821" Hash="43A58873D61D6E0FA83F6C5266F2F05FEA9BC85D11C195493B7FD9F0B4AA799C1EFCB78D76DCED32124D2EC62A4E7114B62CDE6F0B87E42A7E28CDBB0DA0FF8E" Packaging="embedded" SourcePath="a1" Container="WixAttachedContainer" /><RollbackBoundary Id="WixDefaultBoundary" Vital="yes" Transaction="no" /><Registration Id="{35192ED0-C70A-49B2-9D12-3B1FA39B5E6F}" ExecutableName="MultipleBundlePackagesBundle.exe" PerMachine="yes" Tag="" Version="1.0.0.0" ProviderKey="{35192ED0-C70A-49B2-9D12-3B1FA39B5E6F}"><Arp Register="yes" DisplayName="~BundlePackageTests - MultipleBundlePackagesBundle" DisplayVersion="1.0.0.0" /></Registration><Chain><ExePackage Id="NetFx48Web" Cache="remove" CacheId="642721C60D52051C7F3434D8710FE3406A7CFE10B2B39E90EA847719ED1697D7C614F2DF44AD50412B1DF8C98DD78FDC57CA1D047D28C81AC158092E5FB18040" InstallSize="1439328" Size="1439328" PerMachine="yes" Permanent="yes" Vital="yes" RollbackBoundaryForward="WixDefaultBoundary" LogPathVariable="NetFx48WebLog" RollbackLogPathVariable="WixBundleRollbackLog_NetFx48Web" DetectCondition="NETFRAMEWORK45 &gt;= 528040" InstallArguments="/q /norestart /log &quot;[NetFx48WebLog].html&quot;" UninstallArguments="" Uninstallable="no" RepairArguments="" Repairable="no" Protocol="netfx4"><PayloadRef Id="NetFx48Web" /></ExePackage><BundlePackage Id="PackageA" Cache="keep" CacheId="{B39CEE4D-CCD7-4797-BE3A-6613BD1DC4BE}v1.0.0.0" InstallSize="2169" Size="5241635" Version="1.0.0.0" PerMachine="yes" Permanent="no" Vital="yes" LogPathVariable="WixBundleLog_PackageA" RollbackLogPathVariable="WixBundleRollbackLog_PackageA" BundleId="{B39CEE4D-CCD7-4797-BE3A-6613BD1DC4BE}" InstallArguments="" UninstallArguments="" RepairArguments="" SupportsBurnProtocol="yes" Win64="no"><Provides Key="{B39CEE4D-CCD7-4797-BE3A-6613BD1DC4BE}" Version="1.0.0.0" DisplayName="~BasicFunctionalityTests - BundleA" Imported="yes" /><RelatedBundle Id="{8C7E2C47-1EE7-4BBE-99A2-EAB7F3693F48}" Action="Upgrade" /><PayloadRef Id="PackageA" /></BundlePackage><BundlePackage Id="PackageB" Cache="keep" CacheId="{7506235A-7C59-4750-82C7-EB460A87ED3A}v1.0.0.0" InstallSize="1441497" Size="10450821" Version="1.0.0.0" PerMachine="yes" Permanent="no" Vital="yes" RollbackBoundaryBackward="WixDefaultBoundary" LogPathVariable="WixBundleLog_PackageB" RollbackLogPathVariable="WixBundleRollbackLog_PackageB" BundleId="{7506235A-7C59-4750-82C7-EB460A87ED3A}" InstallArguments="" UninstallArguments="" RepairArguments="" SupportsBurnProtocol="yes" Win64="yes"><Provides Key="{7506235A-7C59-4750-82C7-EB460A87ED3A}" Version="1.0.0.0" DisplayName="~BasicFunctionalityTests - BundleB_x64" Imported="yes" /><RelatedBundle Id="{79F45B7A-D990-46E4-819B-078D87C3321A}" Action="Upgrade" /><PayloadRef Id="PackageB" /></BundlePackage></Chain><CommandLine Variables="upperCase" /></BurnManifest>
1 +<?xml version="1.0" encoding="utf-8"?><BurnManifest xmlns="http://wixtoolset.org/schemas/v4/2008/Burn"><Log PathVariable="WixBundleLog" Prefix="~BundlePackageTests_MultipleBundlePackagesBundle" Extension=".log" /><RelatedBundle Id="{86D214FB-8D74-456C-99B3-6557ECA6159C}" Action="Upgrade" /><Variable Id="TestGroupName" Value="BundlePackageTests" Type="string" Hidden="no" Persisted="no" /><Variable Id="WixBundleInProgressName" Hidden="no" Persisted="yes" /><Variable Id="WixBundleName" Hidden="no" Persisted="yes" /><Variable Id="WixBundleOriginalSource" Hidden="no" Persisted="yes" /><Variable Id="WixBundleOriginalSourceFolder" Hidden="no" Persisted="yes" /><Variable Id="WixBundleLastUsedSource" Hidden="no" Persisted="yes" /><RegistrySearch Id="NETFRAMEWORK45" Variable="NETFRAMEWORK45" Root="HKLM" Key="SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full" Value="Release" Type="value" VariableType="string" /><UX><Payload Id="WixManagedBootstrapperApplicationHost" FilePath="mbahost.dll" SourcePath="u30" /><Payload Id="payO60IVK4ATGzPpMz3rwVbUWl6DyU" FilePath="WixToolset.Mba.Host.config" SourcePath="u0" /><Payload Id="payxj4zDAKL2NVlz4ohp0GvwFHepyI" FilePath="TestBA.dll" SourcePath="u1" /><Payload Id="pay1hOSAUC8_D633cD2TXpIXCL30OU" FilePath="mbanative.dll" SourcePath="u2" /><Payload Id="payujy6Izl_BlUNfHt2eI.ADfjYAv4" FilePath="WixToolset.Mba.Core.dll" SourcePath="u3" /><Payload Id="payR4EbR4OTDZpPEycWaSSM_gZRBWM" FilePath="mbapreq.thm" SourcePath="u4" /><Payload Id="paylVCy2Ecl8pHPdJTCQZryUG4T9us" FilePath="mbapreq.png" SourcePath="u5" /><Payload Id="payTaG4B_lob1aLcKFaOqSSG3MPMpU" FilePath="mbapreq.wxl" SourcePath="u6" /><Payload Id="payZwIGuiezVTitZOoZKxyh2DdRSGs" FilePath="1028\mbapreq.wxl" SourcePath="u7" /><Payload Id="pay.herBWX.LlOh8jLsx24aWdunV_0" FilePath="1029\mbapreq.wxl" SourcePath="u8" /><Payload Id="pay8DkMszYsoxxdgX14huLDMYXylQg" FilePath="1030\mbapreq.wxl" SourcePath="u9" /><Payload Id="payPaHpoTeOdkW.TK99IDwktNLhTAg" FilePath="1031\mbapreq.wxl" SourcePath="u10" /><Payload Id="pay45AtAzterLTMzZgdxxtuYvaiXwU" FilePath="1032\mbapreq.wxl" SourcePath="u11" /><Payload Id="payA2VEKIqhePyNIEmr14eyH3JoVLc" FilePath="1035\mbapreq.wxl" SourcePath="u12" /><Payload Id="payvre23ObscjzhcaFIifUAkXMdPa8" FilePath="1036\mbapreq.wxl" SourcePath="u13" /><Payload Id="paytxUV3vuBbG2c.a9c.d_sZX2x6wA" FilePath="1038\mbapreq.wxl" SourcePath="u14" /><Payload Id="payYvMWRK9xelo5.sQn7jRkJIaBp9A" FilePath="1040\mbapreq.wxl" SourcePath="u15" /><Payload Id="pay68KKSApyQimbA25t6kSbqhdeH10" FilePath="1041\mbapreq.wxl" SourcePath="u16" /><Payload Id="paypiqxaHpYZqx.9eDVjQrj1igLbRY" FilePath="1042\mbapreq.wxl" SourcePath="u17" /><Payload Id="payTO0YwZzxKpbqdrBVUcVRTu3BFe8" FilePath="1043\mbapreq.wxl" SourcePath="u18" /><Payload Id="payIXg2ldBJukRzhqWolJVOEbTmF34" FilePath="1044\mbapreq.wxl" SourcePath="u19" /><Payload Id="payOHIZbSkIvrpwKkkXI173tv3u3B4" FilePath="1045\mbapreq.wxl" SourcePath="u20" /><Payload Id="payQRQ_UZl_R2UtV0xDXB2yeH2bg3E" FilePath="1046\mbapreq.wxl" SourcePath="u21" /><Payload Id="payhrejLLBfc1i27iN._QPhQ4K337I" FilePath="1049\mbapreq.wxl" SourcePath="u22" /><Payload Id="payqEzaDNzxB68vGp29jgDcCos6dvg" FilePath="1051\mbapreq.wxl" SourcePath="u23" /><Payload Id="paydz8Vk8xSTyYohgGXTSIxWGXL5.Q" FilePath="1053\mbapreq.wxl" SourcePath="u24" /><Payload Id="pay0HRUZTlbC3taSOffJBsEj92Br8Y" FilePath="1055\mbapreq.wxl" SourcePath="u25" /><Payload Id="payIvUOkc_EMH7laMFehefNolV8hZo" FilePath="1060\mbapreq.wxl" SourcePath="u26" /><Payload Id="payLFhOb.rHuk4sW5CYAPMShG0NjGI" FilePath="2052\mbapreq.wxl" SourcePath="u27" /><Payload Id="payqIKCmERK7Nhxx_nNXvRxdKqKDbI" FilePath="2070\mbapreq.wxl" SourcePath="u28" /><Payload Id="payqeWUzIVaEqjuRXN0z8ECC3Y4tCc" FilePath="3082\mbapreq.wxl" SourcePath="u29" /><Payload Id="paylfeHEjJSSTnNzY9QMZM2Ye3Ipy4" FilePath="mbapreq.dll" SourcePath="u31" /><Payload Id="payDPxs6uy8nbky.R7zhir2RRAfc.c" FilePath="WixToolset.Mba.Host.dll" SourcePath="u32" /><Payload Id="uxTxMXPVMXwQrPTMIGa5WGt93w0Ns" FilePath="BootstrapperApplicationData.xml" SourcePath="u33" /><Payload Id="uxYRbgitOs0K878jn5L_z7LdJ21KI" FilePath="BundleExtensionData.xml" SourcePath="u34" /></UX><Container Id="WixAttachedContainer" FileSize="15696370" Hash="0F9966B421400E481D394DB4C4D7F0F92548E5BEB79B98880C926E817E8C1F381EC8A17053E2E66AE7132A3C9ECE441629E6A1FB3452C5C9282280C40252F141" FilePath="MultipleBundlePackagesBundle.exe" AttachedIndex="1" Attached="yes" Primary="yes" /><Payload Id="NetFx48Web" FilePath="redist\ndp48-web.exe" FileSize="1439328" CertificateRootPublicKeyIdentifier="F49F9B33E25E33CCA0BFB15A62B7C29FFAB3880B" CertificateRootThumbprint="ABDCA79AF9DD48A0EA702AD45260B3C03093FB4B" DownloadUrl="https://go.microsoft.com/fwlink/?LinkId=2085155" Packaging="external" SourcePath="redist\ndp48-web.exe" /><Payload Id="PackageA" FilePath="BundleA.exe" FileSize="5241635" Hash="20E1AFF76DE4693CB2876DC6BCCA0152DB16BE49AEDE2CD581C03FC39AB89DEA12BC25CB435F06E4D7D2B4443CE8A8935D5E92E2E49A4981B60A273980E4B29B" Packaging="embedded" SourcePath="a0" Container="WixAttachedContainer" /><Payload Id="PackageB" FilePath="BundleB_x64.exe" FileSize="10450821" Hash="43A58873D61D6E0FA83F6C5266F2F05FEA9BC85D11C195493B7FD9F0B4AA799C1EFCB78D76DCED32124D2EC62A4E7114B62CDE6F0B87E42A7E28CDBB0DA0FF8E" Packaging="embedded" SourcePath="a1" Container="WixAttachedContainer" /><RollbackBoundary Id="WixDefaultBoundary" Vital="yes" Transaction="no" /><Registration Id="{35192ED0-C70A-49B2-9D12-3B1FA39B5E6F}" ExecutableName="MultipleBundlePackagesBundle.exe" PerMachine="yes" Tag="" Version="1.0.0.0" ProviderKey="{35192ED0-C70A-49B2-9D12-3B1FA39B5E6F}"><Arp Register="yes" DisplayName="~BundlePackageTests - MultipleBundlePackagesBundle" DisplayVersion="1.0.0.0" /></Registration><Chain><ExePackage Id="NetFx48Web" Cache="remove" CacheId="642721C60D52051C7F3434D8710FE3406A7CFE10B2B39E90EA847719ED1697D7C614F2DF44AD50412B1DF8C98DD78FDC57CA1D047D28C81AC158092E5FB18040" InstallSize="1439328" Size="1439328" PerMachine="yes" Permanent="yes" Vital="yes" RollbackBoundaryForward="WixDefaultBoundary" LogPathVariable="NetFx48WebLog" RollbackLogPathVariable="WixBundleRollbackLog_NetFx48Web" DetectCondition="NETFRAMEWORK45 &gt;= 528040" InstallArguments="/q /norestart /log &quot;[NetFx48WebLog].html&quot;" UninstallArguments="" Uninstallable="no" RepairArguments="" Repairable="no" Protocol="netfx4"><PayloadRef Id="NetFx48Web" /></ExePackage><BundlePackage Id="PackageA" Cache="keep" CacheId="{B39CEE4D-CCD7-4797-BE3A-6613BD1DC4BE}v1.0.0.0" InstallSize="2169" Size="5241635" Version="1.0.0.0" PerMachine="yes" Permanent="no" Vital="yes" RepairCondition="0" LogPathVariable="WixBundleLog_PackageA" RollbackLogPathVariable="WixBundleRollbackLog_PackageA" BundleId="{B39CEE4D-CCD7-4797-BE3A-6613BD1DC4BE}" InstallArguments="" UninstallArguments="" RepairArguments="" SupportsBurnProtocol="yes" Win64="no"><Provides Key="{B39CEE4D-CCD7-4797-BE3A-6613BD1DC4BE}" Version="1.0.0.0" DisplayName="~BasicFunctionalityTests - BundleA" Imported="yes" /><RelatedBundle Id="{8C7E2C47-1EE7-4BBE-99A2-EAB7F3693F48}" Action="Upgrade" /><PayloadRef Id="PackageA" /></BundlePackage><BundlePackage Id="PackageB" Cache="keep" CacheId="{7506235A-7C59-4750-82C7-EB460A87ED3A}v1.0.0.0" InstallSize="1441497" Size="10450821" Version="1.0.0.0" PerMachine="yes" Permanent="no" Vital="yes" RollbackBoundaryBackward="WixDefaultBoundary" LogPathVariable="WixBundleLog_PackageB" RollbackLogPathVariable="WixBundleRollbackLog_PackageB" BundleId="{7506235A-7C59-4750-82C7-EB460A87ED3A}" InstallArguments="" UninstallArguments="" RepairArguments="" SupportsBurnProtocol="yes" Win64="yes"><Provides Key="{7506235A-7C59-4750-82C7-EB460A87ED3A}" Version="1.0.0.0" DisplayName="~BasicFunctionalityTests - BundleB_x64" Imported="yes" /><RelatedBundle Id="{79F45B7A-D990-46E4-819B-078D87C3321A}" Action="Upgrade" /><PayloadRef Id="PackageB" /></BundlePackage></Chain><CommandLine Variables="upperCase" /></BurnManifest>
src/burn/test/BurnUnitTest/VariableTest.cpp
+1
@@ -388,6 +388,7 @@ namespace Bootstrapper
388 Assert::True(EvaluateFailureConditionHelper(&variables, L"1A"));
389 Assert::True(EvaluateFailureConditionHelper(&variables, L"*"));
390
391 + Assert::False(EvaluateFailureConditionHelper(&variables, L"0"));
392 Assert::True(EvaluateFailureConditionHelper(&variables, L"1 == 1"));
393 }
394 finally
src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp
+2 -1
@@ -425,6 +425,7 @@ public: // IBootstrapperApplication
425 __in BOOTSTRAPPER_PACKAGE_STATE state,
426 __in BOOL fCached,
427 __in BOOTSTRAPPER_PACKAGE_CONDITION_RESULT installCondition,
428 + __in BOOTSTRAPPER_PACKAGE_CONDITION_RESULT repairCondition,
429 __in BOOTSTRAPPER_REQUEST_STATE recommendedState,
430 __in BOOTSTRAPPER_CACHE_TYPE recommendedCacheType,
431 __inout BOOTSTRAPPER_REQUEST_STATE* pRequestState,
@@ -485,7 +486,7 @@ public: // IBootstrapperApplication
486 }
487 }
488
488 - return CBalBaseBootstrapperApplication::OnPlanPackageBegin(wzPackageId, state, fCached, installCondition, recommendedState, recommendedCacheType, pRequestState, pRequestedCacheType, pfCancel);
489 + return CBalBaseBootstrapperApplication::OnPlanPackageBegin(wzPackageId, state, fCached, installCondition, repairCondition, recommendedState, recommendedCacheType, pRequestState, pRequestedCacheType, pfCancel);
490 }
491
492
src/wix/WixToolset.Core.Burn/Bundles/CreateBootstrapperApplicationManifestCommand.cs
+5
@@ -206,6 +206,11 @@ namespace WixToolset.Core.Burn.Bundles
206 writer.WriteAttributeString("InstallCondition", package.PackageSymbol.InstallCondition);
207 }
208
209 + if (!String.IsNullOrEmpty(package.PackageSymbol.RepairCondition))
210 + {
211 + writer.WriteAttributeString("RepairCondition", package.PackageSymbol.RepairCondition);
212 + }
213 +
214 switch (package.PackageSymbol.Cache)
215 {
216 case BundleCacheType.Remove:
src/wix/WixToolset.Core.Burn/Bundles/CreateBurnManifestCommand.cs
+5
@@ -389,6 +389,11 @@ namespace WixToolset.Core.Burn.Bundles
389 writer.WriteAttributeString("InstallCondition", package.PackageSymbol.InstallCondition);
390 }
391
392 + if (!String.IsNullOrEmpty(package.PackageSymbol.RepairCondition))
393 + {
394 + writer.WriteAttributeString("RepairCondition", package.PackageSymbol.RepairCondition);
395 + }
396 +
397 if (package.SpecificPackageSymbol is WixBundleBundlePackageSymbol bundlePackage) // BUNDLE
398 {
399 writer.WriteAttributeString("BundleId", bundlePackage.BundleId);
src/wix/WixToolset.Core.Burn/Bundles/PerformBundleBackendValidationCommand.cs
+5
@@ -91,6 +91,11 @@ namespace WixToolset.Core.Burn.Bundles
91 {
92 this.BackendHelper.ValidateBundleCondition(symbol.SourceLineNumbers, elementName, "InstallCondition", symbol.InstallCondition, BundleConditionPhase.Plan);
93 }
94 +
95 + if (!String.IsNullOrEmpty(symbol.RepairCondition))
96 + {
97 + this.BackendHelper.ValidateBundleCondition(symbol.SourceLineNumbers, elementName, "RepairCondition", symbol.RepairCondition, BundleConditionPhase.Plan);
98 + }
99 }
100
101 private void ValidateBundlePackage(WixBundleBundlePackageSymbol symbol, WixBundlePackageSymbol packageSymbol)
src/wix/WixToolset.Core/Compiler_Bundle.cs
+11
@@ -2003,6 +2003,7 @@ namespace WixToolset.Core
2003 };
2004 string after = null;
2005 string installCondition = null;
2006 + string repairCondition = null;
2007 var cache = BundleCacheType.Keep; // the default is to cache everything in tradeoff for stability over disk space.
2008 string cacheId = null;
2009 string description = null;
@@ -2061,6 +2062,10 @@ namespace WixToolset.Core
2062 case "InstallCondition":
2063 installCondition = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
2064 break;
2065 + case "RepairCondition":
2066 + repairCondition = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
2067 + allowed = (packageType != WixBundlePackageType.Msu);
2068 + break;
2069 case "Cache":
2070 var value = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
2071 switch (value)
@@ -2262,6 +2267,11 @@ namespace WixToolset.Core
2267 }
2268 }
2269
2270 + if (repairArguments == null && repairCondition != null)
2271 + {
2272 + this.Core.Write(ErrorMessages.ExpectedAttributeWithValueWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "RepairArguments", "RepairCondition"));
2273 + }
2274 +
2275 // Validate the protocol if provided.
2276 if (!String.IsNullOrEmpty(protocol))
2277 {
@@ -2429,6 +2439,7 @@ namespace WixToolset.Core
2439 Type = packageType,
2440 Attributes = attributes,
2441 InstallCondition = installCondition,
2442 + RepairCondition = repairCondition,
2443 Cache = cache,
2444 CacheId = cacheId,
2445 Description = description,
src/wix/test/WixToolsetTest.CoreIntegration/BundleManifestFixture.cs
+1 -1
@@ -88,7 +88,7 @@ namespace WixToolsetTest.CoreIntegration
88 { "WixPackageProperties", new List<string> { "DownloadSize", "PackageSize", "InstalledSize", "Version" } },
89 };
90 Assert.Equal(3, packageElements.Count);
91 - Assert.Equal("<WixPackageProperties Package='burn.exe' Vital='yes' DisplayName='Windows Installer XML Toolset' Description='WiX Toolset Bootstrapper' DownloadSize='*' PackageSize='*' InstalledSize='*' PackageType='Exe' Permanent='yes' LogPathVariable='WixBundleLog_burn.exe' RollbackLogPathVariable='WixBundleRollbackLog_burn.exe' Compressed='yes' Version='*' Cache='keep' />", packageElements[0].GetTestXml(ignoreAttributesByElementName));
91 + Assert.Equal("<WixPackageProperties Package='burn.exe' Vital='yes' DisplayName='Windows Installer XML Toolset' Description='WiX Toolset Bootstrapper' DownloadSize='*' PackageSize='*' InstalledSize='*' PackageType='Exe' Permanent='yes' LogPathVariable='WixBundleLog_burn.exe' RollbackLogPathVariable='WixBundleRollbackLog_burn.exe' Compressed='yes' Version='*' RepairCondition='RepairRedists' Cache='keep' />", packageElements[0].GetTestXml(ignoreAttributesByElementName));
92 Assert.Equal("<WixPackageProperties Package='RemotePayloadExe' Vital='yes' DisplayName='Override RemotePayload display name' Description='Override RemotePayload description' DownloadSize='1' PackageSize='1' InstalledSize='1' PackageType='Exe' Permanent='yes' LogPathVariable='WixBundleLog_RemotePayloadExe' RollbackLogPathVariable='WixBundleRollbackLog_RemotePayloadExe' Compressed='no' Version='1.0.0.0' Cache='keep' />", packageElements[1].GetTestXml());
93 Assert.Equal("<WixPackageProperties Package='calc.exe' Vital='yes' DisplayName='Override harvested display name' Description='Override harvested description' DownloadSize='*' PackageSize='*' InstalledSize='*' PackageType='Exe' Permanent='yes' LogPathVariable='WixBundleLog_calc.exe' RollbackLogPathVariable='WixBundleRollbackLog_calc.exe' Compressed='yes' Version='*' Cache='keep' />", packageElements[2].GetTestXml(ignoreAttributesByElementName));
94 }
src/wix/test/WixToolsetTest.CoreIntegration/BundlePackageFixture.cs
+2 -2
@@ -354,7 +354,7 @@ namespace WixToolsetTest.CoreIntegration
354 .ToArray();
355 WixAssert.CompareLineByLine(new string[]
356 {
357 - $"<BundlePackage Id='v3bundle.exe' Cache='keep' CacheId='{chainBundleId}v1.0.0.0' InstallSize='1135' Size='*' PerMachine='yes' Permanent='no' Vital='yes' RollbackBoundaryForward='WixDefaultBoundary' RollbackBoundaryBackward='WixDefaultBoundary' LogPathVariable='WixBundleLog_v3bundle.exe' RollbackLogPathVariable='WixBundleRollbackLog_v3bundle.exe' BundleId='{chainBundleId}' Version='1.0.0.0' InstallArguments='' UninstallArguments='' RepairArguments='' SupportsBurnProtocol='yes' Win64='no'>" +
357 + $"<BundlePackage Id='v3bundle.exe' Cache='keep' CacheId='{chainBundleId}v1.0.0.0' InstallSize='1135' Size='*' PerMachine='yes' Permanent='no' Vital='yes' RollbackBoundaryForward='WixDefaultBoundary' RollbackBoundaryBackward='WixDefaultBoundary' LogPathVariable='WixBundleLog_v3bundle.exe' RollbackLogPathVariable='WixBundleRollbackLog_v3bundle.exe' RepairCondition='0' BundleId='{chainBundleId}' Version='1.0.0.0' InstallArguments='' UninstallArguments='' RepairArguments='' SupportsBurnProtocol='yes' Win64='no'>" +
358 "<Provides Key='{215a70db-ab35-48c7-be51-d66eaac87177}' Version='1.0.0.0' DisplayName='CustomV3Theme' Imported='yes' />" +
359 "<RelatedBundle Id='{2BF4C01F-C132-4E70-97AB-2BC68C7CCD10}' Action='Upgrade' />" +
360 "<PayloadRef Id='v3bundle.exe' />" +
@@ -382,7 +382,7 @@ namespace WixToolsetTest.CoreIntegration
382 .ToArray();
383 WixAssert.CompareLineByLine(new string[]
384 {
385 - "<WixPackageProperties Package='v3bundle.exe' Vital='yes' DisplayName='CustomV3Theme' Description='CustomV3Theme' DownloadSize='*' PackageSize='*' InstalledSize='1135' PackageType='Bundle' Permanent='no' LogPathVariable='WixBundleLog_v3bundle.exe' RollbackLogPathVariable='WixBundleRollbackLog_v3bundle.exe' Compressed='yes' Version='1.0.0.0' Cache='keep' />",
385 + "<WixPackageProperties Package='v3bundle.exe' Vital='yes' DisplayName='CustomV3Theme' Description='CustomV3Theme' DownloadSize='*' PackageSize='*' InstalledSize='1135' PackageType='Bundle' Permanent='no' LogPathVariable='WixBundleLog_v3bundle.exe' RollbackLogPathVariable='WixBundleRollbackLog_v3bundle.exe' Compressed='yes' Version='1.0.0.0' RepairCondition='0' Cache='keep' />",
386 }, packageElements);
387 }
388 }
src/wix/test/WixToolsetTest.CoreIntegration/ExePackageFixture.cs
+24
@@ -35,6 +35,30 @@ namespace WixToolsetTest.CoreIntegration
35 }
36 }
37
38 + [Fact]
39 + public void ErrorWhenRepairConditionWithoutRepairArguments()
40 + {
41 + var folder = TestData.Get(@"TestData", "ExePackage");
42 +
43 + using (var fs = new DisposableFileSystem())
44 + {
45 + var baseFolder = fs.GetFolder();
46 +
47 + var result = WixRunner.Execute(new[]
48 + {
49 + "build",
50 + Path.Combine(folder, "RepairConditionWithoutRepairArguments.wxs"),
51 + "-o", Path.Combine(baseFolder, "test.wixlib")
52 + });
53 +
54 + WixAssert.CompareLineByLine(new[]
55 + {
56 + "The ExePackage/@RepairArguments attribute is required to have a value when attribute RepairCondition is present.",
57 + }, result.Messages.Select(m => m.ToString()).ToArray());
58 + Assert.Equal(401, result.ExitCode);
59 + }
60 + }
61 +
62 [Fact]
63 public void ErrorWhenRequireDetectCondition()
64 {
src/wix/test/WixToolsetTest.CoreIntegration/TestData/BundlePackage/V3BundlePackage.wxs
+1 -1
@@ -4,7 +4,7 @@
4 <BootstrapperApplicationDll SourceFile="fakeba.dll" />
5 </BootstrapperApplication>
6 <Chain>
7 - <BundlePackage SourceFile="v3bundle.exe" />
7 + <BundlePackage SourceFile="v3bundle.exe" RepairCondition="0" />
8 </Chain>
9 </Bundle>
10 </Wix>
src/wix/test/WixToolsetTest.CoreIntegration/TestData/CustomPackageDescription/CustomPackageDescription.wxs
+1 -1
@@ -2,7 +2,7 @@
2 <Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
3 <Fragment>
4 <PackageGroup Id="BundlePackages">
5 - <ExePackage DetectCondition="ForTestPurposesOnly" SourceFile="burn.exe" Permanent="yes" />
5 + <ExePackage DetectCondition="ForTestPurposesOnly" SourceFile="burn.exe" Permanent="yes" RepairArguments="-repair" RepairCondition="RepairRedists" />
6 <ExePackage Id="RemotePayloadExe" DetectCondition="ForTestPurposesOnly" Description="Override RemotePayload description" DisplayName="Override RemotePayload display name" Permanent="yes">
7 <ExePackagePayload Description="RemotePayload description" Hash="a" ProductName="RemotePayload product name" Size="1" Version="1.0.0.0" Name="fake.exe" DownloadUrl="example.com" />
8 </ExePackage>
src/wix/test/WixToolsetTest.CoreIntegration/TestData/ExePackage/RepairConditionWithoutRepairArguments.wxs new
+12
@@ -0,0 +1,12 @@
1 +<?xml version="1.0" encoding="utf-8"?>
2 +<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
3 + <Fragment>
4 + <PackageGroup Id="TestPackageGroup">
5 + <ExePackage RepairCondition="0"
6 + InstallArguments="-install"
7 + Permanent="yes"
8 + DetectCondition="fake"
9 + SourceFile="testsetup.exe" />
10 + </PackageGroup>
11 + </Fragment>
12 +</Wix>