Add WixBundleCommandLineAction, don't set dynamic variables at startup.
Fixes 6736
Sean Hall committed
Mar 16, 2022 at 15:20 UTC
8c9ca787bee29f969cd7ca9aeaa46626d557d196
11 files changed
+78
-58
src/burn/engine/core.cpp
+5
-5
@@ -309,7 +309,7 @@ extern "C" HRESULT CoreDetect(
309
pEngineState->fDetected = FALSE;
310
pEngineState->fPlanned = FALSE;
311
DetectReset(&pEngineState->registration, &pEngineState->packages);
312
- PlanReset(&pEngineState->plan, &pEngineState->containers, &pEngineState->packages, &pEngineState->layoutPayloads);
312
+ PlanReset(&pEngineState->plan, &pEngineState->variables, &pEngineState->containers, &pEngineState->packages, &pEngineState->layoutPayloads);
313
314
hr = RegistrationSetDynamicVariables(&pEngineState->registration, &pEngineState->variables);
315
ExitOnFailure(hr, "Failed to reset the dynamic registration variables during detect.");
@@ -441,6 +441,9 @@ extern "C" HRESULT CorePlan(
441
BURN_PACKAGE* pForwardCompatibleBundlePackage = NULL;
442
BOOL fContinuePlanning = TRUE; // assume we won't skip planning due to dependencies.
443
444
+ hr = PlanSetVariables(action, &pEngineState->variables);
445
+ ExitOnFailure(hr, "Failed to update action.");
446
+
447
LogId(REPORT_STANDARD, MSG_PLAN_BEGIN, pEngineState->packages.cPackages, LoggingBurnActionToString(action));
448
449
fPlanBegan = TRUE;
@@ -458,7 +461,7 @@ extern "C" HRESULT CorePlan(
461
462
// Always reset the plan.
463
pEngineState->fPlanned = FALSE;
461
- PlanReset(&pEngineState->plan, &pEngineState->containers, &pEngineState->packages, &pEngineState->layoutPayloads);
464
+ PlanReset(&pEngineState->plan, &pEngineState->variables, &pEngineState->containers, &pEngineState->packages, &pEngineState->layoutPayloads);
465
466
// Remember the overall action state in the plan since it shapes the changes
467
// we make everywhere.
@@ -472,9 +475,6 @@ extern "C" HRESULT CorePlan(
475
pEngineState->plan.fDisableRollback = pEngineState->fDisableRollback || BOOTSTRAPPER_ACTION_UNSAFE_UNINSTALL == pEngineState->plan.action;
476
pEngineState->plan.fPlanPackageCacheRollback = BOOTSTRAPPER_REGISTRATION_TYPE_NONE == pEngineState->registration.detectedRegistrationType;
477
475
- hr = PlanSetVariables(action, &pEngineState->variables);
476
- ExitOnFailure(hr, "Failed to update action.");
477
-
478
// Set resume commandline
479
hr = PlanSetResumeCommand(&pEngineState->plan, &pEngineState->registration, &pEngineState->log);
480
ExitOnFailure(hr, "Failed to set resume command");
src/burn/engine/core.h
+1
@@ -37,6 +37,7 @@ const LPCWSTR BURN_COMMANDLINE_SWITCH_PREFIX = L"burn.";
37
const LPCWSTR BURN_BUNDLE_LAYOUT_DIRECTORY = L"WixBundleLayoutDirectory";
38
const LPCWSTR BURN_BUNDLE_ACTION = L"WixBundleAction";
39
const LPCWSTR BURN_BUNDLE_ACTIVE_PARENT = L"WixBundleActiveParent";
40
+const LPCWSTR BURN_BUNDLE_COMMAND_LINE_ACTION = L"WixBundleCommandLineAction";
41
const LPCWSTR BURN_BUNDLE_EXECUTE_PACKAGE_CACHE_FOLDER = L"WixBundleExecutePackageCacheFolder";
42
const LPCWSTR BURN_BUNDLE_EXECUTE_PACKAGE_ACTION = L"WixBundleExecutePackageAction";
43
const LPCWSTR BURN_BUNDLE_FORCED_RESTART_PACKAGE = L"WixBundleForcedRestartPackage";
src/burn/engine/engine.cpp
+2
-2
@@ -557,8 +557,8 @@ static HRESULT RunNormal(
557
hr = S_OK;
558
559
// Set some built-in variables before loading the BA.
560
- hr = PlanSetVariables(pEngineState->command.action, &pEngineState->variables);
561
- ExitOnFailure(hr, "Failed to set action variables.");
560
+ hr = VariableSetNumeric(&pEngineState->variables, BURN_BUNDLE_COMMAND_LINE_ACTION, pEngineState->command.action, TRUE);
561
+ ExitOnFailure(hr, "Failed to set command line action variable.");
562
563
hr = RegistrationSetVariables(&pEngineState->registration, &pEngineState->variables);
564
ExitOnFailure(hr, "Failed to set registration variables.");
src/burn/engine/plan.cpp
+3
@@ -147,6 +147,7 @@ static BOOL ForceCache(
147
148
extern "C" void PlanReset(
149
__in BURN_PLAN* pPlan,
150
+ __in BURN_VARIABLES* pVariables,
151
__in BURN_CONTAINERS* pContainers,
152
__in BURN_PACKAGES* pPackages,
153
__in BURN_PAYLOAD_GROUP* pLayoutPayloads
@@ -274,6 +275,8 @@ extern "C" void PlanReset(
275
ResetPlannedRollbackBoundaryState(&pPackages->rgRollbackBoundaries[i]);
276
}
277
}
278
+
279
+ PlanSetVariables(BOOTSTRAPPER_ACTION_UNKNOWN, pVariables);
280
}
281
282
extern "C" void PlanUninitializeExecuteAction(
src/burn/engine/plan.h
+1
@@ -306,6 +306,7 @@ typedef struct _BURN_PLAN
306
307
void PlanReset(
308
__in BURN_PLAN* pPlan,
309
+ __in BURN_VARIABLES* pVariables,
310
__in BURN_CONTAINERS* pContainers,
311
__in BURN_PACKAGES* pPackages,
312
__in BURN_PAYLOAD_GROUP* pLayoutPayloads
src/burn/engine/registration.cpp
-3
@@ -445,9 +445,6 @@ extern "C" HRESULT RegistrationSetVariables(
445
HRESULT hr = S_OK;
446
LPWSTR scz = NULL;
447
448
- hr = RegistrationSetDynamicVariables(pRegistration, pVariables);
449
- ExitOnFailure(hr, "Failed to set the dynamic registration variables.");
450
-
448
// Ensure the registration bundle name is updated.
449
hr = GetBundleInProgressName(pRegistration, pVariables, &scz);
450
ExitOnFailure(hr, "Failed to initialize bundle name.");
src/burn/engine/variable.cpp
+1
@@ -268,6 +268,7 @@ extern "C" HRESULT VariableInitialize(
268
{L"WindowsFolder", InitializeVariableCsidlFolder, CSIDL_WINDOWS},
269
{L"WindowsVolume", InitializeVariableWindowsVolumeFolder, 0},
270
{BURN_BUNDLE_ACTION, InitializeVariableNumeric, 0, FALSE, TRUE},
271
+ {BURN_BUNDLE_COMMAND_LINE_ACTION, InitializeVariableNumeric, 0, FALSE, TRUE},
272
{BURN_BUNDLE_EXECUTE_PACKAGE_CACHE_FOLDER, InitializeVariableString, NULL, FALSE, TRUE},
273
{BURN_BUNDLE_EXECUTE_PACKAGE_ACTION, InitializeVariableString, NULL, FALSE, TRUE},
274
{BURN_BUNDLE_FORCED_RESTART_PACKAGE, InitializeVariableString, NULL, TRUE, TRUE},
src/burn/test/BurnUnitTest/PlanTest.cpp
+1
-1
@@ -2040,7 +2040,7 @@ namespace Bootstrapper
2040
void PlanTestDetect(BURN_ENGINE_STATE* pEngineState)
2041
{
2042
DetectReset(&pEngineState->registration, &pEngineState->packages);
2043
- PlanReset(&pEngineState->plan, &pEngineState->containers, &pEngineState->packages, &pEngineState->layoutPayloads);
2043
+ PlanReset(&pEngineState->plan, &pEngineState->variables, &pEngineState->containers, &pEngineState->packages, &pEngineState->layoutPayloads);
2044
2045
pEngineState->userExperience.fEngineActive = TRUE;
2046
pEngineState->fDetected = TRUE;
src/burn/test/BurnUnitTest/RegistrationTest.cpp
+5
-2
@@ -313,6 +313,9 @@ namespace Bootstrapper
313
plan.pCommand = &command;
314
plan.pInternalCommand = &internalCommand;
315
316
+ hr = RegistrationSetVariables(®istration, &variables);
317
+ TestThrowOnFailure(hr, L"Failed to set registration variables.");
318
+
319
hr = PlanSetResumeCommand(&plan, ®istration, &logging);
320
TestThrowOnFailure(hr, L"Failed to set registration resume command.");
321
@@ -339,8 +342,8 @@ namespace Bootstrapper
342
this->ValidateUninstallKeyDisplayName(L"Product1");
343
registration.detectedRegistrationType = BOOTSTRAPPER_REGISTRATION_TYPE_FULL;
344
342
- hr = RegistrationSetVariables(®istration, &variables);
343
- TestThrowOnFailure(hr, L"Failed to set registration variables.");
345
+ hr = RegistrationSetDynamicVariables(®istration, &variables);
346
+ TestThrowOnFailure(hr, L"Failed to set dynamic registration variables.");
347
348
Assert::Equal(1ll, VariableGetNumericHelper(&variables, BURN_BUNDLE_INSTALLED));
349
Assert::Equal<String^>(gcnew String(L"foo"), VariableGetStringHelper(&variables, BURN_BUNDLE_TAG));
src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp
+58
-45
@@ -242,6 +242,60 @@ public: // IBootstrapperApplication
242
return hr;
243
}
244
245
+ virtual STDMETHODIMP OnDetectBegin(
246
+ __in BOOL fCached,
247
+ __in BOOTSTRAPPER_REGISTRATION_TYPE registrationType,
248
+ __in DWORD cPackages,
249
+ __inout BOOL* pfCancel
250
+ )
251
+ {
252
+ HRESULT hr = S_OK;
253
+ BOOL fInstalled = BOOTSTRAPPER_REGISTRATION_TYPE_FULL == registrationType;
254
+
255
+ if (m_fPrereq)
256
+ {
257
+ // Pre-req BA should only show help or do an install (to launch the Managed BA which can then do the right action).
258
+ if (BOOTSTRAPPER_ACTION_HELP != m_command.action)
259
+ {
260
+ m_command.action = BOOTSTRAPPER_ACTION_INSTALL;
261
+ }
262
+ }
263
+ else // maybe modify the action state if the bundle is or is not already installed.
264
+ {
265
+ if (fInstalled && BOOTSTRAPPER_RESUME_TYPE_REBOOT != m_command.resumeType && BOOTSTRAPPER_ACTION_INSTALL == m_command.action)
266
+ {
267
+ m_command.action = BOOTSTRAPPER_ACTION_MODIFY;
268
+ }
269
+ else if (!fInstalled && (BOOTSTRAPPER_ACTION_MODIFY == m_command.action || BOOTSTRAPPER_ACTION_REPAIR == m_command.action))
270
+ {
271
+ m_command.action = BOOTSTRAPPER_ACTION_INSTALL;
272
+ }
273
+ }
274
+
275
+ // When resuming from restart doing some install-like operation, try to find the package that forced the
276
+ // restart. We'll use this information during planning.
277
+ if (BOOTSTRAPPER_RESUME_TYPE_REBOOT == m_command.resumeType && BOOTSTRAPPER_ACTION_UNINSTALL < m_command.action)
278
+ {
279
+ // Ensure the forced restart package variable is null when it is an empty string.
280
+ hr = BalGetStringVariable(L"WixBundleForcedRestartPackage", &m_sczAfterForcedRestartPackage);
281
+ if (FAILED(hr) || !m_sczAfterForcedRestartPackage || !*m_sczAfterForcedRestartPackage)
282
+ {
283
+ ReleaseNullStr(m_sczAfterForcedRestartPackage);
284
+ }
285
+
286
+ hr = S_OK;
287
+ }
288
+
289
+ // If the UI should be visible, display it now and hide the splash screen
290
+ if (BOOTSTRAPPER_DISPLAY_NONE < m_command.display)
291
+ {
292
+ ::ShowWindow(m_pTheme->hwndParent, SW_SHOW);
293
+ }
294
+
295
+ m_pEngine->CloseSplashScreen();
296
+
297
+ return __super::OnDetectBegin(fCached, registrationType, cPackages, pfCancel);
298
+ }
299
300
virtual STDMETHODIMP OnDetectRelatedBundle(
301
__in LPCWSTR wzBundleId,
@@ -2123,7 +2177,6 @@ public: //CBalBaseBootstrapperApplication
2177
)
2178
{
2179
HRESULT hr = S_OK;
2126
- LONGLONG llInstalled = 0;
2180
2181
hr = __super::Initialize(pCreateArgs);
2182
BalExitOnFailure(hr, "CBalBaseBootstrapperApplication initialization failed.");
@@ -2132,39 +2185,6 @@ public: //CBalBaseBootstrapperApplication
2185
memcpy_s(&m_createArgs, sizeof(m_createArgs), pCreateArgs, sizeof(BOOTSTRAPPER_CREATE_ARGS));
2186
m_createArgs.pCommand = &m_command;
2187
2135
- if (m_fPrereq)
2136
- {
2137
- // Pre-req BA should only show help or do an install (to launch the Managed BA which can then do the right action).
2138
- if (BOOTSTRAPPER_ACTION_HELP != m_command.action)
2139
- {
2140
- m_command.action = BOOTSTRAPPER_ACTION_INSTALL;
2141
- }
2142
- }
2143
- else // maybe modify the action state if the bundle is or is not already installed.
2144
- {
2145
- hr = BalGetNumericVariable(L"WixBundleInstalled", &llInstalled);
2146
- if (SUCCEEDED(hr) && BOOTSTRAPPER_RESUME_TYPE_REBOOT != m_command.resumeType && llInstalled && BOOTSTRAPPER_ACTION_INSTALL == m_command.action)
2147
- {
2148
- m_command.action = BOOTSTRAPPER_ACTION_MODIFY;
2149
- }
2150
- else if (!llInstalled && (BOOTSTRAPPER_ACTION_MODIFY == m_command.action || BOOTSTRAPPER_ACTION_REPAIR == m_command.action))
2151
- {
2152
- m_command.action = BOOTSTRAPPER_ACTION_INSTALL;
2153
- }
2154
- }
2155
-
2156
- // When resuming from restart doing some install-like operation, try to find the package that forced the
2157
- // restart. We'll use this information during planning.
2158
- if (BOOTSTRAPPER_RESUME_TYPE_REBOOT == m_command.resumeType && BOOTSTRAPPER_ACTION_UNINSTALL < m_command.action)
2159
- {
2160
- // Ensure the forced restart package variable is null when it is an empty string.
2161
- hr = BalGetStringVariable(L"WixBundleForcedRestartPackage", &m_sczAfterForcedRestartPackage);
2162
- if (FAILED(hr) || !m_sczAfterForcedRestartPackage || !*m_sczAfterForcedRestartPackage)
2163
- {
2164
- ReleaseNullStr(m_sczAfterForcedRestartPackage);
2165
- }
2166
- }
2167
-
2188
hr = BalGetStringVariable(L"WixBundleVersion", &m_sczBundleVersion);
2189
BalExitOnFailure(hr, "CWixStandardBootstrapperApplication initialization failed.");
2190
@@ -2320,7 +2340,7 @@ private:
2340
BalExitOnFailure(hr, "Failed to read bootstrapper application data.");
2341
}
2342
2323
- if (BOOTSTRAPPER_ACTION_CACHE == m_plannedAction)
2343
+ if (m_fRequestedCacheOnly)
2344
{
2345
if (m_fSupportCacheOnly)
2346
{
@@ -2335,7 +2355,6 @@ private:
2355
else
2356
{
2357
BalLog(BOOTSTRAPPER_LOG_LEVEL_ERROR, "Ignoring attempt to only cache a bundle that does not explicitly support it.");
2338
- m_plannedAction = BOOTSTRAPPER_ACTION_UNKNOWN;
2358
}
2359
}
2360
@@ -2385,7 +2404,7 @@ private:
2404
}
2405
else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, L"cache", -1))
2406
{
2388
- m_plannedAction = BOOTSTRAPPER_ACTION_CACHE;
2407
+ m_fRequestedCacheOnly = TRUE;
2408
}
2409
else
2410
{
@@ -3227,14 +3246,6 @@ private:
3246
3247
SetState(WIXSTDBA_STATE_DETECTING, hr);
3248
3230
- // If the UI should be visible, display it now and hide the splash screen
3231
- if (BOOTSTRAPPER_DISPLAY_NONE < m_command.display)
3232
- {
3233
- ::ShowWindow(m_pTheme->hwndParent, SW_SHOW);
3234
- }
3235
-
3236
- m_pEngine->CloseSplashScreen();
3237
-
3249
// Tell the core we're ready for the packages to be processed now.
3250
hr = m_pEngine->Detect();
3251
BalExitOnFailure(hr, "Failed to start detecting chain.");
@@ -4232,6 +4243,7 @@ public:
4243
m_fSuppressDowngradeFailure = FALSE;
4244
m_fSuppressRepair = FALSE;
4245
m_fSupportCacheOnly = FALSE;
4246
+ m_fRequestedCacheOnly = FALSE;
4247
4248
m_pTaskbarList = NULL;
4249
m_uTaskbarButtonCreatedMessage = UINT_MAX;
@@ -4536,6 +4548,7 @@ private:
4548
BOOL m_fSuppressDowngradeFailure;
4549
BOOL m_fSuppressRepair;
4550
BOOL m_fSupportCacheOnly;
4551
+ BOOL m_fRequestedCacheOnly;
4552
4553
BOOL m_fPrereq;
4554
BOOL m_fPrereqInstalled;
src/wix/WixToolset.Core/CompilerCore.cs
+1
@@ -94,6 +94,7 @@ namespace WixToolset.Core
94
"WindowsFolder",
95
"WindowsVolume",
96
"WixBundleAction",
97
+ "WixBundleCommandLineAction",
98
"WixBundleForcedRestartPackage",
99
"WixBundleElevated",
100
"WixBundleInstalled",