@joebigelow / wix-1 / commits / 8c9ca787

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(&registration, &variables);
317 + TestThrowOnFailure(hr, L"Failed to set registration variables.");
318 +
319 hr = PlanSetResumeCommand(&plan, &registration, &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(&registration, &variables);
343 - TestThrowOnFailure(hr, L"Failed to set registration variables.");
345 + hr = RegistrationSetDynamicVariables(&registration, &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",