Add `ExePackage/@Bundle` to opt-in to v3 behavior. Automatically add '-norestart' for bundle ExePackages.
Add `ExePackage/@Bundle` to opt-in to v3 behavior. Automatically add '-norestart' for bundle ExePackages. Fixes 6252
Sean Hall committed
Mar 21, 2022 at 23:22 UTC
fc3e4722307c86b5d06918f0721b98323735bb40
16 files changed
+233
-40
src/api/wix/WixToolset.Data/Symbols/WixBundleExePackageSymbol.cs
+3
@@ -39,6 +39,7 @@ namespace WixToolset.Data.Symbols
39
public enum WixBundleExePackageAttributes
40
{
41
None = 0,
42
+ Bundle = 1,
43
}
44
45
public class WixBundleExePackageSymbol : IntermediateSymbol
@@ -89,6 +90,8 @@ namespace WixToolset.Data.Symbols
90
set => this.Set((int)WixBundleExePackageSymbolFields.ExeProtocol, value);
91
}
92
93
+ public bool IsBundle => this.Attributes.HasFlag(WixBundleExePackageAttributes.Bundle);
94
+
95
public bool Repairable => this.RepairCommand != null;
96
97
public bool Uninstallable => this.UninstallCommand != null;
src/burn/engine/core.cpp
+5
@@ -234,6 +234,11 @@ extern "C" HRESULT CoreInitializeConstants(
234
pPackage->Bundle.wzAncestors = pRegistration->sczBundlePackageAncestors;
235
pPackage->Bundle.wzEngineWorkingDirectory = pInternalCommand->sczEngineWorkingDirectory;
236
}
237
+ else if (BURN_PACKAGE_TYPE_EXE == pPackage->type && pPackage->Exe.fBundle)
238
+ {
239
+ pPackage->Exe.wzAncestors = pRegistration->sczBundlePackageAncestors;
240
+ pPackage->Exe.wzEngineWorkingDirectory = pInternalCommand->sczEngineWorkingDirectory;
241
+ }
242
}
243
244
LExit:
src/burn/engine/elevation.cpp
+44
@@ -940,6 +940,15 @@ extern "C" HRESULT ElevationExecuteExePackage(
940
hr = BuffWriteNumber(&pbData, &cbData, fRollback);
941
ExitOnFailure(hr, "Failed to write rollback.");
942
943
+ hr = BuffWriteString(&pbData, &cbData, pExecuteAction->exePackage.sczIgnoreDependencies);
944
+ ExitOnFailure(hr, "Failed to write the list of dependencies to ignore to the message buffer.");
945
+
946
+ hr = BuffWriteString(&pbData, &cbData, pExecuteAction->exePackage.sczAncestors);
947
+ ExitOnFailure(hr, "Failed to write the list of ancestors to the message buffer.");
948
+
949
+ hr = BuffWriteString(&pbData, &cbData, pExecuteAction->exePackage.sczEngineWorkingDirectory);
950
+ ExitOnFailure(hr, "Failed to write the custom working directory to the message buffer.");
951
+
952
hr = VariableSerialize(pVariables, FALSE, &pbData, &cbData);
953
ExitOnFailure(hr, "Failed to write variables.");
954
@@ -2844,6 +2853,9 @@ static HRESULT OnExecuteExePackage(
2853
LPWSTR sczPackage = NULL;
2854
DWORD dwRollback = 0;
2855
BURN_EXECUTE_ACTION executeAction = { };
2856
+ LPWSTR sczIgnoreDependencies = NULL;
2857
+ LPWSTR sczAncestors = NULL;
2858
+ LPWSTR sczEngineWorkingDirectory = NULL;
2859
BOOTSTRAPPER_APPLY_RESTART exeRestart = BOOTSTRAPPER_APPLY_RESTART_NONE;
2860
2861
executeAction.type = BURN_EXECUTE_ACTION_TYPE_EXE_PACKAGE;
@@ -2858,6 +2870,15 @@ static HRESULT OnExecuteExePackage(
2870
hr = BuffReadNumber(pbData, cbData, &iData, &dwRollback);
2871
ExitOnFailure(hr, "Failed to read rollback.");
2872
2873
+ hr = BuffReadString(pbData, cbData, &iData, &sczIgnoreDependencies);
2874
+ ExitOnFailure(hr, "Failed to read the list of dependencies to ignore.");
2875
+
2876
+ hr = BuffReadString(pbData, cbData, &iData, &sczAncestors);
2877
+ ExitOnFailure(hr, "Failed to read the list of ancestors.");
2878
+
2879
+ hr = BuffReadString(pbData, cbData, &iData, &sczEngineWorkingDirectory);
2880
+ ExitOnFailure(hr, "Failed to read the custom working directory.");
2881
+
2882
hr = VariableDeserialize(pVariables, FALSE, pbData, cbData, &iData);
2883
ExitOnFailure(hr, "Failed to read variables.");
2884
@@ -2869,11 +2890,34 @@ static HRESULT OnExecuteExePackage(
2890
ExitWithRootFailure(hr, E_INVALIDARG, "Package is not an EXE package: %ls", sczPackage);
2891
}
2892
2893
+ // Pass the list of dependencies to ignore, if any, to the related bundle.
2894
+ if (sczIgnoreDependencies && *sczIgnoreDependencies)
2895
+ {
2896
+ hr = StrAllocString(&executeAction.exePackage.sczIgnoreDependencies, sczIgnoreDependencies, 0);
2897
+ ExitOnFailure(hr, "Failed to allocate the list of dependencies to ignore.");
2898
+ }
2899
+
2900
+ // Pass the list of ancestors, if any, to the related bundle.
2901
+ if (sczAncestors && *sczAncestors)
2902
+ {
2903
+ hr = StrAllocString(&executeAction.exePackage.sczAncestors, sczAncestors, 0);
2904
+ ExitOnFailure(hr, "Failed to allocate the list of ancestors.");
2905
+ }
2906
+
2907
+ if (sczEngineWorkingDirectory && *sczEngineWorkingDirectory)
2908
+ {
2909
+ hr = StrAllocString(&executeAction.exePackage.sczEngineWorkingDirectory, sczEngineWorkingDirectory, 0);
2910
+ ExitOnFailure(hr, "Failed to allocate the custom working directory.");
2911
+ }
2912
+
2913
// Execute EXE package.
2914
hr = ExeEngineExecutePackage(&executeAction, pCache, pVariables, static_cast<BOOL>(dwRollback), GenericExecuteMessageHandler, hPipe, &exeRestart);
2915
ExitOnFailure(hr, "Failed to execute EXE package.");
2916
2917
LExit:
2918
+ ReleaseStr(sczEngineWorkingDirectory);
2919
+ ReleaseStr(sczAncestors);
2920
+ ReleaseStr(sczIgnoreDependencies);
2921
ReleaseStr(sczPackage);
2922
PlanUninitializeExecuteAction(&executeAction);
2923
src/burn/engine/exeengine.cpp
+79
-12
@@ -40,6 +40,10 @@ extern "C" HRESULT ExeEngineParsePackageFromXml(
40
hr = XmlGetYesNoAttribute(pixnExePackage, L"Uninstallable", &pPackage->Exe.fUninstallable);
41
ExitOnOptionalXmlQueryFailure(hr, fFoundXml, "Failed to get @Uninstallable.");
42
43
+ // @Bundle
44
+ hr = XmlGetYesNoAttribute(pixnExePackage, L"Bundle", &pPackage->Exe.fBundle);
45
+ ExitOnOptionalXmlQueryFailure(hr, fFoundXml, "Failed to get @Bundle.");
46
+
47
// @Protocol
48
hr = XmlGetAttributeEx(pixnExePackage, L"Protocol", &scz);
49
ExitOnOptionalXmlQueryFailure(hr, fFoundXml, "Failed to get @Protocol.");
@@ -87,6 +91,7 @@ extern "C" void ExeEnginePackageUninitialize(
91
ReleaseStr(pPackage->Exe.sczInstallArguments);
92
ReleaseStr(pPackage->Exe.sczRepairArguments);
93
ReleaseStr(pPackage->Exe.sczUninstallArguments);
94
+ ReleaseStr(pPackage->Exe.sczIgnoreDependencies);
95
ReleaseMem(pPackage->Exe.rgExitCodes);
96
97
// free command-line arguments
@@ -286,6 +291,24 @@ extern "C" HRESULT ExeEnginePlanAddPackage(
291
pAction->exePackage.pPackage = pPackage;
292
pAction->exePackage.action = pPackage->rollback;
293
294
+ if (pPackage->Exe.sczIgnoreDependencies)
295
+ {
296
+ hr = StrAllocString(&pAction->exePackage.sczIgnoreDependencies, pPackage->Exe.sczIgnoreDependencies, 0);
297
+ ExitOnFailure(hr, "Failed to allocate the list of dependencies to ignore.");
298
+ }
299
+
300
+ if (pPackage->Exe.wzAncestors)
301
+ {
302
+ hr = StrAllocString(&pAction->exePackage.sczAncestors, pPackage->Exe.wzAncestors, 0);
303
+ ExitOnFailure(hr, "Failed to allocate the list of ancestors.");
304
+ }
305
+
306
+ if (pPackage->Exe.wzEngineWorkingDirectory)
307
+ {
308
+ hr = StrAllocString(&pAction->exePackage.sczEngineWorkingDirectory, pPackage->Exe.wzEngineWorkingDirectory, 0);
309
+ ExitOnFailure(hr, "Failed to allocate the custom working directory.");
310
+ }
311
+
312
LoggingSetPackageVariable(pPackage, NULL, TRUE, pLog, pVariables, NULL); // ignore errors.
313
314
hr = PlanExecuteCheckpoint(pPlan);
@@ -302,6 +325,24 @@ extern "C" HRESULT ExeEnginePlanAddPackage(
325
pAction->exePackage.pPackage = pPackage;
326
pAction->exePackage.action = pPackage->execute;
327
328
+ if (pPackage->Exe.sczIgnoreDependencies)
329
+ {
330
+ hr = StrAllocString(&pAction->exePackage.sczIgnoreDependencies, pPackage->Exe.sczIgnoreDependencies, 0);
331
+ ExitOnFailure(hr, "Failed to allocate the list of dependencies to ignore.");
332
+ }
333
+
334
+ if (pPackage->Exe.wzAncestors)
335
+ {
336
+ hr = StrAllocString(&pAction->exePackage.sczAncestors, pPackage->Exe.wzAncestors, 0);
337
+ ExitOnFailure(hr, "Failed to allocate the list of ancestors.");
338
+ }
339
+
340
+ if (pPackage->Exe.wzEngineWorkingDirectory)
341
+ {
342
+ hr = StrAllocString(&pAction->exePackage.sczEngineWorkingDirectory, pPackage->Exe.wzEngineWorkingDirectory, 0);
343
+ ExitOnFailure(hr, "Failed to allocate the custom working directory.");
344
+ }
345
+
346
LoggingSetPackageVariable(pPackage, NULL, FALSE, pLog, pVariables, NULL); // ignore errors.
347
}
348
@@ -406,27 +447,53 @@ extern "C" HRESULT ExeEngineExecutePackage(
447
}
448
449
// build command
409
- if (*sczArguments)
450
+ AppAppendCommandLineArgument(&sczCommand, sczExecutablePath);
451
+ ExitOnFailure(hr, "Failed to create executable command.");
452
+
453
+ if (pPackage->Exe.fBundle)
454
+ {
455
+ hr = StrAllocConcat(&sczCommand, L" -norestart", 0);
456
+ ExitOnFailure(hr, "Failed to append quiet argument.");
457
+
458
+ // Add the list of dependencies to ignore, if any, to the burn command line.
459
+ if (pExecuteAction->exePackage.sczIgnoreDependencies)
460
+ {
461
+ hr = StrAllocConcatFormatted(&sczCommand, L" -%ls=%ls", BURN_COMMANDLINE_SWITCH_IGNOREDEPENDENCIES, pExecuteAction->exePackage.sczIgnoreDependencies);
462
+ ExitOnFailure(hr, "Failed to append the list of dependencies to ignore to the command line.");
463
+ }
464
+
465
+ // Add the list of ancestors, if any, to the burn command line.
466
+ if (pExecuteAction->exePackage.sczAncestors)
467
+ {
468
+ hr = StrAllocConcatFormatted(&sczCommand, L" -%ls=%ls", sczCommand, BURN_COMMANDLINE_SWITCH_ANCESTORS, pExecuteAction->exePackage.sczAncestors);
469
+ ExitOnFailure(hr, "Failed to append the list of ancestors to the command line.");
470
+ }
471
+
472
+ if (pExecuteAction->exePackage.sczEngineWorkingDirectory)
473
+ {
474
+ hr = CoreAppendEngineWorkingDirectoryToCommandLine(pExecuteAction->exePackage.sczEngineWorkingDirectory, &sczCommand, NULL);
475
+ ExitOnFailure(hr, "Failed to append the custom working directory to the exepackage command line.");
476
+ }
477
+
478
+ hr = CoreAppendFileHandleSelfToCommandLine(sczExecutablePath, &hExecutableFile, &sczCommand, NULL);
479
+ ExitOnFailure(hr, "Failed to append %ls", BURN_COMMANDLINE_SWITCH_FILEHANDLE_SELF);
480
+ }
481
+
482
+ // Always add user supplied arguments last.
483
+ if (sczArguments && *sczArguments)
484
{
485
hr = VariableFormatString(pVariables, sczArguments, &sczArgumentsFormatted, NULL);
486
ExitOnFailure(hr, "Failed to format argument string.");
487
414
- hr = StrAllocFormattedSecure(&sczCommand, L"\"%ls\" %ls", sczExecutablePath, sczArgumentsFormatted);
415
- ExitOnFailure(hr, "Failed to create executable command.");
416
-
488
hr = VariableFormatStringObfuscated(pVariables, sczArguments, &sczArgumentsObfuscated, NULL);
489
ExitOnFailure(hr, "Failed to format obfuscated argument string.");
490
420
- hr = StrAllocFormatted(&sczCommandObfuscated, L"\"%ls\" %ls", sczExecutablePath, sczArgumentsObfuscated);
421
- }
422
- else
423
- {
424
- hr = StrAllocFormatted(&sczCommand, L"\"%ls\"", sczExecutablePath);
425
- ExitOnFailure(hr, "Failed to create executable command.");
491
+ hr = StrAllocFormatted(&sczCommandObfuscated, L"%ls %ls", sczCommand, sczArgumentsObfuscated);
492
+ ExitOnFailure(hr, "Failed to copy obfuscated formatted arguments.");
493
427
- hr = StrAllocFormatted(&sczCommandObfuscated, L"\"%ls\"", sczExecutablePath);
494
+ hr = StrAllocConcatFormattedSecure(&sczCommand, L" %ls", sczArgumentsFormatted);
495
+ ExitOnFailure(hr, "Failed to copy formatted arguments.");
496
}
429
- ExitOnFailure(hr, "Failed to create obfuscated executable command.");
497
498
// Log before we add the secret pipe name and client token for embedded processes.
499
LogId(REPORT_STANDARD, MSG_APPLYING_PACKAGE, LoggingRollbackOrExecute(fRollback), pPackage->sczId, LoggingActionStateToString(pExecuteAction->exePackage.action), sczExecutablePath, sczCommandObfuscated);
src/burn/engine/package.h
+4
@@ -324,7 +324,11 @@ typedef struct _BURN_PACKAGE
324
LPWSTR sczInstallArguments;
325
LPWSTR sczRepairArguments;
326
LPWSTR sczUninstallArguments;
327
+ LPWSTR sczIgnoreDependencies;
328
+ LPCWSTR wzAncestors; // points directly into engine state.
329
+ LPCWSTR wzEngineWorkingDirectory; // points directly into engine state.
330
331
+ BOOL fBundle;
332
BOOL fPseudoPackage;
333
BOOL fFireAndForget;
334
BOOL fRepairable;
src/burn/engine/plan.cpp
+22
-11
@@ -291,6 +291,12 @@ extern "C" void PlanUninitializeExecuteAction(
291
ReleaseStr(pExecuteAction->relatedBundle.sczEngineWorkingDirectory);
292
break;
293
294
+ case BURN_EXECUTE_ACTION_TYPE_EXE_PACKAGE:
295
+ ReleaseStr(pExecuteAction->exePackage.sczIgnoreDependencies);
296
+ ReleaseStr(pExecuteAction->exePackage.sczAncestors);
297
+ ReleaseStr(pExecuteAction->exePackage.sczEngineWorkingDirectory);
298
+ break;
299
+
300
case BURN_EXECUTE_ACTION_TYPE_MSI_PACKAGE:
301
ReleaseStr(pExecuteAction->msiPackage.sczLogPath);
302
ReleaseMem(pExecuteAction->msiPackage.rgFeatures);
@@ -1495,26 +1501,21 @@ extern "C" HRESULT PlanRelatedBundlesComplete(
1501
for (DWORD i = 0; i < pPlan->cExecuteActions; ++i)
1502
{
1503
BOOTSTRAPPER_ACTION_STATE packageAction = BOOTSTRAPPER_ACTION_STATE_NONE;
1504
+ BURN_PACKAGE* pPackage = &pPlan->rgExecuteActions[i].relatedBundle.pRelatedBundle->package;
1505
+ BOOL fBundle = FALSE;
1506
1507
switch (pPlan->rgExecuteActions[i].type)
1508
{
1509
case BURN_EXECUTE_ACTION_TYPE_RELATED_BUNDLE:
1510
packageAction = pPlan->rgExecuteActions[i].relatedBundle.action;
1503
-
1504
- if (BOOTSTRAPPER_ACTION_STATE_NONE != packageAction)
1505
- {
1506
- BURN_PACKAGE* pPackage = &pPlan->rgExecuteActions[i].relatedBundle.pRelatedBundle->package;
1507
- if (pPackage->cDependencyProviders)
1508
- {
1509
- // Bundles only support a single provider key.
1510
- const BURN_DEPENDENCY_PROVIDER* pProvider = pPackage->rgDependencyProviders;
1511
- DictAddKey(sdProviderKeys, pProvider->sczKey);
1512
- }
1513
- }
1511
+ pPackage = &pPlan->rgExecuteActions[i].relatedBundle.pRelatedBundle->package;
1512
+ fBundle = TRUE;
1513
break;
1514
1515
case BURN_EXECUTE_ACTION_TYPE_EXE_PACKAGE:
1516
packageAction = pPlan->rgExecuteActions[i].exePackage.action;
1517
+ pPackage = pPlan->rgExecuteActions[i].exePackage.pPackage;
1518
+ fBundle = TRUE;
1519
break;
1520
1521
case BURN_EXECUTE_ACTION_TYPE_MSI_PACKAGE:
@@ -1530,6 +1531,16 @@ extern "C" HRESULT PlanRelatedBundlesComplete(
1531
break;
1532
}
1533
1534
+ if (fBundle && BOOTSTRAPPER_ACTION_STATE_NONE != packageAction)
1535
+ {
1536
+ if (pPackage->cDependencyProviders)
1537
+ {
1538
+ // Bundles only support a single provider key.
1539
+ const BURN_DEPENDENCY_PROVIDER* pProvider = pPackage->rgDependencyProviders;
1540
+ DictAddKey(sdProviderKeys, pProvider->sczKey);
1541
+ }
1542
+ }
1543
+
1544
fExecutingAnyPackage |= BOOTSTRAPPER_ACTION_STATE_NONE != packageAction;
1545
fInstallingAnyPackage |= BOOTSTRAPPER_ACTION_STATE_INSTALL == packageAction || BOOTSTRAPPER_ACTION_STATE_MINOR_UPGRADE == packageAction;
1546
}
src/burn/engine/plan.h
+3
@@ -164,6 +164,9 @@ typedef struct _BURN_EXECUTE_ACTION
164
{
165
BURN_PACKAGE* pPackage;
166
BOOTSTRAPPER_ACTION_STATE action;
167
+ LPWSTR sczIgnoreDependencies;
168
+ LPWSTR sczAncestors;
169
+ LPWSTR sczEngineWorkingDirectory;
170
} exePackage;
171
struct
172
{
src/burn/test/BurnUnitTest/PlanTest.cpp
+6
-4
@@ -716,7 +716,7 @@ namespace Bootstrapper
716
ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
717
ValidateExecuteWaitCachePackage(pPlan, fRollback, dwIndex++, L"ExeA");
718
ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
719
- ValidateExecuteExePackage(pPlan, fRollback, dwIndex++, L"ExeA", BOOTSTRAPPER_ACTION_STATE_INSTALL);
719
+ ValidateExecuteExePackage(pPlan, fRollback, dwIndex++, L"ExeA", BOOTSTRAPPER_ACTION_STATE_INSTALL, NULL);
720
ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
721
ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
722
ValidateExecuteRollbackBoundaryEnd(pPlan, fRollback, dwIndex++);
@@ -727,7 +727,7 @@ namespace Bootstrapper
727
dwExecuteCheckpointId = 2;
728
ValidateExecuteRollbackBoundaryStart(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE);
729
ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
730
- ValidateExecuteExePackage(pPlan, fRollback, dwIndex++, L"ExeA", BOOTSTRAPPER_ACTION_STATE_UNINSTALL);
730
+ ValidateExecuteExePackage(pPlan, fRollback, dwIndex++, L"ExeA", BOOTSTRAPPER_ACTION_STATE_UNINSTALL, NULL);
731
ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
732
ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
733
ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
@@ -2125,7 +2125,7 @@ namespace Bootstrapper
2125
ValidateExecuteRollbackBoundaryStart(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE);
2126
ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
2127
ValidateExecuteWaitCachePackage(pPlan, fRollback, dwIndex++, L"NetFx48Web");
2128
- ValidateExecuteExePackage(pPlan, fRollback, dwIndex++, L"NetFx48Web", BOOTSTRAPPER_ACTION_STATE_INSTALL);
2128
+ ValidateExecuteExePackage(pPlan, fRollback, dwIndex++, L"NetFx48Web", BOOTSTRAPPER_ACTION_STATE_INSTALL, NULL);
2129
ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
2130
dwExecuteCheckpointId += 1; // cache checkpoints
2131
ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
@@ -2683,13 +2683,15 @@ namespace Bootstrapper
2683
__in BOOL fRollback,
2684
__in DWORD dwIndex,
2685
__in LPCWSTR wzPackageId,
2686
- __in BOOTSTRAPPER_ACTION_STATE action
2686
+ __in BOOTSTRAPPER_ACTION_STATE action,
2687
+ __in LPCWSTR wzIgnoreDependencies
2688
)
2689
{
2690
BURN_EXECUTE_ACTION* pAction = ValidateExecuteActionExists(pPlan, fRollback, dwIndex);
2691
Assert::Equal<DWORD>(BURN_EXECUTE_ACTION_TYPE_EXE_PACKAGE, pAction->type);
2692
NativeAssert::StringEqual(wzPackageId, pAction->exePackage.pPackage->sczId);
2693
Assert::Equal<DWORD>(action, pAction->exePackage.action);
2694
+ NativeAssert::StringEqual(wzIgnoreDependencies, pAction->exePackage.sczIgnoreDependencies);
2695
Assert::Equal<BOOL>(FALSE, pAction->fDeleted);
2696
}
2697
src/ext/NetFx/wixlib/NetCore3.1.12_x64.wxs
+2
-2
@@ -20,7 +20,7 @@
20
<WixVariable Id="AspNetCoreRuntime$(var.NetCoreIdVersion)Redist$(var.NetCorePlatform)RepairArguments" Value="" Overridable="yes" />
21
22
<PackageGroup Id="$(var.AspNetCoreRedistId)">
23
- <ExePackage InstallArguments="$(var.AspNetCoreRedistInstallArguments)" PerMachine="yes" DetectCondition="!(wix.AspNetCoreRuntime$(var.NetCoreIdVersion)Redist$(var.NetCorePlatform)DetectCondition)" InstallCondition="!(wix.AspNetCoreRuntime$(var.NetCoreIdVersion)Redist$(var.NetCorePlatform)InstallCondition)" Id="$(var.AspNetCoreRedistId)" Vital="yes" Permanent="yes" Protocol="burn" LogPathVariable="$(var.AspNetCoreRedistLog)" Cache="remove">
23
+ <ExePackage InstallArguments="$(var.AspNetCoreRedistInstallArguments)" PerMachine="yes" DetectCondition="!(wix.AspNetCoreRuntime$(var.NetCoreIdVersion)Redist$(var.NetCorePlatform)DetectCondition)" InstallCondition="!(wix.AspNetCoreRuntime$(var.NetCoreIdVersion)Redist$(var.NetCorePlatform)InstallCondition)" Id="$(var.AspNetCoreRedistId)" Vital="yes" Permanent="yes" Bundle="yes" LogPathVariable="$(var.AspNetCoreRedistLog)" Cache="remove">
24
<ExePackagePayload Name="!(wix.AspNetCoreRuntime$(var.NetCoreIdVersion)Redist$(var.NetCorePlatform)PackageDirectory)aspnetcore-runtime-$(var.NetCoreVersion)-win-$(var.NetCorePlatform).exe" DownloadUrl="$(var.AspNetCoreRedistLink)" ProductName="Microsoft ASP.NET Core 3.1.12 - Shared Framework" Description="Microsoft ASP.NET Core 3.1.12 - Shared Framework" CertificatePublicKey="3756E9BBF4461DCD0AA68E0D1FCFFA9CEA47AC18" CertificateThumbprint="2485A7AFA98E178CB8F30C9838346B514AEA4769" Hash="5CE9839CAE90FB2936033431F2905E97C7DC080DC50108D58714939CCCC6A265694B8259A3BF742A68BF04D9CFFB0602B0306DD401C4CE644BDB96C7D1168E59" Size="7841808" Version="3.1.12.21070" />
25
</ExePackage>
26
</PackageGroup>
@@ -35,7 +35,7 @@
35
<WixVariable Id="DesktopNetCoreRuntime$(var.NetCoreIdVersion)Redist$(var.NetCorePlatform)RepairArguments" Value="" Overridable="yes" />
36
37
<PackageGroup Id="$(var.DesktopNetCoreRedistId)">
38
- <ExePackage InstallArguments="$(var.DesktopNetCoreRedistInstallArguments)" PerMachine="yes" DetectCondition="!(wix.DesktopNetCoreRuntime$(var.NetCoreIdVersion)Redist$(var.NetCorePlatform)DetectCondition)" InstallCondition="!(wix.DesktopNetCoreRuntime$(var.NetCoreIdVersion)Redist$(var.NetCorePlatform)InstallCondition)" Id="$(var.DesktopNetCoreRedistId)" Vital="yes" Permanent="yes" Protocol="burn" LogPathVariable="$(var.DesktopNetCoreRedistLog)" Cache="remove">
38
+ <ExePackage InstallArguments="$(var.DesktopNetCoreRedistInstallArguments)" PerMachine="yes" DetectCondition="!(wix.DesktopNetCoreRuntime$(var.NetCoreIdVersion)Redist$(var.NetCorePlatform)DetectCondition)" InstallCondition="!(wix.DesktopNetCoreRuntime$(var.NetCoreIdVersion)Redist$(var.NetCorePlatform)InstallCondition)" Id="$(var.DesktopNetCoreRedistId)" Vital="yes" Permanent="yes" Bundle="yes" LogPathVariable="$(var.DesktopNetCoreRedistLog)" Cache="remove">
39
<ExePackagePayload Name="!(wix.DesktopNetCoreRuntime$(var.NetCoreIdVersion)Redist$(var.NetCorePlatform)PackageDirectory)windowsdesktop-runtime-$(var.NetCoreVersion)-win-$(var.NetCorePlatform).exe" DownloadUrl="$(var.DesktopNetCoreRedistLink)" ProductName="Microsoft Windows Desktop Runtime - 3.1.12 (x64)" Description="Microsoft Windows Desktop Runtime - 3.1.12 (x64)" CertificatePublicKey="3756E9BBF4461DCD0AA68E0D1FCFFA9CEA47AC18" CertificateThumbprint="2485A7AFA98E178CB8F30C9838346B514AEA4769" Hash="CD69B8722B2FF175FADD6774AB6A97F89292FC57A15CEC95218E79FFF1E26F46A7EFFFB15CE0F6D22B83B991F7083BB5C04F5158F87D298EA0F204933F8ECD27" Size="54284816" Version="3.1.12.29719" />
40
</ExePackage>
41
</PackageGroup>
src/ext/NetFx/wixlib/NetCore3_Platform.wxi
+6
-6
@@ -6,20 +6,20 @@
6
<?define AspNetCoreId = ASPNETCORERUNTIME$(var.NetCoreIdVersion)_$(var.NetCorePlatform)?>
7
<?define AspNetCoreRedistId = AspNetCoreRuntime$(var.NetCoreIdVersion)Redist_$(var.NetCorePlatform)?>
8
<?define AspNetCoreRedistLog = AspNetCoreRuntime$(var.NetCoreIdVersion)RedistLog?>
9
- <?define AspNetCoreRedistInstallArguments = /install /quiet /norestart /log "[$(var.AspNetCoreRedistLog)]"?>
10
- <?define AspNetCoreRedistUninstallArguments = /uninstall /quiet /norestart /log "[$(var.AspNetCoreRedistLog)]"?>
9
+ <?define AspNetCoreRedistInstallArguments = /install /quiet /log "[$(var.AspNetCoreRedistLog)]"?>
10
+ <?define AspNetCoreRedistUninstallArguments = /uninstall /quiet /log "[$(var.AspNetCoreRedistLog)]"?>
11
12
<?define DesktopNetCoreId = DESKTOPNETCORERUNTIME$(var.NetCoreIdVersion)_$(var.NetCorePlatform)?>
13
<?define DesktopNetCoreRedistId = DesktopNetCoreRuntime$(var.NetCoreIdVersion)Redist_$(var.NetCorePlatform)?>
14
<?define DesktopNetCoreRedistLog = DesktopNetCoreRuntime$(var.NetCoreIdVersion)RedistLog?>
15
- <?define DesktopNetCoreRedistInstallArguments = /install /quiet /norestart /log "[$(var.DesktopNetCoreRedistLog)]"?>
16
- <?define DesktopNetCoreRedistUninstallArguments = /uninstall /quiet /norestart /log "[$(var.DesktopNetCoreRedistLog)]"?>
15
+ <?define DesktopNetCoreRedistInstallArguments = /install /quiet /log "[$(var.DesktopNetCoreRedistLog)]"?>
16
+ <?define DesktopNetCoreRedistUninstallArguments = /uninstall /quiet /log "[$(var.DesktopNetCoreRedistLog)]"?>
17
18
<?define DotNetCoreId = DOTNETCORERUNTIME$(var.NetCoreIdVersion)_$(var.NetCorePlatform)?>
19
<?define DotNetCoreRedistId = DotNetCoreRuntime$(var.NetCoreIdVersion)Redist_$(var.NetCorePlatform)?>
20
<?define DotNetCoreRedistLog = DotNetCoreRuntime$(var.NetCoreIdVersion)RedistLog?>
21
- <?define DotNetCoreRedistInstallArguments = /install /quiet /norestart /log "[$(var.DotNetCoreRedistLog)]"?>
22
- <?define DotNetCoreRedistUninstallArguments = /uninstall /quiet /norestart /log "[$(var.DotNetCoreRedistLog)]"?>
21
+ <?define DotNetCoreRedistInstallArguments = /install /quiet /log "[$(var.DotNetCoreRedistLog)]"?>
22
+ <?define DotNetCoreRedistUninstallArguments = /uninstall /quiet /log "[$(var.DotNetCoreRedistLog)]"?>
23
24
<?define DotNetHomeId = DOTNETHOME_$(var.NetCorePlatform)?>
25
<?define NetCoreEulaLink = https://go.microsoft.com/fwlink/?LinkId=329770?>
src/wix/WixToolset.Core.Burn/Bundles/CreateBurnManifestCommand.cs
+6
@@ -389,10 +389,16 @@ namespace WixToolset.Core.Burn.Bundles
389
writer.WriteAttributeString("Uninstallable", exePackage.Uninstallable ? "yes" : "no");
390
writer.WriteAttributeString("RepairArguments", exePackage.RepairCommand);
391
writer.WriteAttributeString("Repairable", exePackage.Repairable ? "yes" : "no");
392
+
393
if (!String.IsNullOrEmpty(exePackage.ExeProtocol))
394
{
395
writer.WriteAttributeString("Protocol", exePackage.ExeProtocol);
396
}
397
+
398
+ if (exePackage.IsBundle)
399
+ {
400
+ writer.WriteAttributeString("Bundle", "yes");
401
+ }
402
}
403
else if (package.SpecificPackageSymbol is WixBundleMsiPackageSymbol msiPackage) // MSI
404
{
src/wix/WixToolset.Core/Compiler_Bundle.cs
+18
-1
@@ -1999,6 +1999,7 @@ namespace WixToolset.Core
1999
var enableFeatureSelection = YesNoType.NotSet;
2000
var forcePerMachine = YesNoType.NotSet;
2001
CompilerPayload childPackageCompilerPayload = null;
2002
+ var bundle = YesNoType.NotSet;
2003
var slipstream = YesNoType.NotSet;
2004
var hasPayloadInfo = false;
2005
@@ -2089,6 +2090,10 @@ namespace WixToolset.Core
2090
case "Vital":
2091
vital = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
2092
break;
2093
+ case "Bundle":
2094
+ bundle = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
2095
+ allowed = (packageType == WixBundlePackageType.Exe);
2096
+ break;
2097
case "InstallArguments":
2098
installArguments = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
2099
allowed = (packageType == WixBundlePackageType.Exe);
@@ -2248,12 +2253,21 @@ namespace WixToolset.Core
2253
this.Core.Write(WarningMessages.AttributeShouldContain(sourceLineNumbers, node.Name.LocalName, "UninstallArguments", uninstallArguments, expectedArgument, "Protocol", "netfx4"));
2254
}
2255
}
2256
+
2257
+ if (bundle == YesNoType.Yes)
2258
+ {
2259
+ this.Core.Write(ErrorMessages.IllegalAttributeValueWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "Protocol", protocol, "Bundle", "yes"));
2260
+ }
2261
}
2262
else if (!protocol.Equals("burn", StringComparison.Ordinal) && !protocol.Equals("none", StringComparison.Ordinal))
2263
{
2264
this.Core.Write(ErrorMessages.IllegalAttributeValueWithLegalList(sourceLineNumbers, node.Name.LocalName, "Protocol", protocol, "none, burn, netfx4"));
2265
}
2266
}
2267
+ else if (bundle == YesNoType.Yes)
2268
+ {
2269
+ protocol = "burn";
2270
+ }
2271
}
2272
else if (packageType == WixBundlePackageType.Msp)
2273
{
@@ -2409,9 +2423,12 @@ namespace WixToolset.Core
2423
switch (packageType)
2424
{
2425
case WixBundlePackageType.Exe:
2426
+ WixBundleExePackageAttributes exeAttributes = 0;
2427
+ exeAttributes |= (YesNoType.Yes == bundle) ? WixBundleExePackageAttributes.Bundle : 0;
2428
+
2429
this.Core.AddSymbol(new WixBundleExePackageSymbol(sourceLineNumbers, id)
2430
{
2414
- Attributes = WixBundleExePackageAttributes.None,
2431
+ Attributes = exeAttributes,
2432
DetectCondition = detectCondition,
2433
InstallCommand = installArguments,
2434
RepairCommand = repairArguments,
src/wix/test/WixToolsetTest.CoreIntegration/BadInputFixture.cs
+23
@@ -85,6 +85,29 @@ namespace WixToolsetTest.CoreIntegration
85
}
86
}
87
88
+ [Fact]
89
+ public void BundleExePackageWithNetfxProtocolIsRejected()
90
+ {
91
+ var folder = TestData.Get(@"TestData\BadInput");
92
+
93
+ using (var fs = new DisposableFileSystem())
94
+ {
95
+ var baseFolder = fs.GetFolder();
96
+ var intermediateFolder = Path.Combine(baseFolder, "obj");
97
+ var wixlibPath = Path.Combine(intermediateFolder, @"test.wixlib");
98
+
99
+ var result = WixRunner.Execute(new[]
100
+ {
101
+ "build",
102
+ Path.Combine(folder, "BundleExePackageWithNetfxProtocol.wxs"),
103
+ "-intermediateFolder", intermediateFolder,
104
+ "-o", wixlibPath,
105
+ });
106
+
107
+ Assert.Equal(193, result.ExitCode);
108
+ }
109
+ }
110
+
111
[Fact]
112
public void BundleVariableWithBadTypeIsRejected()
113
{
src/wix/test/WixToolsetTest.CoreIntegration/BundleManifestFixture.cs
+2
-2
@@ -354,8 +354,8 @@ namespace WixToolsetTest.CoreIntegration
354
{ "ExePackage", new List<string> { "CacheId", "InstallSize", "Size" } },
355
};
356
Assert.Equal(2, exePackageElements.Count);
357
- Assert.Equal("<ExePackage Id='credwiz.exe' Cache='keep' CacheId='*' InstallSize='*' Size='*' PerMachine='yes' Permanent='yes' Vital='yes' RollbackBoundaryForward='WixDefaultBoundary' LogPathVariable='WixBundleLog_credwiz.exe' RollbackLogPathVariable='WixBundleRollbackLog_credwiz.exe' DetectCondition='none' InstallArguments='' UninstallArguments='-foo' Uninstallable='yes' RepairArguments='' Repairable='no'><PayloadRef Id='credwiz.exe' /><PayloadRef Id='SourceFilePayload' /></ExePackage>", exePackageElements[0].GetTestXml(ignoreAttributesByElementName));
358
- Assert.Equal("<ExePackage Id='cscript.exe' Cache='keep' CacheId='*' InstallSize='*' Size='*' PerMachine='yes' Permanent='yes' Vital='yes' RollbackBoundaryBackward='WixDefaultBoundary' LogPathVariable='WixBundleLog_cscript.exe' RollbackLogPathVariable='WixBundleRollbackLog_cscript.exe' DetectCondition='none' InstallArguments='' UninstallArguments='' Uninstallable='yes' RepairArguments='' Repairable='no'><PayloadRef Id='cscript.exe' /><PayloadRef Id='SourceFilePayload' /></ExePackage>", exePackageElements[1].GetTestXml(ignoreAttributesByElementName));
357
+ Assert.Equal("<ExePackage Id='credwiz.exe' Cache='keep' CacheId='*' InstallSize='*' Size='*' PerMachine='yes' Permanent='yes' Vital='yes' RollbackBoundaryForward='WixDefaultBoundary' LogPathVariable='WixBundleLog_credwiz.exe' RollbackLogPathVariable='WixBundleRollbackLog_credwiz.exe' DetectCondition='none' InstallArguments='' UninstallArguments='-foo' Uninstallable='yes' RepairArguments='' Repairable='no' Protocol='burn' Bundle='yes'><PayloadRef Id='credwiz.exe' /><PayloadRef Id='SourceFilePayload' /></ExePackage>", exePackageElements[0].GetTestXml(ignoreAttributesByElementName));
358
+ Assert.Equal("<ExePackage Id='cscript.exe' Cache='keep' CacheId='*' InstallSize='*' Size='*' PerMachine='yes' Permanent='yes' Vital='yes' RollbackBoundaryBackward='WixDefaultBoundary' LogPathVariable='WixBundleLog_cscript.exe' RollbackLogPathVariable='WixBundleRollbackLog_cscript.exe' DetectCondition='none' InstallArguments='' UninstallArguments='' Uninstallable='yes' RepairArguments='' Repairable='no' Protocol='none' Bundle='yes'><PayloadRef Id='cscript.exe' /><PayloadRef Id='SourceFilePayload' /></ExePackage>", exePackageElements[1].GetTestXml(ignoreAttributesByElementName));
359
}
360
}
361
src/wix/test/WixToolsetTest.CoreIntegration/TestData/BadInput/BundleExePackageWithNetfxProtocol.wxs
new
+8
@@ -0,0 +1,8 @@
1
+<?xml version="1.0" encoding="utf-8"?>
2
+<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
3
+ <Fragment>
4
+ <PackageGroup Id="BundlePackages">
5
+ <ExePackage SourceFile="burn.exe" Bundle="yes" Protocol="netfx4" DetectCondition="none" InstallArguments="/q /norestart" UninstallArguments="/q /norestart" />
6
+ </PackageGroup>
7
+ </Fragment>
8
+</Wix>
src/wix/test/WixToolsetTest.CoreIntegration/TestData/SharedPayloadsBetweenPackages/SharedPayloadsBetweenPackages.wxs
+2
-2
@@ -2,10 +2,10 @@
2
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
3
<Fragment>
4
<PackageGroup Id="BundlePackages">
5
- <ExePackage SourceFile="C:\Windows\system32\credwiz.exe" Permanent="yes" DetectCondition="none" UninstallArguments="-foo">
5
+ <ExePackage SourceFile="C:\Windows\system32\credwiz.exe" Permanent="yes" DetectCondition="none" UninstallArguments="-foo" Bundle="yes">
6
<PayloadGroupRef Id="SharedPayloads" />
7
</ExePackage>
8
- <ExePackage SourceFile="C:\Windows\system32\cscript.exe" Permanent="yes" DetectCondition="none" UninstallArguments="">
8
+ <ExePackage SourceFile="C:\Windows\system32\cscript.exe" Permanent="yes" DetectCondition="none" UninstallArguments="" Bundle="yes" Protocol="none">
9
<PayloadGroupRef Id="SharedPayloads" />
10
</ExePackage>
11
</PackageGroup>