diff options
Diffstat (limited to '')
35 files changed, 1154 insertions, 42 deletions
diff --git a/src/ext/Bal/dnchost/dnchost.cpp b/src/ext/Bal/dnchost/dnchost.cpp index 6c066f43..36970f83 100644 --- a/src/ext/Bal/dnchost/dnchost.cpp +++ b/src/ext/Bal/dnchost/dnchost.cpp | |||
| @@ -76,6 +76,16 @@ extern "C" HRESULT WINAPI BootstrapperApplicationCreate( | |||
| 76 | vstate.fInitialized = TRUE; | 76 | vstate.fInitialized = TRUE; |
| 77 | } | 77 | } |
| 78 | 78 | ||
| 79 | if (vstate.prereqData.fAlwaysInstallPrereqs && !vstate.prereqData.fCompleted) | ||
| 80 | { | ||
| 81 | BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "Loading prerequisite bootstrapper application since it's configured to always run before loading the runtime."); | ||
| 82 | |||
| 83 | hr = CreatePrerequisiteBA(&vstate, pEngine, pArgs, pResults); | ||
| 84 | BalExitOnFailure(hr, "Failed to create the pre-requisite bootstrapper application."); | ||
| 85 | |||
| 86 | ExitFunction(); | ||
| 87 | } | ||
| 88 | |||
| 79 | if (!vstate.fInitializedRuntime) | 89 | if (!vstate.fInitializedRuntime) |
| 80 | { | 90 | { |
| 81 | hr = LoadRuntime(&vstate); | 91 | hr = LoadRuntime(&vstate); |
| @@ -214,6 +224,15 @@ static HRESULT LoadDncConfiguration( | |||
| 214 | hr = StrAllocConcat(&pState->sczBaFactoryRuntimeConfigPath, L".runtimeconfig.json", 0); | 224 | hr = StrAllocConcat(&pState->sczBaFactoryRuntimeConfigPath, L".runtimeconfig.json", 0); |
| 215 | BalExitOnFailure(hr, "Failed to concat extension to runtime config path."); | 225 | BalExitOnFailure(hr, "Failed to concat extension to runtime config path."); |
| 216 | 226 | ||
| 227 | hr = XmlSelectSingleNode(pixdManifest, L"/BootstrapperApplicationData/WixMbaPrereqOptions", &pixnHost); | ||
| 228 | BalExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed to find WixMbaPrereqOptions element in bootstrapper application config."); | ||
| 229 | |||
| 230 | if (fXmlFound) | ||
| 231 | { | ||
| 232 | hr = XmlGetAttributeNumber(pixnHost, L"AlwaysInstallPrereqs", reinterpret_cast<DWORD*>(&pState->prereqData.fAlwaysInstallPrereqs)); | ||
| 233 | BalExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed to get AlwaysInstallPrereqs value."); | ||
| 234 | } | ||
| 235 | |||
| 217 | pState->type = DNCHOSTTYPE_FDD; | 236 | pState->type = DNCHOSTTYPE_FDD; |
| 218 | 237 | ||
| 219 | hr = XmlSelectSingleNode(pixdManifest, L"/BootstrapperApplicationData/WixDncOptions", &pixnHost); | 238 | hr = XmlSelectSingleNode(pixdManifest, L"/BootstrapperApplicationData/WixDncOptions", &pixnHost); |
diff --git a/src/ext/Bal/mbahost/mbahost.cpp b/src/ext/Bal/mbahost/mbahost.cpp index 3de77a05..0b89fc58 100644 --- a/src/ext/Bal/mbahost/mbahost.cpp +++ b/src/ext/Bal/mbahost/mbahost.cpp | |||
| @@ -24,6 +24,10 @@ static HRESULT GetAppDomain( | |||
| 24 | static HRESULT LoadModulePaths( | 24 | static HRESULT LoadModulePaths( |
| 25 | __in MBASTATE* pState | 25 | __in MBASTATE* pState |
| 26 | ); | 26 | ); |
| 27 | static HRESULT LoadMbaConfiguration( | ||
| 28 | __in MBASTATE* pState, | ||
| 29 | __in const BOOTSTRAPPER_CREATE_ARGS* pArgs | ||
| 30 | ); | ||
| 27 | static HRESULT CheckSupportedFrameworks( | 31 | static HRESULT CheckSupportedFrameworks( |
| 28 | __in LPCWSTR wzConfigPath | 32 | __in LPCWSTR wzConfigPath |
| 29 | ); | 33 | ); |
| @@ -96,12 +100,28 @@ extern "C" HRESULT WINAPI BootstrapperApplicationCreate( | |||
| 96 | 100 | ||
| 97 | if (!vstate.fInitialized) | 101 | if (!vstate.fInitialized) |
| 98 | { | 102 | { |
| 103 | hr = XmlInitialize(); | ||
| 104 | BalExitOnFailure(hr, "Failed to initialize XML."); | ||
| 105 | |||
| 99 | hr = LoadModulePaths(&vstate); | 106 | hr = LoadModulePaths(&vstate); |
| 100 | BalExitOnFailure(hr, "Failed to load the module paths."); | 107 | BalExitOnFailure(hr, "Failed to load the module paths."); |
| 101 | 108 | ||
| 109 | hr = LoadMbaConfiguration(&vstate, pArgs); | ||
| 110 | BalExitOnFailure(hr, "Failed to get the mba configuration."); | ||
| 111 | |||
| 102 | vstate.fInitialized = TRUE; | 112 | vstate.fInitialized = TRUE; |
| 103 | } | 113 | } |
| 104 | 114 | ||
| 115 | if (vstate.prereqData.fAlwaysInstallPrereqs && !vstate.prereqData.fCompleted) | ||
| 116 | { | ||
| 117 | BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "Loading prerequisite bootstrapper application since it's configured to always run before loading the runtime."); | ||
| 118 | |||
| 119 | hr = CreatePrerequisiteBA(&vstate, pEngine, pArgs, pResults); | ||
| 120 | BalExitOnFailure(hr, "Failed to create the pre-requisite bootstrapper application."); | ||
| 121 | |||
| 122 | ExitFunction(); | ||
| 123 | } | ||
| 124 | |||
| 105 | if (!vstate.fInitializedRuntime) | 125 | if (!vstate.fInitializedRuntime) |
| 106 | { | 126 | { |
| 107 | hr = LoadRuntime(&vstate); | 127 | hr = LoadRuntime(&vstate); |
| @@ -264,6 +284,35 @@ LExit: | |||
| 264 | return hr; | 284 | return hr; |
| 265 | } | 285 | } |
| 266 | 286 | ||
| 287 | static HRESULT LoadMbaConfiguration( | ||
| 288 | __in MBASTATE* pState, | ||
| 289 | __in const BOOTSTRAPPER_CREATE_ARGS* pArgs | ||
| 290 | ) | ||
| 291 | { | ||
| 292 | HRESULT hr = S_OK; | ||
| 293 | IXMLDOMDocument* pixdManifest = NULL; | ||
| 294 | IXMLDOMNode* pixnHost = NULL; | ||
| 295 | BOOL fXmlFound = FALSE; | ||
| 296 | |||
| 297 | hr = XmlLoadDocumentFromFile(pArgs->pCommand->wzBootstrapperApplicationDataPath, &pixdManifest); | ||
| 298 | BalExitOnFailure(hr, "Failed to load BalManifest '%ls'", pArgs->pCommand->wzBootstrapperApplicationDataPath); | ||
| 299 | |||
| 300 | hr = XmlSelectSingleNode(pixdManifest, L"/BootstrapperApplicationData/WixMbaPrereqOptions", &pixnHost); | ||
| 301 | BalExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed to find WixMbaPrereqOptions element in bootstrapper application config."); | ||
| 302 | |||
| 303 | if (fXmlFound) | ||
| 304 | { | ||
| 305 | hr = XmlGetAttributeNumber(pixnHost, L"AlwaysInstallPrereqs", reinterpret_cast<DWORD*>(&pState->prereqData.fAlwaysInstallPrereqs)); | ||
| 306 | BalExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed to get AlwaysInstallPrereqs value."); | ||
| 307 | } | ||
| 308 | |||
| 309 | LExit: | ||
| 310 | ReleaseObject(pixnHost); | ||
| 311 | ReleaseObject(pixdManifest); | ||
| 312 | |||
| 313 | return hr; | ||
| 314 | } | ||
| 315 | |||
| 267 | // Checks whether at least one of required supported frameworks is installed via the NETFX registry keys. | 316 | // Checks whether at least one of required supported frameworks is installed via the NETFX registry keys. |
| 268 | static HRESULT CheckSupportedFrameworks( | 317 | static HRESULT CheckSupportedFrameworks( |
| 269 | __in LPCWSTR wzConfigPath | 318 | __in LPCWSTR wzConfigPath |
| @@ -280,9 +329,6 @@ static HRESULT CheckSupportedFrameworks( | |||
| 280 | DWORD dwFrameworkInstalled = 0; | 329 | DWORD dwFrameworkInstalled = 0; |
| 281 | BOOL fUpdatedManifest = FALSE; | 330 | BOOL fUpdatedManifest = FALSE; |
| 282 | 331 | ||
| 283 | hr = XmlInitialize(); | ||
| 284 | ExitOnFailure(hr, "Failed to initialize XML."); | ||
| 285 | |||
| 286 | hr = XmlLoadDocumentFromFile(wzConfigPath, &pixdManifest); | 332 | hr = XmlLoadDocumentFromFile(wzConfigPath, &pixdManifest); |
| 287 | ExitOnFailure(hr, "Failed to load bootstrapper config file from path: %ls", wzConfigPath); | 333 | ExitOnFailure(hr, "Failed to load bootstrapper config file from path: %ls", wzConfigPath); |
| 288 | 334 | ||
| @@ -342,8 +388,6 @@ LExit: | |||
| 342 | ReleaseObject(pNodeList); | 388 | ReleaseObject(pNodeList); |
| 343 | ReleaseObject(pixdManifest); | 389 | ReleaseObject(pixdManifest); |
| 344 | 390 | ||
| 345 | XmlUninitialize(); | ||
| 346 | |||
| 347 | return hr; | 391 | return hr; |
| 348 | } | 392 | } |
| 349 | 393 | ||
diff --git a/src/ext/Bal/test/WixToolsetTest.Bal/BalExtensionFixture.cs b/src/ext/Bal/test/WixToolsetTest.Bal/BalExtensionFixture.cs index 9aea8c1d..43484855 100644 --- a/src/ext/Bal/test/WixToolsetTest.Bal/BalExtensionFixture.cs +++ b/src/ext/Bal/test/WixToolsetTest.Bal/BalExtensionFixture.cs | |||
| @@ -107,7 +107,41 @@ namespace WixToolsetTest.Bal | |||
| 107 | } | 107 | } |
| 108 | 108 | ||
| 109 | [Fact] | 109 | [Fact] |
| 110 | public void CantBuildUsingMBAWithNoPrereqs() | 110 | public void CanBuildUsingMBAWithAlwaysInstallPrereqs() |
| 111 | { | ||
| 112 | using (var fs = new DisposableFileSystem()) | ||
| 113 | { | ||
| 114 | var baseFolder = fs.GetFolder(); | ||
| 115 | var bundleFile = Path.Combine(baseFolder, "bin", "test.exe"); | ||
| 116 | var bundleSourceFolder = TestData.Get(@"TestData\MBA"); | ||
| 117 | var intermediateFolder = Path.Combine(baseFolder, "obj"); | ||
| 118 | var baFolderPath = Path.Combine(baseFolder, "ba"); | ||
| 119 | var extractFolderPath = Path.Combine(baseFolder, "extract"); | ||
| 120 | |||
| 121 | var compileResult = WixRunner.Execute(new[] | ||
| 122 | { | ||
| 123 | "build", | ||
| 124 | Path.Combine(bundleSourceFolder, "AlwaysInstallPrereqsBundle.wxs"), | ||
| 125 | "-ext", TestData.Get(@"WixToolset.Bal.wixext.dll"), | ||
| 126 | "-intermediateFolder", intermediateFolder, | ||
| 127 | "-o", bundleFile, | ||
| 128 | }); | ||
| 129 | |||
| 130 | compileResult.AssertSuccess(); | ||
| 131 | |||
| 132 | Assert.True(File.Exists(bundleFile)); | ||
| 133 | |||
| 134 | var extractResult = BundleExtractor.ExtractBAContainer(null, bundleFile, baFolderPath, extractFolderPath); | ||
| 135 | extractResult.AssertSuccess(); | ||
| 136 | |||
| 137 | var wixMbaPrereqOptionsElements = extractResult.SelectBADataNodes("/ba:BootstrapperApplicationData/ba:WixMbaPrereqOptions"); | ||
| 138 | var wixMbaPrereqOptions = (XmlNode)Assert.Single(wixMbaPrereqOptionsElements); | ||
| 139 | Assert.Equal("<WixMbaPrereqOptions AlwaysInstallPrereqs='1' />", wixMbaPrereqOptions.GetTestXml()); | ||
| 140 | } | ||
| 141 | } | ||
| 142 | |||
| 143 | [Fact] | ||
| 144 | public void CannotBuildUsingMBAWithNoPrereqs() | ||
| 111 | { | 145 | { |
| 112 | using (var fs = new DisposableFileSystem()) | 146 | using (var fs = new DisposableFileSystem()) |
| 113 | { | 147 | { |
| @@ -133,7 +167,7 @@ namespace WixToolsetTest.Bal | |||
| 133 | } | 167 | } |
| 134 | 168 | ||
| 135 | [Fact] | 169 | [Fact] |
| 136 | public void CantBuildUsingOverridableWrongCase() | 170 | public void CannotBuildUsingOverridableWrongCase() |
| 137 | { | 171 | { |
| 138 | using (var fs = new DisposableFileSystem()) | 172 | using (var fs = new DisposableFileSystem()) |
| 139 | { | 173 | { |
diff --git a/src/ext/Bal/test/WixToolsetTest.Bal/TestData/MBA/AlwaysInstallPrereqsBundle.wxs b/src/ext/Bal/test/WixToolsetTest.Bal/TestData/MBA/AlwaysInstallPrereqsBundle.wxs new file mode 100644 index 00000000..685fef7b --- /dev/null +++ b/src/ext/Bal/test/WixToolsetTest.Bal/TestData/MBA/AlwaysInstallPrereqsBundle.wxs | |||
| @@ -0,0 +1,12 @@ | |||
| 1 | <?xml version="1.0" encoding="utf-8"?> | ||
| 2 | <Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" | ||
| 3 | xmlns:bal="http://wixtoolset.org/schemas/v4/wxs/bal"> | ||
| 4 | <Bundle Name="AlwaysInstallPrereqsBundle" Version="1.0.0.0" Manufacturer="Example Corporation" UpgradeCode="{36E9E102-E0E4-4A91-941D-6681A49216E6}"> | ||
| 5 | <BootstrapperApplication> | ||
| 6 | <bal:WixManagedBootstrapperApplicationHost AlwaysInstallPrereqs="yes" /> | ||
| 7 | </BootstrapperApplication> | ||
| 8 | <Chain> | ||
| 9 | <ExePackage bal:PrereqPackage="yes" Permanent="yes" DetectCondition="none" SourceFile="runtimes\win-x86\native\wixnative.exe" /> | ||
| 10 | </Chain> | ||
| 11 | </Bundle> | ||
| 12 | </Wix> | ||
diff --git a/src/ext/Bal/wixext/BalBurnBackendExtension.cs b/src/ext/Bal/wixext/BalBurnBackendExtension.cs index 3b19ae78..d34c159a 100644 --- a/src/ext/Bal/wixext/BalBurnBackendExtension.cs +++ b/src/ext/Bal/wixext/BalBurnBackendExtension.cs | |||
| @@ -24,6 +24,7 @@ namespace WixToolset.Bal | |||
| 24 | BalSymbolDefinitions.WixMbaPrereqInformation, | 24 | BalSymbolDefinitions.WixMbaPrereqInformation, |
| 25 | BalSymbolDefinitions.WixStdbaOptions, | 25 | BalSymbolDefinitions.WixStdbaOptions, |
| 26 | BalSymbolDefinitions.WixStdbaOverridableVariable, | 26 | BalSymbolDefinitions.WixStdbaOverridableVariable, |
| 27 | BalSymbolDefinitions.WixMbaPrereqOptions, | ||
| 27 | }; | 28 | }; |
| 28 | 29 | ||
| 29 | protected override IReadOnlyCollection<IntermediateSymbolDefinition> SymbolDefinitions => BurnSymbolDefinitions; | 30 | protected override IReadOnlyCollection<IntermediateSymbolDefinition> SymbolDefinitions => BurnSymbolDefinitions; |
diff --git a/src/ext/Bal/wixext/BalCompiler.cs b/src/ext/Bal/wixext/BalCompiler.cs index 267345e7..1721f252 100644 --- a/src/ext/Bal/wixext/BalCompiler.cs +++ b/src/ext/Bal/wixext/BalCompiler.cs | |||
| @@ -117,6 +117,7 @@ namespace WixToolset.Bal | |||
| 117 | 117 | ||
| 118 | switch (parentElement.Name.LocalName) | 118 | switch (parentElement.Name.LocalName) |
| 119 | { | 119 | { |
| 120 | case "BundlePackage": | ||
| 120 | case "ExePackage": | 121 | case "ExePackage": |
| 121 | case "MsiPackage": | 122 | case "MsiPackage": |
| 122 | case "MspPackage": | 123 | case "MspPackage": |
| @@ -216,7 +217,7 @@ namespace WixToolset.Bal | |||
| 216 | case "PrereqPackage": | 217 | case "PrereqPackage": |
| 217 | if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attribute)) | 218 | if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attribute)) |
| 218 | { | 219 | { |
| 219 | if (!this.prereqInfoSymbolsByPackageId.TryGetValue(packageId, out prereqInfo)) | 220 | if (!this.prereqInfoSymbolsByPackageId.TryGetValue(packageId, out _)) |
| 220 | { | 221 | { |
| 221 | prereqInfo = section.AddSymbol(new WixMbaPrereqInformationSymbol(sourceLineNumbers) | 222 | prereqInfo = section.AddSymbol(new WixMbaPrereqInformationSymbol(sourceLineNumbers) |
| 222 | { | 223 | { |
| @@ -703,6 +704,7 @@ namespace WixToolset.Bal | |||
| 703 | private void ParseWixManagedBootstrapperApplicationHostElement(Intermediate intermediate, IntermediateSection section, XElement node) | 704 | private void ParseWixManagedBootstrapperApplicationHostElement(Intermediate intermediate, IntermediateSection section, XElement node) |
| 704 | { | 705 | { |
| 705 | var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node); | 706 | var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node); |
| 707 | bool alwaysInstallPrereqs = false; | ||
| 706 | string logoFile = null; | 708 | string logoFile = null; |
| 707 | string themeFile = null; | 709 | string themeFile = null; |
| 708 | string localizationFile = null; | 710 | string localizationFile = null; |
| @@ -714,6 +716,9 @@ namespace WixToolset.Bal | |||
| 714 | { | 716 | { |
| 715 | switch (attrib.Name.LocalName) | 717 | switch (attrib.Name.LocalName) |
| 716 | { | 718 | { |
| 719 | case "AlwaysInstallPrereqs": | ||
| 720 | alwaysInstallPrereqs = this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) == YesNoType.Yes; | ||
| 721 | break; | ||
| 717 | case "LogoFile": | 722 | case "LogoFile": |
| 718 | logoFile = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); | 723 | logoFile = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); |
| 719 | break; | 724 | break; |
| @@ -792,6 +797,14 @@ namespace WixToolset.Bal | |||
| 792 | } | 797 | } |
| 793 | 798 | ||
| 794 | this.CreateBARef(section, sourceLineNumbers, node, baId); | 799 | this.CreateBARef(section, sourceLineNumbers, node, baId); |
| 800 | |||
| 801 | if (alwaysInstallPrereqs) | ||
| 802 | { | ||
| 803 | section.AddSymbol(new WixMbaPrereqOptionsSymbol(sourceLineNumbers, new Identifier(AccessModifier.Global, "WixMbaPrereqOptions")) | ||
| 804 | { | ||
| 805 | AlwaysInstallPrereqs = 1, | ||
| 806 | }); | ||
| 807 | } | ||
| 795 | } | 808 | } |
| 796 | } | 809 | } |
| 797 | 810 | ||
| @@ -802,6 +815,7 @@ namespace WixToolset.Bal | |||
| 802 | private void ParseWixDotNetCoreBootstrapperApplicationHostElement(Intermediate intermediate, IntermediateSection section, XElement node) | 815 | private void ParseWixDotNetCoreBootstrapperApplicationHostElement(Intermediate intermediate, IntermediateSection section, XElement node) |
| 803 | { | 816 | { |
| 804 | var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node); | 817 | var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node); |
| 818 | bool alwaysInstallPrereqs = false; | ||
| 805 | string logoFile = null; | 819 | string logoFile = null; |
| 806 | string themeFile = null; | 820 | string themeFile = null; |
| 807 | string localizationFile = null; | 821 | string localizationFile = null; |
| @@ -814,6 +828,9 @@ namespace WixToolset.Bal | |||
| 814 | { | 828 | { |
| 815 | switch (attrib.Name.LocalName) | 829 | switch (attrib.Name.LocalName) |
| 816 | { | 830 | { |
| 831 | case "AlwaysInstallPrereqs": | ||
| 832 | alwaysInstallPrereqs = this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) == YesNoType.Yes; | ||
| 833 | break; | ||
| 817 | case "LogoFile": | 834 | case "LogoFile": |
| 818 | logoFile = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); | 835 | logoFile = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); |
| 819 | break; | 836 | break; |
| @@ -903,6 +920,14 @@ namespace WixToolset.Bal | |||
| 903 | } | 920 | } |
| 904 | 921 | ||
| 905 | this.CreateBARef(section, sourceLineNumbers, node, baId); | 922 | this.CreateBARef(section, sourceLineNumbers, node, baId); |
| 923 | |||
| 924 | if (alwaysInstallPrereqs) | ||
| 925 | { | ||
| 926 | section.AddSymbol(new WixMbaPrereqOptionsSymbol(sourceLineNumbers, new Identifier(AccessModifier.Global, "WixMbaPrereqOptions")) | ||
| 927 | { | ||
| 928 | AlwaysInstallPrereqs = 1, | ||
| 929 | }); | ||
| 930 | } | ||
| 906 | } | 931 | } |
| 907 | } | 932 | } |
| 908 | 933 | ||
diff --git a/src/ext/Bal/wixext/Symbols/BalSymbolDefinitions.cs b/src/ext/Bal/wixext/Symbols/BalSymbolDefinitions.cs index 90865621..9010ce2d 100644 --- a/src/ext/Bal/wixext/Symbols/BalSymbolDefinitions.cs +++ b/src/ext/Bal/wixext/Symbols/BalSymbolDefinitions.cs | |||
| @@ -16,6 +16,7 @@ namespace WixToolset.Bal | |||
| 16 | WixMbaPrereqInformation, | 16 | WixMbaPrereqInformation, |
| 17 | WixStdbaOptions, | 17 | WixStdbaOptions, |
| 18 | WixStdbaOverridableVariable, | 18 | WixStdbaOverridableVariable, |
| 19 | WixMbaPrereqOptions, | ||
| 19 | } | 20 | } |
| 20 | 21 | ||
| 21 | public static partial class BalSymbolDefinitions | 22 | public static partial class BalSymbolDefinitions |
| @@ -60,6 +61,9 @@ namespace WixToolset.Bal | |||
| 60 | case BalSymbolDefinitionType.WixStdbaOverridableVariable: | 61 | case BalSymbolDefinitionType.WixStdbaOverridableVariable: |
| 61 | return BalSymbolDefinitions.WixStdbaOverridableVariable; | 62 | return BalSymbolDefinitions.WixStdbaOverridableVariable; |
| 62 | 63 | ||
| 64 | case BalSymbolDefinitionType.WixMbaPrereqOptions: | ||
| 65 | return BalSymbolDefinitions.WixMbaPrereqOptions; | ||
| 66 | |||
| 63 | default: | 67 | default: |
| 64 | throw new ArgumentOutOfRangeException(nameof(type)); | 68 | throw new ArgumentOutOfRangeException(nameof(type)); |
| 65 | } | 69 | } |
| @@ -75,6 +79,7 @@ namespace WixToolset.Bal | |||
| 75 | WixMbaPrereqInformation.AddTag(BurnConstants.BootstrapperApplicationDataSymbolDefinitionTag); | 79 | WixMbaPrereqInformation.AddTag(BurnConstants.BootstrapperApplicationDataSymbolDefinitionTag); |
| 76 | WixStdbaOptions.AddTag(BurnConstants.BootstrapperApplicationDataSymbolDefinitionTag); | 80 | WixStdbaOptions.AddTag(BurnConstants.BootstrapperApplicationDataSymbolDefinitionTag); |
| 77 | WixStdbaOverridableVariable.AddTag(BurnConstants.BootstrapperApplicationDataSymbolDefinitionTag); | 81 | WixStdbaOverridableVariable.AddTag(BurnConstants.BootstrapperApplicationDataSymbolDefinitionTag); |
| 82 | WixMbaPrereqOptions.AddTag(BurnConstants.BootstrapperApplicationDataSymbolDefinitionTag); | ||
| 78 | } | 83 | } |
| 79 | } | 84 | } |
| 80 | } | 85 | } |
diff --git a/src/ext/Bal/wixext/Symbols/WixMbaPrereqOptionsSymbol.cs b/src/ext/Bal/wixext/Symbols/WixMbaPrereqOptionsSymbol.cs new file mode 100644 index 00000000..66374579 --- /dev/null +++ b/src/ext/Bal/wixext/Symbols/WixMbaPrereqOptionsSymbol.cs | |||
| @@ -0,0 +1,47 @@ | |||
| 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | ||
| 2 | |||
| 3 | namespace WixToolset.Bal | ||
| 4 | { | ||
| 5 | using WixToolset.Data; | ||
| 6 | using WixToolset.Bal.Symbols; | ||
| 7 | |||
| 8 | public static partial class BalSymbolDefinitions | ||
| 9 | { | ||
| 10 | public static readonly IntermediateSymbolDefinition WixMbaPrereqOptions = new IntermediateSymbolDefinition( | ||
| 11 | BalSymbolDefinitionType.WixMbaPrereqOptions.ToString(), | ||
| 12 | new[] | ||
| 13 | { | ||
| 14 | new IntermediateFieldDefinition(nameof(WixMbaPrereqOptionsSymbolFields.AlwaysInstallPrereqs), IntermediateFieldType.Number), | ||
| 15 | }, | ||
| 16 | typeof(WixMbaPrereqOptionsSymbol)); | ||
| 17 | } | ||
| 18 | } | ||
| 19 | |||
| 20 | namespace WixToolset.Bal.Symbols | ||
| 21 | { | ||
| 22 | using WixToolset.Data; | ||
| 23 | |||
| 24 | public enum WixMbaPrereqOptionsSymbolFields | ||
| 25 | { | ||
| 26 | AlwaysInstallPrereqs, | ||
| 27 | } | ||
| 28 | |||
| 29 | public class WixMbaPrereqOptionsSymbol : IntermediateSymbol | ||
| 30 | { | ||
| 31 | public WixMbaPrereqOptionsSymbol() : base(BalSymbolDefinitions.WixMbaPrereqOptions, null, null) | ||
| 32 | { | ||
| 33 | } | ||
| 34 | |||
| 35 | public WixMbaPrereqOptionsSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(BalSymbolDefinitions.WixMbaPrereqOptions, sourceLineNumber, id) | ||
| 36 | { | ||
| 37 | } | ||
| 38 | |||
| 39 | public IntermediateField this[WixMbaPrereqOptionsSymbolFields index] => this.Fields[(int)index]; | ||
| 40 | |||
| 41 | public int AlwaysInstallPrereqs | ||
| 42 | { | ||
| 43 | get => this.Fields[(int)WixMbaPrereqOptionsSymbolFields.AlwaysInstallPrereqs].AsNumber(); | ||
| 44 | set => this.Set((int)WixMbaPrereqOptionsSymbolFields.AlwaysInstallPrereqs, value); | ||
| 45 | } | ||
| 46 | } | ||
| 47 | } | ||
diff --git a/src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp b/src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp index 3774f49c..9c0f9576 100644 --- a/src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp +++ b/src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp | |||
| @@ -30,6 +30,8 @@ enum WIXSTDBA_STATE | |||
| 30 | WIXSTDBA_STATE_HELP, | 30 | WIXSTDBA_STATE_HELP, |
| 31 | WIXSTDBA_STATE_DETECTING, | 31 | WIXSTDBA_STATE_DETECTING, |
| 32 | WIXSTDBA_STATE_DETECTED, | 32 | WIXSTDBA_STATE_DETECTED, |
| 33 | WIXSTDBA_STATE_PLANNING_PREREQS, | ||
| 34 | WIXSTDBA_STATE_PLANNED_PREREQS, | ||
| 33 | WIXSTDBA_STATE_PLANNING, | 35 | WIXSTDBA_STATE_PLANNING, |
| 34 | WIXSTDBA_STATE_PLANNED, | 36 | WIXSTDBA_STATE_PLANNED, |
| 35 | WIXSTDBA_STATE_APPLYING, | 37 | WIXSTDBA_STATE_APPLYING, |
| @@ -49,6 +51,7 @@ enum WM_WIXSTDBA | |||
| 49 | WM_WIXSTDBA_APPLY_PACKAGES, | 51 | WM_WIXSTDBA_APPLY_PACKAGES, |
| 50 | WM_WIXSTDBA_CHANGE_STATE, | 52 | WM_WIXSTDBA_CHANGE_STATE, |
| 51 | WM_WIXSTDBA_SHOW_FAILURE, | 53 | WM_WIXSTDBA_SHOW_FAILURE, |
| 54 | WM_WIXSTDBA_PLAN_PREREQS, | ||
| 52 | }; | 55 | }; |
| 53 | 56 | ||
| 54 | // This enum must be kept in the same order as the vrgwzPageNames array. | 57 | // This enum must be kept in the same order as the vrgwzPageNames array. |
| @@ -217,9 +220,11 @@ public: // IBootstrapperApplication | |||
| 217 | : "A restart is required by the prerequisites but the user delayed it. The bootstrapper application will be reloaded after the computer is restarted."); | 220 | : "A restart is required by the prerequisites but the user delayed it. The bootstrapper application will be reloaded after the computer is restarted."); |
| 218 | } | 221 | } |
| 219 | } | 222 | } |
| 220 | else if (m_fPrereqInstalled) | 223 | else if (m_fPrereqInstalled || m_fPrereqSkipped) |
| 221 | { | 224 | { |
| 222 | BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "The prerequisites were successfully installed. The bootstrapper application will be reloaded."); | 225 | BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, m_fPrereqInstalled |
| 226 | ? "The prerequisites were successfully installed. The bootstrapper application will be reloaded." | ||
| 227 | : "The prerequisites were already installed. The bootstrapper application will be reloaded."); | ||
| 223 | *pAction = BOOTSTRAPPER_SHUTDOWN_ACTION_RELOAD_BOOTSTRAPPER; | 228 | *pAction = BOOTSTRAPPER_SHUTDOWN_ACTION_RELOAD_BOOTSTRAPPER; |
| 224 | m_pPrereqData->fCompleted = TRUE; | 229 | m_pPrereqData->fCompleted = TRUE; |
| 225 | } | 230 | } |
| @@ -275,13 +280,16 @@ public: // IBootstrapperApplication | |||
| 275 | hr = S_OK; | 280 | hr = S_OK; |
| 276 | } | 281 | } |
| 277 | 282 | ||
| 278 | // If the UI should be visible, display it now and hide the splash screen | 283 | if (!m_fPreplanPrereqs) |
| 279 | if (BOOTSTRAPPER_DISPLAY_NONE < m_command.display) | ||
| 280 | { | 284 | { |
| 281 | ::ShowWindow(m_pTheme->hwndParent, SW_SHOW); | 285 | // If the UI should be visible, display it now and hide the splash screen |
| 282 | } | 286 | if (BOOTSTRAPPER_DISPLAY_NONE < m_command.display) |
| 287 | { | ||
| 288 | ::ShowWindow(m_pTheme->hwndParent, SW_SHOW); | ||
| 289 | } | ||
| 283 | 290 | ||
| 284 | m_pEngine->CloseSplashScreen(); | 291 | m_pEngine->CloseSplashScreen(); |
| 292 | } | ||
| 285 | 293 | ||
| 286 | return __super::OnDetectBegin(fCached, registrationType, cPackages, pfCancel); | 294 | return __super::OnDetectBegin(fCached, registrationType, cPackages, pfCancel); |
| 287 | } | 295 | } |
| @@ -331,24 +339,37 @@ public: // IBootstrapperApplication | |||
| 331 | if (fEvaluateConditions) | 339 | if (fEvaluateConditions) |
| 332 | { | 340 | { |
| 333 | hrStatus = EvaluateConditions(); | 341 | hrStatus = EvaluateConditions(); |
| 334 | |||
| 335 | if (FAILED(hrStatus)) | ||
| 336 | { | ||
| 337 | fSkipToPlan = FALSE; | ||
| 338 | } | ||
| 339 | } | 342 | } |
| 340 | 343 | ||
| 341 | SetState(WIXSTDBA_STATE_DETECTED, hrStatus); | 344 | SetState(WIXSTDBA_STATE_DETECTED, hrStatus); |
| 342 | 345 | ||
| 343 | if (fSkipToPlan) | 346 | if (SUCCEEDED(hrStatus)) |
| 344 | { | 347 | { |
| 345 | ::PostMessageW(m_hWnd, WM_WIXSTDBA_PLAN_PACKAGES, 0, m_command.action); | 348 | if (m_fPreplanPrereqs) |
| 349 | { | ||
| 350 | ::PostMessageW(m_hWnd, WM_WIXSTDBA_PLAN_PREREQS, 0, BOOTSTRAPPER_ACTION_INSTALL); | ||
| 351 | } | ||
| 352 | else if (fSkipToPlan) | ||
| 353 | { | ||
| 354 | ::PostMessageW(m_hWnd, WM_WIXSTDBA_PLAN_PACKAGES, 0, m_command.action); | ||
| 355 | } | ||
| 346 | } | 356 | } |
| 347 | 357 | ||
| 348 | return hr; | 358 | return hr; |
| 349 | } | 359 | } |
| 350 | 360 | ||
| 351 | 361 | ||
| 362 | virtual STDMETHODIMP OnPlanBegin( | ||
| 363 | __in DWORD cPackages, | ||
| 364 | __in BOOL* pfCancel | ||
| 365 | ) | ||
| 366 | { | ||
| 367 | m_fPrereqPackagePlanned = FALSE; | ||
| 368 | |||
| 369 | return __super::OnPlanBegin(cPackages, pfCancel); | ||
| 370 | } | ||
| 371 | |||
| 372 | |||
| 352 | virtual STDMETHODIMP OnPlanRelatedBundleType( | 373 | virtual STDMETHODIMP OnPlanRelatedBundleType( |
| 353 | __in_z LPCWSTR wzBundleId, | 374 | __in_z LPCWSTR wzBundleId, |
| 354 | __in BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE recommendedType, | 375 | __in BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE recommendedType, |
| @@ -484,24 +505,97 @@ public: // IBootstrapperApplication | |||
| 484 | } | 505 | } |
| 485 | 506 | ||
| 486 | 507 | ||
| 508 | virtual STDMETHODIMP OnPlannedPackage( | ||
| 509 | __in_z LPCWSTR wzPackageId, | ||
| 510 | __in BOOTSTRAPPER_ACTION_STATE execute, | ||
| 511 | __in BOOTSTRAPPER_ACTION_STATE rollback, | ||
| 512 | __in BOOL fPlannedCache, | ||
| 513 | __in BOOL fPlannedUncache | ||
| 514 | ) | ||
| 515 | { | ||
| 516 | if (m_fPrereq && BOOTSTRAPPER_ACTION_STATE_NONE != execute) | ||
| 517 | { | ||
| 518 | m_fPrereqPackagePlanned = TRUE; | ||
| 519 | } | ||
| 520 | |||
| 521 | return __super::OnPlannedPackage(wzPackageId, execute, rollback, fPlannedCache, fPlannedUncache); | ||
| 522 | } | ||
| 523 | |||
| 524 | |||
| 487 | virtual STDMETHODIMP OnPlanComplete( | 525 | virtual STDMETHODIMP OnPlanComplete( |
| 488 | __in HRESULT hrStatus | 526 | __in HRESULT hrStatus |
| 489 | ) | 527 | ) |
| 490 | { | 528 | { |
| 491 | HRESULT hr = S_OK; | 529 | HRESULT hr = S_OK; |
| 530 | BOOL fPlannedPrereqs = WIXSTDBA_STATE_PLANNING_PREREQS == m_state; | ||
| 531 | WIXSTDBA_STATE completedState = WIXSTDBA_STATE_PLANNED; | ||
| 532 | BOOL fApply = TRUE; | ||
| 492 | 533 | ||
| 493 | SetState(WIXSTDBA_STATE_PLANNED, hrStatus); | 534 | if (fPlannedPrereqs) |
| 535 | { | ||
| 536 | if (SUCCEEDED(hrStatus) && !m_fPrereqPackagePlanned) | ||
| 537 | { | ||
| 538 | // Nothing to do, so close and let the parent BA take over. | ||
| 539 | m_fPrereqSkipped = TRUE; | ||
| 540 | SetState(WIXSTDBA_STATE_APPLIED, S_OK); | ||
| 541 | ExitFunction(); | ||
| 542 | } | ||
| 543 | else if (BOOTSTRAPPER_ACTION_HELP == m_command.action) | ||
| 544 | { | ||
| 545 | // If prereq packages were planned then the managed BA probably can't be loaded, so show the help from this BA. | ||
| 494 | 546 | ||
| 495 | if (SUCCEEDED(hrStatus)) | 547 | // Need to force the state change since normally moving backwards is prevented. |
| 548 | ::PostMessageW(m_hWnd, WM_WIXSTDBA_CHANGE_STATE, 0, WIXSTDBA_STATE_HELP); | ||
| 549 | |||
| 550 | ::PostMessageW(m_hWnd, WM_WIXSTDBA_SHOW_HELP, 0, 0); | ||
| 551 | |||
| 552 | ExitFunction(); | ||
| 553 | } | ||
| 554 | |||
| 555 | completedState = WIXSTDBA_STATE_PLANNED_PREREQS; | ||
| 556 | } | ||
| 557 | |||
| 558 | SetState(completedState, hrStatus); | ||
| 559 | |||
| 560 | if (FAILED(hrStatus)) | ||
| 561 | { | ||
| 562 | ExitFunction(); | ||
| 563 | } | ||
| 564 | |||
| 565 | if (fPlannedPrereqs) | ||
| 566 | { | ||
| 567 | // If the UI should be visible, display it now and hide the splash screen | ||
| 568 | if (BOOTSTRAPPER_DISPLAY_NONE < m_command.display) | ||
| 569 | { | ||
| 570 | ::ShowWindow(m_pTheme->hwndParent, SW_SHOW); | ||
| 571 | } | ||
| 572 | |||
| 573 | m_pEngine->CloseSplashScreen(); | ||
| 574 | |||
| 575 | fApply = BOOTSTRAPPER_DISPLAY_FULL > m_command.display || | ||
| 576 | BOOTSTRAPPER_RESUME_TYPE_REBOOT == m_command.resumeType; | ||
| 577 | } | ||
| 578 | |||
| 579 | if (fApply) | ||
| 496 | { | 580 | { |
| 497 | ::PostMessageW(m_hWnd, WM_WIXSTDBA_APPLY_PACKAGES, 0, 0); | 581 | ::PostMessageW(m_hWnd, WM_WIXSTDBA_APPLY_PACKAGES, 0, 0); |
| 498 | } | 582 | } |
| 499 | 583 | ||
| 584 | LExit: | ||
| 585 | return hr; | ||
| 586 | } | ||
| 587 | |||
| 588 | |||
| 589 | virtual STDMETHODIMP OnApplyBegin( | ||
| 590 | __in DWORD dwPhaseCount, | ||
| 591 | __in BOOL* pfCancel | ||
| 592 | ) | ||
| 593 | { | ||
| 500 | m_fStartedExecution = FALSE; | 594 | m_fStartedExecution = FALSE; |
| 501 | m_dwCalculatedCacheProgress = 0; | 595 | m_dwCalculatedCacheProgress = 0; |
| 502 | m_dwCalculatedExecuteProgress = 0; | 596 | m_dwCalculatedExecuteProgress = 0; |
| 503 | 597 | ||
| 504 | return hr; | 598 | return __super::OnApplyBegin(dwPhaseCount, pfCancel); |
| 505 | } | 599 | } |
| 506 | 600 | ||
| 507 | 601 | ||
| @@ -2149,6 +2243,7 @@ private: | |||
| 2149 | BOOL fRet = FALSE; | 2243 | BOOL fRet = FALSE; |
| 2150 | MSG msg = { }; | 2244 | MSG msg = { }; |
| 2151 | DWORD dwQuit = 0; | 2245 | DWORD dwQuit = 0; |
| 2246 | WM_WIXSTDBA firstAction = WM_WIXSTDBA_DETECT_PACKAGES; | ||
| 2152 | 2247 | ||
| 2153 | // Initialize COM and theme. | 2248 | // Initialize COM and theme. |
| 2154 | hr = ::CoInitialize(NULL); | 2249 | hr = ::CoInitialize(NULL); |
| @@ -2169,15 +2264,21 @@ private: | |||
| 2169 | if (FAILED(pThis->m_hrFinal)) | 2264 | if (FAILED(pThis->m_hrFinal)) |
| 2170 | { | 2265 | { |
| 2171 | pThis->SetState(WIXSTDBA_STATE_FAILED, hr); | 2266 | pThis->SetState(WIXSTDBA_STATE_FAILED, hr); |
| 2172 | ::PostMessageW(pThis->m_hWnd, WM_WIXSTDBA_SHOW_FAILURE, 0, 0); | 2267 | firstAction = WM_WIXSTDBA_SHOW_FAILURE; |
| 2173 | } | 2268 | } |
| 2174 | else | 2269 | else |
| 2175 | { | 2270 | { |
| 2176 | // Okay, we're ready for packages now. | 2271 | // Okay, we're ready for packages now. |
| 2177 | pThis->SetState(WIXSTDBA_STATE_INITIALIZED, hr); | 2272 | pThis->SetState(WIXSTDBA_STATE_INITIALIZED, hr); |
| 2178 | ::PostMessageW(pThis->m_hWnd, BOOTSTRAPPER_ACTION_HELP == pThis->m_command.action ? WM_WIXSTDBA_SHOW_HELP : WM_WIXSTDBA_DETECT_PACKAGES, 0, 0); | 2273 | |
| 2274 | if (!pThis->m_fPreplanPrereqs && BOOTSTRAPPER_ACTION_HELP == pThis->m_command.action) | ||
| 2275 | { | ||
| 2276 | firstAction = WM_WIXSTDBA_SHOW_HELP; | ||
| 2277 | } | ||
| 2179 | } | 2278 | } |
| 2180 | 2279 | ||
| 2280 | ::PostMessageW(pThis->m_hWnd, firstAction, 0, 0); | ||
| 2281 | |||
| 2181 | // message pump | 2282 | // message pump |
| 2182 | while (0 != (fRet = ::GetMessageW(&msg, NULL, 0, 0))) | 2283 | while (0 != (fRet = ::GetMessageW(&msg, NULL, 0, 0))) |
| 2183 | { | 2284 | { |
| @@ -2647,7 +2748,7 @@ private: | |||
| 2647 | 2748 | ||
| 2648 | // Calculate the window style based on the theme style and command display value. | 2749 | // Calculate the window style based on the theme style and command display value. |
| 2649 | dwWindowStyle = m_pTheme->dwStyle; | 2750 | dwWindowStyle = m_pTheme->dwStyle; |
| 2650 | if (BOOTSTRAPPER_DISPLAY_NONE >= m_command.display) | 2751 | if (BOOTSTRAPPER_DISPLAY_NONE >= m_command.display || m_fPreplanPrereqs) |
| 2651 | { | 2752 | { |
| 2652 | dwWindowStyle &= ~WS_VISIBLE; | 2753 | dwWindowStyle &= ~WS_VISIBLE; |
| 2653 | } | 2754 | } |
| @@ -2850,6 +2951,10 @@ private: | |||
| 2850 | pBA->OnShowFailure(); | 2951 | pBA->OnShowFailure(); |
| 2851 | return 0; | 2952 | return 0; |
| 2852 | 2953 | ||
| 2954 | case WM_WIXSTDBA_PLAN_PREREQS: | ||
| 2955 | pBA->OnPlanPrereqs(static_cast<BOOTSTRAPPER_ACTION>(lParam)); | ||
| 2956 | return 0; | ||
| 2957 | |||
| 2853 | case WM_THMUTIL_CONTROL_WM_COMMAND: | 2958 | case WM_THMUTIL_CONTROL_WM_COMMAND: |
| 2854 | return pBA->OnThemeControlWmCommand(reinterpret_cast<THEME_CONTROLWMCOMMAND_ARGS*>(wParam), reinterpret_cast<THEME_CONTROLWMCOMMAND_RESULTS*>(lParam)); | 2959 | return pBA->OnThemeControlWmCommand(reinterpret_cast<THEME_CONTROLWMCOMMAND_ARGS*>(wParam), reinterpret_cast<THEME_CONTROLWMCOMMAND_RESULTS*>(lParam)); |
| 2855 | 2960 | ||
| @@ -3141,6 +3246,30 @@ private: | |||
| 3141 | 3246 | ||
| 3142 | 3247 | ||
| 3143 | // | 3248 | // |
| 3249 | // OnPlanPrereqs - preplan the packages to see if the preqba can be skipped. | ||
| 3250 | // | ||
| 3251 | void OnPlanPrereqs( | ||
| 3252 | __in BOOTSTRAPPER_ACTION action | ||
| 3253 | ) | ||
| 3254 | { | ||
| 3255 | HRESULT hr = S_OK; | ||
| 3256 | |||
| 3257 | m_plannedAction = action; | ||
| 3258 | |||
| 3259 | SetState(WIXSTDBA_STATE_PLANNING_PREREQS, hr); | ||
| 3260 | |||
| 3261 | hr = m_pEngine->Plan(action); | ||
| 3262 | BalExitOnFailure(hr, "Failed to start planning prereq packages."); | ||
| 3263 | |||
| 3264 | LExit: | ||
| 3265 | if (FAILED(hr)) | ||
| 3266 | { | ||
| 3267 | SetState(WIXSTDBA_STATE_PLANNING_PREREQS, hr); | ||
| 3268 | } | ||
| 3269 | } | ||
| 3270 | |||
| 3271 | |||
| 3272 | // | ||
| 3144 | // OnApply - apply the packages. | 3273 | // OnApply - apply the packages. |
| 3145 | // | 3274 | // |
| 3146 | void OnApply() | 3275 | void OnApply() |
| @@ -3838,6 +3967,8 @@ LExit: | |||
| 3838 | break; | 3967 | break; |
| 3839 | 3968 | ||
| 3840 | case WIXSTDBA_STATE_DETECTED: __fallthrough; | 3969 | case WIXSTDBA_STATE_DETECTED: __fallthrough; |
| 3970 | case WIXSTDBA_STATE_PLANNING_PREREQS: __fallthrough; | ||
| 3971 | case WIXSTDBA_STATE_PLANNED_PREREQS: __fallthrough; | ||
| 3841 | case WIXSTDBA_STATE_PLANNING: __fallthrough; | 3972 | case WIXSTDBA_STATE_PLANNING: __fallthrough; |
| 3842 | case WIXSTDBA_STATE_PLANNED: __fallthrough; | 3973 | case WIXSTDBA_STATE_PLANNED: __fallthrough; |
| 3843 | case WIXSTDBA_STATE_APPLYING: __fallthrough; | 3974 | case WIXSTDBA_STATE_APPLYING: __fallthrough; |
| @@ -3874,6 +4005,8 @@ LExit: | |||
| 3874 | break; | 4005 | break; |
| 3875 | 4006 | ||
| 3876 | case WIXSTDBA_STATE_DETECTED: | 4007 | case WIXSTDBA_STATE_DETECTED: |
| 4008 | case WIXSTDBA_STATE_PLANNING_PREREQS: __fallthrough; | ||
| 4009 | case WIXSTDBA_STATE_PLANNED_PREREQS: __fallthrough; | ||
| 3877 | switch (m_command.action) | 4010 | switch (m_command.action) |
| 3878 | { | 4011 | { |
| 3879 | case BOOTSTRAPPER_ACTION_INSTALL: | 4012 | case BOOTSTRAPPER_ACTION_INSTALL: |
| @@ -4124,7 +4257,10 @@ public: | |||
| 4124 | 4257 | ||
| 4125 | m_pPrereqData = pPrereqData; | 4258 | m_pPrereqData = pPrereqData; |
| 4126 | m_fPrereq = NULL != pPrereqData; | 4259 | m_fPrereq = NULL != pPrereqData; |
| 4260 | m_fPreplanPrereqs = m_fPrereq && m_pPrereqData->fAlwaysInstallPrereqs; | ||
| 4261 | m_fPrereqPackagePlanned = FALSE; | ||
| 4127 | m_fPrereqInstalled = FALSE; | 4262 | m_fPrereqInstalled = FALSE; |
| 4263 | m_fPrereqSkipped = FALSE; | ||
| 4128 | 4264 | ||
| 4129 | pEngine->AddRef(); | 4265 | pEngine->AddRef(); |
| 4130 | m_pEngine = pEngine; | 4266 | m_pEngine = pEngine; |
| @@ -4405,7 +4541,10 @@ private: | |||
| 4405 | 4541 | ||
| 4406 | PREQBA_DATA* m_pPrereqData; | 4542 | PREQBA_DATA* m_pPrereqData; |
| 4407 | BOOL m_fPrereq; | 4543 | BOOL m_fPrereq; |
| 4544 | BOOL m_fPreplanPrereqs; | ||
| 4545 | BOOL m_fPrereqPackagePlanned; | ||
| 4408 | BOOL m_fPrereqInstalled; | 4546 | BOOL m_fPrereqInstalled; |
| 4547 | BOOL m_fPrereqSkipped; | ||
| 4409 | 4548 | ||
| 4410 | ITaskbarList3* m_pTaskbarList; | 4549 | ITaskbarList3* m_pTaskbarList; |
| 4411 | UINT m_uTaskbarButtonCreatedMessage; | 4550 | UINT m_uTaskbarButtonCreatedMessage; |
diff --git a/src/ext/Bal/wixstdba/inc/preqba.h b/src/ext/Bal/wixstdba/inc/preqba.h index 93a547ed..ed339730 100644 --- a/src/ext/Bal/wixstdba/inc/preqba.h +++ b/src/ext/Bal/wixstdba/inc/preqba.h | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | struct PREQBA_DATA | 5 | struct PREQBA_DATA |
| 6 | { | 6 | { |
| 7 | HRESULT hrHostInitialization; | 7 | HRESULT hrHostInitialization; |
| 8 | BOOL fAlwaysInstallPrereqs; | ||
| 8 | BOOL fCompleted; | 9 | BOOL fCompleted; |
| 9 | }; | 10 | }; |
| 10 | 11 | ||
diff --git a/src/test/burn/TestBA/TestBA.cs b/src/test/burn/TestBA/TestBA.cs index 1548c05b..9ca82377 100644 --- a/src/test/burn/TestBA/TestBA.cs +++ b/src/test/burn/TestBA/TestBA.cs | |||
| @@ -146,6 +146,13 @@ namespace WixToolset.Test.BA | |||
| 146 | 146 | ||
| 147 | this.wait.WaitOne(); | 147 | this.wait.WaitOne(); |
| 148 | 148 | ||
| 149 | if (this.action == LaunchAction.Help) | ||
| 150 | { | ||
| 151 | this.Log("This is a BA for automated testing"); | ||
| 152 | this.Engine.Quit(0); | ||
| 153 | return; | ||
| 154 | } | ||
| 155 | |||
| 149 | this.redetectRemaining = redetectCount; | 156 | this.redetectRemaining = redetectCount; |
| 150 | for (int i = -1; i < redetectCount; i++) | 157 | for (int i = -1; i < redetectCount; i++) |
| 151 | { | 158 | { |
diff --git a/src/test/burn/TestData/PrereqBaTests/BundleA/BundleA.wixproj b/src/test/burn/TestData/PrereqBaTests/BundleA/BundleA.wixproj index 0199f91f..b084997c 100644 --- a/src/test/burn/TestData/PrereqBaTests/BundleA/BundleA.wixproj +++ b/src/test/burn/TestData/PrereqBaTests/BundleA/BundleA.wixproj | |||
| @@ -13,9 +13,12 @@ | |||
| 13 | </ItemGroup> | 13 | </ItemGroup> |
| 14 | <ItemGroup> | 14 | <ItemGroup> |
| 15 | <ProjectReference Include="..\PackageA\PackageA.wixproj" /> | 15 | <ProjectReference Include="..\PackageA\PackageA.wixproj" /> |
| 16 | <ProjectReference Include="..\PackageF\PackageF.wixproj" /> | 16 | <ProjectReference Include="..\PackageC\PackageC.wixproj" /> |
| 17 | <ProjectReference Include="..\PrereqBaf\PrereqBaf.vcxproj" /> | ||
| 18 | <ProjectReference Include="..\ReplaceConfig\ReplaceConfig.vcxproj" /> | ||
| 17 | </ItemGroup> | 19 | </ItemGroup> |
| 18 | <ItemGroup> | 20 | <ItemGroup> |
| 19 | <PackageReference Include="WixToolset.Bal.wixext" /> | 21 | <PackageReference Include="WixToolset.Bal.wixext" /> |
| 22 | <PackageReference Include="WixToolset.Util.wixext" /> | ||
| 20 | </ItemGroup> | 23 | </ItemGroup> |
| 21 | </Project> \ No newline at end of file | 24 | </Project> \ No newline at end of file |
diff --git a/src/test/burn/TestData/PrereqBaTests/BundleA/BundleA.wxs b/src/test/burn/TestData/PrereqBaTests/BundleA/BundleA.wxs index 682f0bd7..6073e09f 100644 --- a/src/test/burn/TestData/PrereqBaTests/BundleA/BundleA.wxs +++ b/src/test/burn/TestData/PrereqBaTests/BundleA/BundleA.wxs | |||
| @@ -1,22 +1,30 @@ | |||
| 1 | <!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. --> | 1 | <!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. --> |
| 2 | 2 | ||
| 3 | 3 | ||
| 4 | <Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:bal="http://wixtoolset.org/schemas/v4/wxs/bal"> | 4 | <Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:bal="http://wixtoolset.org/schemas/v4/wxs/bal" xmlns:util="http://wixtoolset.org/schemas/v4/wxs/util"> |
| 5 | <Fragment> | 5 | <Fragment> |
| 6 | <BootstrapperApplication Id="BrokenDnc"> | 6 | <BootstrapperApplication Id="BrokenDnc"> |
| 7 | <Payload SourceFile="!(bindpath.dncx86)\TestBA.deps.json" /> | 7 | <Payload SourceFile="!(bindpath.dncx86)\TestBA.deps.json" /> |
| 8 | <Payload SourceFile="!(bindpath.dncx86)\TestBA.dll" bal:BAFactoryAssembly="yes" /> | 8 | <Payload SourceFile="!(bindpath.dncx86)\TestBA.dll" bal:BAFactoryAssembly="yes" /> |
| 9 | <Payload Name="good.runtimeconfig.json" SourceFile="!(bindpath.dncx86)\TestBA.runtimeconfig.json" /> | ||
| 9 | <Payload Name="TestBA.runtimeconfig.json" SourceFile="bad.runtimeconfig.json" /> | 10 | <Payload Name="TestBA.runtimeconfig.json" SourceFile="bad.runtimeconfig.json" /> |
| 10 | <Payload SourceFile="!(bindpath.dncx86)\mbanative.dll" /> | 11 | <Payload SourceFile="!(bindpath.dncx86)\mbanative.dll" /> |
| 11 | <Payload SourceFile="!(bindpath.dncx86)\WixToolset.Mba.Core.dll" /> | 12 | <Payload SourceFile="!(bindpath.dncx86)\WixToolset.Mba.Core.dll" /> |
| 13 | <Payload SourceFile="$(var.PrereqBaf.TargetPath)" bal:BAFunctions="yes" /> | ||
| 12 | <bal:WixDotNetCoreBootstrapperApplicationHost /> | 14 | <bal:WixDotNetCoreBootstrapperApplicationHost /> |
| 13 | </BootstrapperApplication> | 15 | </BootstrapperApplication> |
| 14 | </Fragment> | 16 | </Fragment> |
| 15 | 17 | ||
| 16 | <Fragment> | 18 | <Fragment> |
| 19 | <util:FileSearch Variable="GoodConfigPresent" Path="[BARuntimeDirectory]\good.runtimeconfig.json" Result="exists" /> | ||
| 20 | <Variable Name="CAUSEINFINITELOOP" bal:Overridable="yes" /> | ||
| 21 | |||
| 17 | <PackageGroup Id="BundlePackages"> | 22 | <PackageGroup Id="BundlePackages"> |
| 23 | <ExePackage SourceFile="$(var.ReplaceConfig.TargetPath)" bal:PrereqPackage="yes" | ||
| 24 | Permanent="yes" DetectCondition="NOT GoodConfigPresent OR CAUSEINFINITELOOP = 1" | ||
| 25 | InstallArguments=""[BARuntimeDirectory]TestBA.runtimeconfig.json" "[BARuntimeDirectory]good.runtimeconfig.json" "[BARuntimeDirectory]bad.runtimeconfig.json"" /> | ||
| 18 | <MsiPackage Id="PackageA" SourceFile="$(var.PackageA.TargetPath)" bal:PrereqPackage="yes" Permanent="yes" /> | 26 | <MsiPackage Id="PackageA" SourceFile="$(var.PackageA.TargetPath)" bal:PrereqPackage="yes" Permanent="yes" /> |
| 19 | <MsiPackage Id="PackageF" SourceFile="$(var.PackageF.TargetPath)" Cache="force" /> | 27 | <MsiPackage Id="PackageC" SourceFile="$(var.PackageC.TargetPath)" Cache="force" /> |
| 20 | </PackageGroup> | 28 | </PackageGroup> |
| 21 | </Fragment> | 29 | </Fragment> |
| 22 | </Wix> | 30 | </Wix> |
diff --git a/src/test/burn/TestData/PrereqBaTests/BundleB/BundleB.wixproj b/src/test/burn/TestData/PrereqBaTests/BundleB/BundleB.wixproj index d4288d4b..843b382a 100644 --- a/src/test/burn/TestData/PrereqBaTests/BundleB/BundleB.wixproj +++ b/src/test/burn/TestData/PrereqBaTests/BundleB/BundleB.wixproj | |||
| @@ -13,9 +13,12 @@ | |||
| 13 | </ItemGroup> | 13 | </ItemGroup> |
| 14 | <ItemGroup> | 14 | <ItemGroup> |
| 15 | <ProjectReference Include="..\PackageB\PackageB.wixproj" /> | 15 | <ProjectReference Include="..\PackageB\PackageB.wixproj" /> |
| 16 | <ProjectReference Include="..\PackageF\PackageF.wixproj" /> | 16 | <ProjectReference Include="..\PackageC\PackageC.wixproj" /> |
| 17 | <ProjectReference Include="..\PrereqBaf\PrereqBaf.vcxproj" /> | ||
| 18 | <ProjectReference Include="..\ReplaceConfig\ReplaceConfig.vcxproj" /> | ||
| 17 | </ItemGroup> | 19 | </ItemGroup> |
| 18 | <ItemGroup> | 20 | <ItemGroup> |
| 19 | <PackageReference Include="WixToolset.Bal.wixext" /> | 21 | <PackageReference Include="WixToolset.Bal.wixext" /> |
| 22 | <PackageReference Include="WixToolset.Util.wixext" /> | ||
| 20 | </ItemGroup> | 23 | </ItemGroup> |
| 21 | </Project> \ No newline at end of file | 24 | </Project> \ No newline at end of file |
diff --git a/src/test/burn/TestData/PrereqBaTests/BundleB/BundleB.wxs b/src/test/burn/TestData/PrereqBaTests/BundleB/BundleB.wxs index 603c3aee..b7742582 100644 --- a/src/test/burn/TestData/PrereqBaTests/BundleB/BundleB.wxs +++ b/src/test/burn/TestData/PrereqBaTests/BundleB/BundleB.wxs | |||
| @@ -1,21 +1,29 @@ | |||
| 1 | <!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. --> | 1 | <!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. --> |
| 2 | 2 | ||
| 3 | 3 | ||
| 4 | <Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:bal="http://wixtoolset.org/schemas/v4/wxs/bal"> | 4 | <Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:bal="http://wixtoolset.org/schemas/v4/wxs/bal" xmlns:util="http://wixtoolset.org/schemas/v4/wxs/util"> |
| 5 | <Fragment> | 5 | <Fragment> |
| 6 | <BootstrapperApplication Id="BrokenMba"> | 6 | <BootstrapperApplication Id="BrokenMba"> |
| 7 | <Payload Name="good.config" SourceFile="!(bindpath.net2x86)\TestBA.BootstrapperCore.config" /> | ||
| 7 | <Payload Name="WixToolset.Mba.Host.config" SourceFile="bad.config" /> | 8 | <Payload Name="WixToolset.Mba.Host.config" SourceFile="bad.config" /> |
| 8 | <Payload SourceFile="!(bindpath.net2x86)\TestBA.dll" /> | 9 | <Payload SourceFile="!(bindpath.net2x86)\TestBA.dll" /> |
| 9 | <Payload SourceFile="!(bindpath.net2x86)\mbanative.dll" /> | 10 | <Payload SourceFile="!(bindpath.net2x86)\mbanative.dll" /> |
| 10 | <Payload SourceFile="!(bindpath.net2x86)\WixToolset.Mba.Core.dll" /> | 11 | <Payload SourceFile="!(bindpath.net2x86)\WixToolset.Mba.Core.dll" /> |
| 12 | <Payload SourceFile="$(var.PrereqBaf.TargetPath)" bal:BAFunctions="yes" /> | ||
| 11 | <bal:WixManagedBootstrapperApplicationHost /> | 13 | <bal:WixManagedBootstrapperApplicationHost /> |
| 12 | </BootstrapperApplication> | 14 | </BootstrapperApplication> |
| 13 | </Fragment> | 15 | </Fragment> |
| 14 | 16 | ||
| 15 | <Fragment> | 17 | <Fragment> |
| 18 | <util:FileSearch Variable="GoodConfigPresent" Path="[BARuntimeDirectory]\good.config" Result="exists" /> | ||
| 19 | <Variable Name="CAUSEINFINITELOOP" bal:Overridable="yes" /> | ||
| 20 | |||
| 16 | <PackageGroup Id="BundlePackages"> | 21 | <PackageGroup Id="BundlePackages"> |
| 22 | <ExePackage SourceFile="$(var.ReplaceConfig.TargetPath)" bal:PrereqPackage="yes" | ||
| 23 | Permanent="yes" DetectCondition="NOT GoodConfigPresent OR CAUSEINFINITELOOP = 1" | ||
| 24 | InstallArguments=""[BARuntimeDirectory]WixToolset.Mba.Host.config" "[BARuntimeDirectory]good.config" "[BARuntimeDirectory]bad.config"" /> | ||
| 17 | <MsiPackage Id="PackageB" SourceFile="$(var.PackageB.TargetPath)" bal:PrereqPackage="yes" Permanent="yes" /> | 25 | <MsiPackage Id="PackageB" SourceFile="$(var.PackageB.TargetPath)" bal:PrereqPackage="yes" Permanent="yes" /> |
| 18 | <MsiPackage Id="PackageF" SourceFile="$(var.PackageF.TargetPath)" /> | 26 | <MsiPackage Id="PackageC" SourceFile="$(var.PackageC.TargetPath)" /> |
| 19 | </PackageGroup> | 27 | </PackageGroup> |
| 20 | </Fragment> | 28 | </Fragment> |
| 21 | </Wix> | 29 | </Wix> |
diff --git a/src/test/burn/TestData/PrereqBaTests/BundleC/BundleC.wixproj b/src/test/burn/TestData/PrereqBaTests/BundleC/BundleC.wixproj new file mode 100644 index 00000000..81641f66 --- /dev/null +++ b/src/test/burn/TestData/PrereqBaTests/BundleC/BundleC.wixproj | |||
| @@ -0,0 +1,24 @@ | |||
| 1 | <!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. --> | ||
| 2 | <Project Sdk="WixToolset.Sdk"> | ||
| 3 | <PropertyGroup> | ||
| 4 | <OutputType>Bundle</OutputType> | ||
| 5 | <BA>BrokenDncAlwaysPrereq</BA> | ||
| 6 | <UpgradeCode>{D2763AB7-979B-485C-AE52-DD03C23CCB93}</UpgradeCode> | ||
| 7 | </PropertyGroup> | ||
| 8 | <ItemGroup> | ||
| 9 | <Compile Include="..\..\Templates\Bundle.wxs" Link="Bundle.wxs" /> | ||
| 10 | </ItemGroup> | ||
| 11 | <ItemGroup> | ||
| 12 | <BindInputPaths Include="$(BaseOutputPath)$(Configuration)\net6.0-windows\win-x86" BindName="dncx86" /> | ||
| 13 | </ItemGroup> | ||
| 14 | <ItemGroup> | ||
| 15 | <ProjectReference Include="..\PackageA\PackageA.wixproj" /> | ||
| 16 | <ProjectReference Include="..\PackageC\PackageC.wixproj" /> | ||
| 17 | <ProjectReference Include="..\PrereqBaf\PrereqBaf.vcxproj" /> | ||
| 18 | <ProjectReference Include="..\ReplaceConfig\ReplaceConfig.vcxproj" /> | ||
| 19 | </ItemGroup> | ||
| 20 | <ItemGroup> | ||
| 21 | <PackageReference Include="WixToolset.Bal.wixext" /> | ||
| 22 | <PackageReference Include="WixToolset.Util.wixext" /> | ||
| 23 | </ItemGroup> | ||
| 24 | </Project> \ No newline at end of file | ||
diff --git a/src/test/burn/TestData/PrereqBaTests/BundleC/BundleC.wxs b/src/test/burn/TestData/PrereqBaTests/BundleC/BundleC.wxs new file mode 100644 index 00000000..fe9425f7 --- /dev/null +++ b/src/test/burn/TestData/PrereqBaTests/BundleC/BundleC.wxs | |||
| @@ -0,0 +1,30 @@ | |||
| 1 | <!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. --> | ||
| 2 | |||
| 3 | |||
| 4 | <Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:bal="http://wixtoolset.org/schemas/v4/wxs/bal" xmlns:util="http://wixtoolset.org/schemas/v4/wxs/util"> | ||
| 5 | <Fragment> | ||
| 6 | <BootstrapperApplication Id="BrokenDncAlwaysPrereq"> | ||
| 7 | <Payload SourceFile="!(bindpath.dncx86)\TestBA.deps.json" /> | ||
| 8 | <Payload SourceFile="!(bindpath.dncx86)\TestBA.dll" bal:BAFactoryAssembly="yes" /> | ||
| 9 | <Payload Name="good.runtimeconfig.json" SourceFile="!(bindpath.dncx86)\TestBA.runtimeconfig.json" /> | ||
| 10 | <Payload Name="TestBA.runtimeconfig.json" SourceFile="bad.runtimeconfig.json" /> | ||
| 11 | <Payload SourceFile="!(bindpath.dncx86)\mbanative.dll" /> | ||
| 12 | <Payload SourceFile="!(bindpath.dncx86)\WixToolset.Mba.Core.dll" /> | ||
| 13 | <Payload SourceFile="$(var.PrereqBaf.TargetPath)" bal:BAFunctions="yes" /> | ||
| 14 | <bal:WixDotNetCoreBootstrapperApplicationHost AlwaysInstallPrereqs="yes" /> | ||
| 15 | </BootstrapperApplication> | ||
| 16 | </Fragment> | ||
| 17 | |||
| 18 | <Fragment> | ||
| 19 | <util:FileSearch Variable="GoodConfigPresent" Path="[BARuntimeDirectory]\good.runtimeconfig.json" Result="exists" /> | ||
| 20 | <Variable Name="CAUSEINFINITELOOP" bal:Overridable="yes" /> | ||
| 21 | |||
| 22 | <PackageGroup Id="BundlePackages"> | ||
| 23 | <ExePackage SourceFile="$(var.ReplaceConfig.TargetPath)" bal:PrereqPackage="yes" | ||
| 24 | Permanent="yes" DetectCondition="NOT GoodConfigPresent OR CAUSEINFINITELOOP = 1" | ||
| 25 | InstallArguments=""[BARuntimeDirectory]TestBA.runtimeconfig.json" "[BARuntimeDirectory]good.runtimeconfig.json" "[BARuntimeDirectory]bad.runtimeconfig.json"" /> | ||
| 26 | <MsiPackage Id="PackageA" SourceFile="$(var.PackageA.TargetPath)" bal:PrereqPackage="yes" Permanent="yes" /> | ||
| 27 | <MsiPackage Id="PackageC" SourceFile="$(var.PackageC.TargetPath)" Cache="force" /> | ||
| 28 | </PackageGroup> | ||
| 29 | </Fragment> | ||
| 30 | </Wix> | ||
diff --git a/src/test/burn/TestData/PrereqBaTests/BundleC/bad.runtimeconfig.json b/src/test/burn/TestData/PrereqBaTests/BundleC/bad.runtimeconfig.json new file mode 100644 index 00000000..07a1a830 --- /dev/null +++ b/src/test/burn/TestData/PrereqBaTests/BundleC/bad.runtimeconfig.json | |||
| @@ -0,0 +1,10 @@ | |||
| 1 | { | ||
| 2 | "runtimeOptions": { | ||
| 3 | "tfm": "net5.5", | ||
| 4 | "rollForward": "Disable", | ||
| 5 | "framework": { | ||
| 6 | "name": "Microsoft.WindowsDesktop.App", | ||
| 7 | "version": "5.5.0" | ||
| 8 | } | ||
| 9 | } | ||
| 10 | } \ No newline at end of file | ||
diff --git a/src/test/burn/TestData/PrereqBaTests/BundleD/BundleD.wixproj b/src/test/burn/TestData/PrereqBaTests/BundleD/BundleD.wixproj new file mode 100644 index 00000000..314fe2e2 --- /dev/null +++ b/src/test/burn/TestData/PrereqBaTests/BundleD/BundleD.wixproj | |||
| @@ -0,0 +1,24 @@ | |||
| 1 | <!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. --> | ||
| 2 | <Project Sdk="WixToolset.Sdk"> | ||
| 3 | <PropertyGroup> | ||
| 4 | <OutputType>Bundle</OutputType> | ||
| 5 | <BA>BrokenMbaAlwaysPrereq</BA> | ||
| 6 | <UpgradeCode>{415CA128-60E1-4D16-ACE8-A1D43E98B997}</UpgradeCode> | ||
| 7 | </PropertyGroup> | ||
| 8 | <ItemGroup> | ||
| 9 | <Compile Include="..\..\Templates\Bundle.wxs" Link="Bundle.wxs" /> | ||
| 10 | </ItemGroup> | ||
| 11 | <ItemGroup> | ||
| 12 | <BindInputPaths Include="$(BaseOutputPath)$(Configuration)\net35\win-x86" BindName="net2x86" /> | ||
| 13 | </ItemGroup> | ||
| 14 | <ItemGroup> | ||
| 15 | <ProjectReference Include="..\PackageB\PackageB.wixproj" /> | ||
| 16 | <ProjectReference Include="..\PackageC\PackageC.wixproj" /> | ||
| 17 | <ProjectReference Include="..\PrereqBaf\PrereqBaf.vcxproj" /> | ||
| 18 | <ProjectReference Include="..\ReplaceConfig\ReplaceConfig.vcxproj" /> | ||
| 19 | </ItemGroup> | ||
| 20 | <ItemGroup> | ||
| 21 | <PackageReference Include="WixToolset.Bal.wixext" /> | ||
| 22 | <PackageReference Include="WixToolset.Util.wixext" /> | ||
| 23 | </ItemGroup> | ||
| 24 | </Project> \ No newline at end of file | ||
diff --git a/src/test/burn/TestData/PrereqBaTests/BundleD/BundleD.wxs b/src/test/burn/TestData/PrereqBaTests/BundleD/BundleD.wxs new file mode 100644 index 00000000..0e866295 --- /dev/null +++ b/src/test/burn/TestData/PrereqBaTests/BundleD/BundleD.wxs | |||
| @@ -0,0 +1,29 @@ | |||
| 1 | <!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. --> | ||
| 2 | |||
| 3 | |||
| 4 | <Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:bal="http://wixtoolset.org/schemas/v4/wxs/bal" xmlns:util="http://wixtoolset.org/schemas/v4/wxs/util"> | ||
| 5 | <Fragment> | ||
| 6 | <BootstrapperApplication Id="BrokenMbaAlwaysPrereq"> | ||
| 7 | <Payload Name="good.config" SourceFile="!(bindpath.net2x86)\TestBA.BootstrapperCore.config" /> | ||
| 8 | <Payload Name="WixToolset.Mba.Host.config" SourceFile="bad.config" /> | ||
| 9 | <Payload SourceFile="!(bindpath.net2x86)\TestBA.dll" /> | ||
| 10 | <Payload SourceFile="!(bindpath.net2x86)\mbanative.dll" /> | ||
| 11 | <Payload SourceFile="!(bindpath.net2x86)\WixToolset.Mba.Core.dll" /> | ||
| 12 | <Payload SourceFile="$(var.PrereqBaf.TargetPath)" bal:BAFunctions="yes" /> | ||
| 13 | <bal:WixManagedBootstrapperApplicationHost AlwaysInstallPrereqs="yes" /> | ||
| 14 | </BootstrapperApplication> | ||
| 15 | </Fragment> | ||
| 16 | |||
| 17 | <Fragment> | ||
| 18 | <util:FileSearch Variable="GoodConfigPresent" Path="[BARuntimeDirectory]\good.config" Result="exists" /> | ||
| 19 | <Variable Name="CAUSEINFINITELOOP" bal:Overridable="yes" /> | ||
| 20 | |||
| 21 | <PackageGroup Id="BundlePackages"> | ||
| 22 | <ExePackage SourceFile="$(var.ReplaceConfig.TargetPath)" bal:PrereqPackage="yes" | ||
| 23 | Permanent="yes" DetectCondition="NOT GoodConfigPresent OR CAUSEINFINITELOOP = 1" | ||
| 24 | InstallArguments=""[BARuntimeDirectory]WixToolset.Mba.Host.config" "[BARuntimeDirectory]good.config" "[BARuntimeDirectory]bad.config"" /> | ||
| 25 | <MsiPackage Id="PackageB" SourceFile="$(var.PackageB.TargetPath)" bal:PrereqPackage="yes" Permanent="yes" /> | ||
| 26 | <MsiPackage Id="PackageC" SourceFile="$(var.PackageC.TargetPath)" /> | ||
| 27 | </PackageGroup> | ||
| 28 | </Fragment> | ||
| 29 | </Wix> | ||
diff --git a/src/test/burn/TestData/PrereqBaTests/BundleD/bad.config b/src/test/burn/TestData/PrereqBaTests/BundleD/bad.config new file mode 100644 index 00000000..1512e59a --- /dev/null +++ b/src/test/burn/TestData/PrereqBaTests/BundleD/bad.config | |||
| @@ -0,0 +1,17 @@ | |||
| 1 | <?xml version="1.0" encoding="utf-8" ?> | ||
| 2 | <!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. --> | ||
| 3 | |||
| 4 | |||
| 5 | <configuration> | ||
| 6 | <configSections> | ||
| 7 | <sectionGroup name="wix.bootstrapper" type="WixToolset.Mba.Host.BootstrapperSectionGroup, WixToolset.Mba.Host"> | ||
| 8 | <section name="host" type="WixToolset.Mba.Host.HostSection, WixToolset.Mba.Host" /> | ||
| 9 | </sectionGroup> | ||
| 10 | </configSections> | ||
| 11 | <startup> | ||
| 12 | <supportedRuntime version="v4.0" sku=".NETFramework,Version=v5.8" /> | ||
| 13 | </startup> | ||
| 14 | <wix.bootstrapper> | ||
| 15 | <host assemblyName="TestBA" /> | ||
| 16 | </wix.bootstrapper> | ||
| 17 | </configuration> | ||
diff --git a/src/test/burn/TestData/PrereqBaTests/BundleE/BundleE.wixproj b/src/test/burn/TestData/PrereqBaTests/BundleE/BundleE.wixproj new file mode 100644 index 00000000..5d271f55 --- /dev/null +++ b/src/test/burn/TestData/PrereqBaTests/BundleE/BundleE.wixproj | |||
| @@ -0,0 +1,22 @@ | |||
| 1 | <!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. --> | ||
| 2 | <Project Sdk="WixToolset.Sdk"> | ||
| 3 | <PropertyGroup> | ||
| 4 | <OutputType>Bundle</OutputType> | ||
| 5 | <BA>DncAlwaysPrereq</BA> | ||
| 6 | <UpgradeCode>{2F61ECD8-C28B-4FF9-9609-0E9633716CF9}</UpgradeCode> | ||
| 7 | </PropertyGroup> | ||
| 8 | <ItemGroup> | ||
| 9 | <Compile Include="..\..\Templates\Bundle.wxs" Link="Bundle.wxs" /> | ||
| 10 | </ItemGroup> | ||
| 11 | <ItemGroup> | ||
| 12 | <BindInputPaths Include="$(BaseOutputPath)$(Configuration)\net6.0-windows\win-x86" BindName="dncx86" /> | ||
| 13 | </ItemGroup> | ||
| 14 | <ItemGroup> | ||
| 15 | <ProjectReference Include="..\PrereqBaf\PrereqBaf.vcxproj" /> | ||
| 16 | <ProjectReference Include="..\ReplaceConfig\ReplaceConfig.vcxproj" /> | ||
| 17 | </ItemGroup> | ||
| 18 | <ItemGroup> | ||
| 19 | <PackageReference Include="WixToolset.Bal.wixext" /> | ||
| 20 | <PackageReference Include="WixToolset.Util.wixext" /> | ||
| 21 | </ItemGroup> | ||
| 22 | </Project> \ No newline at end of file | ||
diff --git a/src/test/burn/TestData/PrereqBaTests/BundleE/BundleE.wxs b/src/test/burn/TestData/PrereqBaTests/BundleE/BundleE.wxs new file mode 100644 index 00000000..5f2e6a75 --- /dev/null +++ b/src/test/burn/TestData/PrereqBaTests/BundleE/BundleE.wxs | |||
| @@ -0,0 +1,26 @@ | |||
| 1 | <!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. --> | ||
| 2 | |||
| 3 | |||
| 4 | <Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:bal="http://wixtoolset.org/schemas/v4/wxs/bal" xmlns:util="http://wixtoolset.org/schemas/v4/wxs/util"> | ||
| 5 | <Fragment> | ||
| 6 | <BootstrapperApplication Id="DncAlwaysPrereq"> | ||
| 7 | <Payload SourceFile="!(bindpath.dncx86)\TestBA.deps.json" /> | ||
| 8 | <Payload SourceFile="!(bindpath.dncx86)\TestBA.dll" bal:BAFactoryAssembly="yes" /> | ||
| 9 | <Payload SourceFile="!(bindpath.dncx86)\TestBA.runtimeconfig.json" /> | ||
| 10 | <Payload SourceFile="!(bindpath.dncx86)\mbanative.dll" /> | ||
| 11 | <Payload SourceFile="!(bindpath.dncx86)\WixToolset.Mba.Core.dll" /> | ||
| 12 | <Payload SourceFile="$(var.PrereqBaf.TargetPath)" bal:BAFunctions="yes" /> | ||
| 13 | <bal:WixDotNetCoreBootstrapperApplicationHost AlwaysInstallPrereqs="yes" /> | ||
| 14 | </BootstrapperApplication> | ||
| 15 | </Fragment> | ||
| 16 | |||
| 17 | <Fragment> | ||
| 18 | <util:FileSearch Variable="GoodConfigPresent" Path="[BARuntimeDirectory]\good.runtimeconfig.json" Result="exists" /> | ||
| 19 | |||
| 20 | <PackageGroup Id="BundlePackages"> | ||
| 21 | <ExePackage SourceFile="$(var.ReplaceConfig.TargetPath)" bal:PrereqPackage="yes" | ||
| 22 | Permanent="yes" DetectCondition="NOT GoodConfigPresent" | ||
| 23 | InstallArguments=""[BARuntimeDirectory]TestBA.runtimeconfig.json" "[BARuntimeDirectory]good.runtimeconfig.json" "[BARuntimeDirectory]bad.runtimeconfig.json"" /> | ||
| 24 | </PackageGroup> | ||
| 25 | </Fragment> | ||
| 26 | </Wix> | ||
diff --git a/src/test/burn/TestData/PrereqBaTests/PackageF/PackageF.wixproj b/src/test/burn/TestData/PrereqBaTests/PackageC/PackageC.wixproj index 00ffb7d8..1c8c4fa8 100644 --- a/src/test/burn/TestData/PrereqBaTests/PackageF/PackageF.wixproj +++ b/src/test/burn/TestData/PrereqBaTests/PackageC/PackageC.wixproj | |||
| @@ -4,9 +4,6 @@ | |||
| 4 | <UpgradeCode>{7DEEE928-CD7F-49AD-8000-2ED6339D8A78}</UpgradeCode> | 4 | <UpgradeCode>{7DEEE928-CD7F-49AD-8000-2ED6339D8A78}</UpgradeCode> |
| 5 | </PropertyGroup> | 5 | </PropertyGroup> |
| 6 | <ItemGroup> | 6 | <ItemGroup> |
| 7 | <Compile Include="..\..\Templates\PackageFail.wxs" Link="PackageFail.wxs" /> | 7 | <Compile Include="..\..\Templates\Package.wxs" Link="Package.wxs" /> |
| 8 | </ItemGroup> | ||
| 9 | <ItemGroup> | ||
| 10 | <PackageReference Include="WixToolset.Util.wixext" /> | ||
| 11 | </ItemGroup> | 8 | </ItemGroup> |
| 12 | </Project> \ No newline at end of file | 9 | </Project> \ No newline at end of file |
diff --git a/src/test/burn/TestData/PrereqBaTests/PrereqBaf/PrereqBaf.cpp b/src/test/burn/TestData/PrereqBaTests/PrereqBaf/PrereqBaf.cpp new file mode 100644 index 00000000..35949eb9 --- /dev/null +++ b/src/test/burn/TestData/PrereqBaTests/PrereqBaf/PrereqBaf.cpp | |||
| @@ -0,0 +1,79 @@ | |||
| 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | ||
| 2 | |||
| 3 | #include "precomp.h" | ||
| 4 | #include "BalBaseBAFunctions.h" | ||
| 5 | #include "BalBaseBAFunctionsProc.h" | ||
| 6 | |||
| 7 | class CPrereqBaf : public CBalBaseBAFunctions | ||
| 8 | { | ||
| 9 | public: // IBAFunctions | ||
| 10 | |||
| 11 | public: //IBootstrapperApplication | ||
| 12 | |||
| 13 | virtual STDMETHODIMP OnDetectBegin( | ||
| 14 | __in BOOL /*fCached*/, | ||
| 15 | __in BOOTSTRAPPER_REGISTRATION_TYPE /*registrationType*/, | ||
| 16 | __in DWORD /*cPackages*/, | ||
| 17 | __inout BOOL* /*pfCancel*/ | ||
| 18 | ) | ||
| 19 | { | ||
| 20 | HRESULT hr = S_OK; | ||
| 21 | |||
| 22 | hr = m_pEngine->SetVariableString(L"BARuntimeDirectory", m_command.wzBootstrapperWorkingFolder, FALSE); | ||
| 23 | ExitOnFailure(hr, "Failed to set BARuntimeDirectory"); | ||
| 24 | |||
| 25 | LExit: | ||
| 26 | return hr; | ||
| 27 | } | ||
| 28 | |||
| 29 | private: | ||
| 30 | |||
| 31 | public: | ||
| 32 | // | ||
| 33 | // Constructor - initialize member variables. | ||
| 34 | // | ||
| 35 | CPrereqBaf( | ||
| 36 | __in HMODULE hModule, | ||
| 37 | __in IBootstrapperEngine* pEngine, | ||
| 38 | __in const BA_FUNCTIONS_CREATE_ARGS* pArgs | ||
| 39 | ) : CBalBaseBAFunctions(hModule, pEngine, pArgs) | ||
| 40 | { | ||
| 41 | } | ||
| 42 | |||
| 43 | // | ||
| 44 | // Destructor - release member variables. | ||
| 45 | // | ||
| 46 | ~CPrereqBaf() | ||
| 47 | { | ||
| 48 | } | ||
| 49 | |||
| 50 | private: | ||
| 51 | }; | ||
| 52 | |||
| 53 | |||
| 54 | HRESULT WINAPI CreateBAFunctions( | ||
| 55 | __in HMODULE hModule, | ||
| 56 | __in const BA_FUNCTIONS_CREATE_ARGS* pArgs, | ||
| 57 | __inout BA_FUNCTIONS_CREATE_RESULTS* pResults | ||
| 58 | ) | ||
| 59 | { | ||
| 60 | HRESULT hr = S_OK; | ||
| 61 | CPrereqBaf* pBAFunctions = NULL; | ||
| 62 | IBootstrapperEngine* pEngine = NULL; | ||
| 63 | |||
| 64 | hr = BalInitializeFromCreateArgs(pArgs->pBootstrapperCreateArgs, &pEngine); | ||
| 65 | ExitOnFailure(hr, "Failed to initialize Bal."); | ||
| 66 | |||
| 67 | pBAFunctions = new CPrereqBaf(hModule, pEngine, pArgs); | ||
| 68 | ExitOnNull(pBAFunctions, hr, E_OUTOFMEMORY, "Failed to create new CPrereqBaf object."); | ||
| 69 | |||
| 70 | pResults->pfnBAFunctionsProc = BalBaseBAFunctionsProc; | ||
| 71 | pResults->pvBAFunctionsProcContext = pBAFunctions; | ||
| 72 | pBAFunctions = NULL; | ||
| 73 | |||
| 74 | LExit: | ||
| 75 | ReleaseObject(pBAFunctions); | ||
| 76 | ReleaseObject(pEngine); | ||
| 77 | |||
| 78 | return hr; | ||
| 79 | } | ||
diff --git a/src/test/burn/TestData/PrereqBaTests/PrereqBaf/PrereqBaf.def b/src/test/burn/TestData/PrereqBaTests/PrereqBaf/PrereqBaf.def new file mode 100644 index 00000000..6e016dad --- /dev/null +++ b/src/test/burn/TestData/PrereqBaTests/PrereqBaf/PrereqBaf.def | |||
| @@ -0,0 +1,6 @@ | |||
| 1 | ; Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | ||
| 2 | |||
| 3 | |||
| 4 | EXPORTS | ||
| 5 | BAFunctionsCreate | ||
| 6 | BAFunctionsDestroy | ||
diff --git a/src/test/burn/TestData/PrereqBaTests/PrereqBaf/PrereqBaf.vcxproj b/src/test/burn/TestData/PrereqBaTests/PrereqBaf/PrereqBaf.vcxproj new file mode 100644 index 00000000..0d8d63be --- /dev/null +++ b/src/test/burn/TestData/PrereqBaTests/PrereqBaf/PrereqBaf.vcxproj | |||
| @@ -0,0 +1,66 @@ | |||
| 1 | <?xml version="1.0" encoding="utf-8"?> | ||
| 2 | <!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. --> | ||
| 3 | |||
| 4 | <Project DefaultTargets="Build" Toolsxmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | ||
| 5 | <ItemGroup Label="ProjectConfigurations"> | ||
| 6 | <ProjectConfiguration Include="Debug|ARM64"> | ||
| 7 | <Configuration>Debug</Configuration> | ||
| 8 | <Platform>ARM64</Platform> | ||
| 9 | </ProjectConfiguration> | ||
| 10 | <ProjectConfiguration Include="Release|ARM64"> | ||
| 11 | <Configuration>Release</Configuration> | ||
| 12 | <Platform>ARM64</Platform> | ||
| 13 | </ProjectConfiguration> | ||
| 14 | <ProjectConfiguration Include="Debug|Win32"> | ||
| 15 | <Configuration>Debug</Configuration> | ||
| 16 | <Platform>Win32</Platform> | ||
| 17 | </ProjectConfiguration> | ||
| 18 | <ProjectConfiguration Include="Release|Win32"> | ||
| 19 | <Configuration>Release</Configuration> | ||
| 20 | <Platform>Win32</Platform> | ||
| 21 | </ProjectConfiguration> | ||
| 22 | <ProjectConfiguration Include="Debug|x64"> | ||
| 23 | <Configuration>Debug</Configuration> | ||
| 24 | <Platform>x64</Platform> | ||
| 25 | </ProjectConfiguration> | ||
| 26 | <ProjectConfiguration Include="Release|x64"> | ||
| 27 | <Configuration>Release</Configuration> | ||
| 28 | <Platform>x64</Platform> | ||
| 29 | </ProjectConfiguration> | ||
| 30 | </ItemGroup> | ||
| 31 | |||
| 32 | <PropertyGroup Label="Globals"> | ||
| 33 | <ProjectGuid>{C0A11DDB-6CCE-44EC-88FD-93910C2916E3}</ProjectGuid> | ||
| 34 | <ConfigurationType>DynamicLibrary</ConfigurationType> | ||
| 35 | <CharacterSet>Unicode</CharacterSet> | ||
| 36 | <TargetName>PrereqBaf</TargetName> | ||
| 37 | <ProjectModuleDefinitionFile>PrereqBaf.def</ProjectModuleDefinitionFile> | ||
| 38 | <IsWixTestProject>true</IsWixTestProject> | ||
| 39 | </PropertyGroup> | ||
| 40 | |||
| 41 | <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> | ||
| 42 | <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> | ||
| 43 | |||
| 44 | <PropertyGroup> | ||
| 45 | <ProjectAdditionalLinkLibraries>comctl32.lib;gdiplus.lib;msimg32.lib;shlwapi.lib;wininet.lib</ProjectAdditionalLinkLibraries> | ||
| 46 | </PropertyGroup> | ||
| 47 | |||
| 48 | <ItemGroup> | ||
| 49 | <ClCompile Include="precomp.cpp"> | ||
| 50 | <PrecompiledHeader>Create</PrecompiledHeader> | ||
| 51 | </ClCompile> | ||
| 52 | <ClCompile Include="PrereqBaf.cpp" /> | ||
| 53 | </ItemGroup> | ||
| 54 | <ItemGroup> | ||
| 55 | <ClInclude Include="precomp.h" /> | ||
| 56 | </ItemGroup> | ||
| 57 | <ItemGroup> | ||
| 58 | <None Include="PrereqBaf.def" /> | ||
| 59 | </ItemGroup> | ||
| 60 | |||
| 61 | <ItemGroup> | ||
| 62 | <PackageReference Include="WixToolset.BalUtil" /> | ||
| 63 | </ItemGroup> | ||
| 64 | |||
| 65 | <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> | ||
| 66 | </Project> | ||
diff --git a/src/test/burn/TestData/PrereqBaTests/PrereqBaf/precomp.cpp b/src/test/burn/TestData/PrereqBaTests/PrereqBaf/precomp.cpp new file mode 100644 index 00000000..fc9d1177 --- /dev/null +++ b/src/test/burn/TestData/PrereqBaTests/PrereqBaf/precomp.cpp | |||
| @@ -0,0 +1,48 @@ | |||
| 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | ||
| 2 | |||
| 3 | #include "precomp.h" | ||
| 4 | |||
| 5 | static HINSTANCE vhInstance = NULL; | ||
| 6 | |||
| 7 | extern "C" BOOL WINAPI DllMain( | ||
| 8 | IN HINSTANCE hInstance, | ||
| 9 | IN DWORD dwReason, | ||
| 10 | IN LPVOID /* pvReserved */ | ||
| 11 | ) | ||
| 12 | { | ||
| 13 | switch (dwReason) | ||
| 14 | { | ||
| 15 | case DLL_PROCESS_ATTACH: | ||
| 16 | ::DisableThreadLibraryCalls(hInstance); | ||
| 17 | vhInstance = hInstance; | ||
| 18 | break; | ||
| 19 | |||
| 20 | case DLL_PROCESS_DETACH: | ||
| 21 | vhInstance = NULL; | ||
| 22 | break; | ||
| 23 | } | ||
| 24 | |||
| 25 | return TRUE; | ||
| 26 | } | ||
| 27 | |||
| 28 | extern "C" HRESULT WINAPI BAFunctionsCreate( | ||
| 29 | __in const BA_FUNCTIONS_CREATE_ARGS* pArgs, | ||
| 30 | __inout BA_FUNCTIONS_CREATE_RESULTS* pResults | ||
| 31 | ) | ||
| 32 | { | ||
| 33 | HRESULT hr = S_OK; | ||
| 34 | |||
| 35 | hr = CreateBAFunctions(vhInstance, pArgs, pResults); | ||
| 36 | BalExitOnFailure(hr, "Failed to create BAFunctions interface."); | ||
| 37 | |||
| 38 | LExit: | ||
| 39 | return hr; | ||
| 40 | } | ||
| 41 | |||
| 42 | extern "C" void WINAPI BAFunctionsDestroy( | ||
| 43 | __in const BA_FUNCTIONS_DESTROY_ARGS* /*pArgs*/, | ||
| 44 | __inout BA_FUNCTIONS_DESTROY_RESULTS* /*pResults*/ | ||
| 45 | ) | ||
| 46 | { | ||
| 47 | BalUninitialize(); | ||
| 48 | } | ||
diff --git a/src/test/burn/TestData/PrereqBaTests/PrereqBaf/precomp.h b/src/test/burn/TestData/PrereqBaTests/PrereqBaf/precomp.h new file mode 100644 index 00000000..8320bdd8 --- /dev/null +++ b/src/test/burn/TestData/PrereqBaTests/PrereqBaf/precomp.h | |||
| @@ -0,0 +1,31 @@ | |||
| 1 | #pragma once | ||
| 2 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | ||
| 3 | |||
| 4 | |||
| 5 | #include <windows.h> | ||
| 6 | #include <msiquery.h> | ||
| 7 | #include <objbase.h> | ||
| 8 | #include <shlobj.h> | ||
| 9 | #include <shlwapi.h> | ||
| 10 | #include <stdlib.h> | ||
| 11 | #include <strsafe.h> | ||
| 12 | #include <CommCtrl.h> | ||
| 13 | |||
| 14 | #include "dutil.h" | ||
| 15 | #include "dictutil.h" | ||
| 16 | #include "fileutil.h" | ||
| 17 | #include "locutil.h" | ||
| 18 | #include "pathutil.h" | ||
| 19 | #include "strutil.h" | ||
| 20 | |||
| 21 | #include "BalBaseBootstrapperApplication.h" | ||
| 22 | #include "balutil.h" | ||
| 23 | |||
| 24 | #include "BAFunctions.h" | ||
| 25 | #include "IBAFunctions.h" | ||
| 26 | |||
| 27 | HRESULT WINAPI CreateBAFunctions( | ||
| 28 | __in HMODULE hModule, | ||
| 29 | __in const BA_FUNCTIONS_CREATE_ARGS* pArgs, | ||
| 30 | __inout BA_FUNCTIONS_CREATE_RESULTS* pResults | ||
| 31 | ); | ||
diff --git a/src/test/burn/TestData/PrereqBaTests/ReplaceConfig/ReplaceConfig.cpp b/src/test/burn/TestData/PrereqBaTests/ReplaceConfig/ReplaceConfig.cpp new file mode 100644 index 00000000..1fa71bc2 --- /dev/null +++ b/src/test/burn/TestData/PrereqBaTests/ReplaceConfig/ReplaceConfig.cpp | |||
| @@ -0,0 +1,33 @@ | |||
| 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | ||
| 2 | |||
| 3 | #include "precomp.h" | ||
| 4 | |||
| 5 | int __cdecl wmain( | ||
| 6 | __in int argc, | ||
| 7 | __in LPWSTR argv[] | ||
| 8 | ) | ||
| 9 | { | ||
| 10 | HRESULT hr = S_OK; | ||
| 11 | DWORD dwExitCode = 0; | ||
| 12 | LPCWSTR wzDestinationFile = argc > 1 ? argv[1] : NULL; | ||
| 13 | LPCWSTR wzGoodFile = argc > 2 ? argv[2] : NULL; | ||
| 14 | LPCWSTR wzBadFile = argc > 3 ? argv[3] : NULL; | ||
| 15 | |||
| 16 | if (argc != 4) | ||
| 17 | { | ||
| 18 | ExitWithRootFailure(hr, E_INVALIDARG, "Invalid args"); | ||
| 19 | } | ||
| 20 | |||
| 21 | if (!::MoveFileW(wzDestinationFile, wzBadFile)) | ||
| 22 | { | ||
| 23 | ExitWithLastError(hr, "Failed to move bad file"); | ||
| 24 | } | ||
| 25 | |||
| 26 | if (!::MoveFileW(wzGoodFile, wzDestinationFile)) | ||
| 27 | { | ||
| 28 | ExitWithLastError(hr, "Failed to move good file"); | ||
| 29 | } | ||
| 30 | |||
| 31 | LExit: | ||
| 32 | return FAILED(hr) ? (int)hr : (int)dwExitCode; | ||
| 33 | } | ||
diff --git a/src/test/burn/TestData/PrereqBaTests/ReplaceConfig/ReplaceConfig.vcxproj b/src/test/burn/TestData/PrereqBaTests/ReplaceConfig/ReplaceConfig.vcxproj new file mode 100644 index 00000000..c5d7b046 --- /dev/null +++ b/src/test/burn/TestData/PrereqBaTests/ReplaceConfig/ReplaceConfig.vcxproj | |||
| @@ -0,0 +1,63 @@ | |||
| 1 | <?xml version="1.0" encoding="utf-8"?> | ||
| 2 | <!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. --> | ||
| 3 | |||
| 4 | <Project DefaultTargets="Build" Toolsxmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | ||
| 5 | <ItemGroup Label="ProjectConfigurations"> | ||
| 6 | <ProjectConfiguration Include="Debug|ARM64"> | ||
| 7 | <Configuration>Debug</Configuration> | ||
| 8 | <Platform>ARM64</Platform> | ||
| 9 | </ProjectConfiguration> | ||
| 10 | <ProjectConfiguration Include="Release|ARM64"> | ||
| 11 | <Configuration>Release</Configuration> | ||
| 12 | <Platform>ARM64</Platform> | ||
| 13 | </ProjectConfiguration> | ||
| 14 | <ProjectConfiguration Include="Debug|Win32"> | ||
| 15 | <Configuration>Debug</Configuration> | ||
| 16 | <Platform>Win32</Platform> | ||
| 17 | </ProjectConfiguration> | ||
| 18 | <ProjectConfiguration Include="Release|Win32"> | ||
| 19 | <Configuration>Release</Configuration> | ||
| 20 | <Platform>Win32</Platform> | ||
| 21 | </ProjectConfiguration> | ||
| 22 | <ProjectConfiguration Include="Debug|x64"> | ||
| 23 | <Configuration>Debug</Configuration> | ||
| 24 | <Platform>x64</Platform> | ||
| 25 | </ProjectConfiguration> | ||
| 26 | <ProjectConfiguration Include="Release|x64"> | ||
| 27 | <Configuration>Release</Configuration> | ||
| 28 | <Platform>x64</Platform> | ||
| 29 | </ProjectConfiguration> | ||
| 30 | </ItemGroup> | ||
| 31 | |||
| 32 | <PropertyGroup Label="Globals"> | ||
| 33 | <ProjectGuid>{3D10A07D-3321-4F8E-B884-951F8FB5D636}</ProjectGuid> | ||
| 34 | <ConfigurationType>Application</ConfigurationType> | ||
| 35 | <ProjectSubSystem>Console</ProjectSubSystem> | ||
| 36 | <CharacterSet>Unicode</CharacterSet> | ||
| 37 | <TargetName>ReplaceConfig</TargetName> | ||
| 38 | <IsWixTestProject>true</IsWixTestProject> | ||
| 39 | </PropertyGroup> | ||
| 40 | |||
| 41 | <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> | ||
| 42 | <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> | ||
| 43 | |||
| 44 | <PropertyGroup> | ||
| 45 | <ProjectAdditionalLinkLibraries>comctl32.lib;gdiplus.lib;msimg32.lib;shlwapi.lib;wininet.lib</ProjectAdditionalLinkLibraries> | ||
| 46 | </PropertyGroup> | ||
| 47 | |||
| 48 | <ItemGroup> | ||
| 49 | <ClCompile Include="precomp.cpp"> | ||
| 50 | <PrecompiledHeader>Create</PrecompiledHeader> | ||
| 51 | </ClCompile> | ||
| 52 | <ClCompile Include="ReplaceConfig.cpp" /> | ||
| 53 | </ItemGroup> | ||
| 54 | <ItemGroup> | ||
| 55 | <ClInclude Include="precomp.h" /> | ||
| 56 | </ItemGroup> | ||
| 57 | |||
| 58 | <ItemGroup> | ||
| 59 | <PackageReference Include="WixToolset.DUtil" /> | ||
| 60 | </ItemGroup> | ||
| 61 | |||
| 62 | <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> | ||
| 63 | </Project> | ||
diff --git a/src/test/burn/TestData/PrereqBaTests/ReplaceConfig/precomp.cpp b/src/test/burn/TestData/PrereqBaTests/ReplaceConfig/precomp.cpp new file mode 100644 index 00000000..37664a1c --- /dev/null +++ b/src/test/burn/TestData/PrereqBaTests/ReplaceConfig/precomp.cpp | |||
| @@ -0,0 +1,3 @@ | |||
| 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | ||
| 2 | |||
| 3 | #include "precomp.h" | ||
diff --git a/src/test/burn/TestData/PrereqBaTests/ReplaceConfig/precomp.h b/src/test/burn/TestData/PrereqBaTests/ReplaceConfig/precomp.h new file mode 100644 index 00000000..f4180c2e --- /dev/null +++ b/src/test/burn/TestData/PrereqBaTests/ReplaceConfig/precomp.h | |||
| @@ -0,0 +1,17 @@ | |||
| 1 | #pragma once | ||
| 2 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | ||
| 3 | |||
| 4 | |||
| 5 | #include <windows.h> | ||
| 6 | #include <msiquery.h> | ||
| 7 | #include <objbase.h> | ||
| 8 | #include <shlobj.h> | ||
| 9 | #include <shlwapi.h> | ||
| 10 | #include <stdlib.h> | ||
| 11 | #include <strsafe.h> | ||
| 12 | #include <CommCtrl.h> | ||
| 13 | |||
| 14 | #include "dutil.h" | ||
| 15 | #include "fileutil.h" | ||
| 16 | #include "pathutil.h" | ||
| 17 | #include "strutil.h" | ||
diff --git a/src/test/burn/WixTestTools/BundleInstaller.cs b/src/test/burn/WixTestTools/BundleInstaller.cs index 2b449ebf..0ab02d1b 100644 --- a/src/test/burn/WixTestTools/BundleInstaller.cs +++ b/src/test/burn/WixTestTools/BundleInstaller.cs | |||
| @@ -27,6 +27,20 @@ namespace WixTestTools | |||
| 27 | public string TestName { get; } | 27 | public string TestName { get; } |
| 28 | 28 | ||
| 29 | /// <summary> | 29 | /// <summary> |
| 30 | /// Runs the bundle asking for help. | ||
| 31 | /// </summary> | ||
| 32 | /// <param name="expectedExitCode">Expected exit code, defaults to success.</param> | ||
| 33 | /// <param name="arguments">Optional arguments to pass to the tool.</param> | ||
| 34 | /// <returns>Path to the generated log file.</returns> | ||
| 35 | public string Help(int expectedExitCode = (int)MSIExec.MSIExecReturnCode.SUCCESS, params string[] arguments) | ||
| 36 | { | ||
| 37 | var newArgumentList = new List<string>(); | ||
| 38 | newArgumentList.Add("-help"); | ||
| 39 | newArgumentList.AddRange(arguments); | ||
| 40 | return this.RunBundleWithArguments(expectedExitCode, MSIExec.MSIExecMode.Custom, newArgumentList.ToArray()); | ||
| 41 | } | ||
| 42 | |||
| 43 | /// <summary> | ||
| 30 | /// Installs the bundle with optional arguments. | 44 | /// Installs the bundle with optional arguments. |
| 31 | /// </summary> | 45 | /// </summary> |
| 32 | /// <param name="expectedExitCode">Expected exit code, defaults to success.</param> | 46 | /// <param name="expectedExitCode">Expected exit code, defaults to success.</param> |
diff --git a/src/test/burn/WixToolsetTest.BurnE2E/PrereqBaTests.cs b/src/test/burn/WixToolsetTest.BurnE2E/PrereqBaTests.cs index 52e165b4..d958b454 100644 --- a/src/test/burn/WixToolsetTest.BurnE2E/PrereqBaTests.cs +++ b/src/test/burn/WixToolsetTest.BurnE2E/PrereqBaTests.cs | |||
| @@ -18,6 +18,39 @@ namespace WixToolsetTest.BurnE2E | |||
| 18 | /// This bundle purposely provides a .runtimeconfig.json file that requires a version of .NET Core that doesn't exist, | 18 | /// This bundle purposely provides a .runtimeconfig.json file that requires a version of .NET Core that doesn't exist, |
| 19 | /// with an MSI package to represent the prerequisite package. | 19 | /// with an MSI package to represent the prerequisite package. |
| 20 | /// This verifies that: | 20 | /// This verifies that: |
| 21 | /// The preqba doesn't infinitely try to install prereqs. | ||
| 22 | /// The engine automatically uninstalls the bundle since only permanent packages were installed. | ||
| 23 | /// </summary> | ||
| 24 | [RuntimeFact] | ||
| 25 | public void DncAlwaysPreqBaDetectsInfiniteLoop() | ||
| 26 | { | ||
| 27 | var packageA = this.CreatePackageInstaller("PackageA"); | ||
| 28 | var packageC = this.CreatePackageInstaller("PackageC"); | ||
| 29 | |||
| 30 | var bundleC = this.CreateBundleInstaller("BundleC"); | ||
| 31 | |||
| 32 | var packageASourceCodeInstalled = packageA.GetInstalledFilePath("Package.wxs"); | ||
| 33 | |||
| 34 | // Source file should *not* be installed | ||
| 35 | Assert.False(File.Exists(packageASourceCodeInstalled), $"Package A payload should not be there on test start: {packageASourceCodeInstalled}"); | ||
| 36 | packageC.VerifyInstalled(false); | ||
| 37 | |||
| 38 | bundleC.Install(E_PREREQBA_INFINITE_LOOP, "CAUSEINFINITELOOP=1"); | ||
| 39 | |||
| 40 | // Part of the test is Install actually completing. | ||
| 41 | |||
| 42 | // Source file should be installed | ||
| 43 | Assert.True(File.Exists(packageASourceCodeInstalled), String.Concat("Should have found Package A payload installed at: ", packageASourceCodeInstalled)); | ||
| 44 | packageC.VerifyInstalled(false); | ||
| 45 | |||
| 46 | // No non-permanent packages should have ended up installed or cached so it should have unregistered. | ||
| 47 | bundleC.VerifyUnregisteredAndRemovedFromPackageCache(); | ||
| 48 | } | ||
| 49 | |||
| 50 | /// <summary> | ||
| 51 | /// This bundle purposely provides a .runtimeconfig.json file that requires a version of .NET Core that doesn't exist, | ||
| 52 | /// with an MSI package to represent the prerequisite package. | ||
| 53 | /// This verifies that: | ||
| 21 | /// The preqba doesn't infinitely reload itself after failing to load the managed BA. | 54 | /// The preqba doesn't infinitely reload itself after failing to load the managed BA. |
| 22 | /// The engine automatically uninstalls the bundle since only permanent packages were installed. | 55 | /// The engine automatically uninstalls the bundle since only permanent packages were installed. |
| 23 | /// </summary> | 56 | /// </summary> |
| @@ -25,7 +58,7 @@ namespace WixToolsetTest.BurnE2E | |||
| 25 | public void DncPreqBaDetectsInfiniteLoop() | 58 | public void DncPreqBaDetectsInfiniteLoop() |
| 26 | { | 59 | { |
| 27 | var packageA = this.CreatePackageInstaller("PackageA"); | 60 | var packageA = this.CreatePackageInstaller("PackageA"); |
| 28 | this.CreatePackageInstaller("PackageF"); | 61 | var packageC = this.CreatePackageInstaller("PackageC"); |
| 29 | 62 | ||
| 30 | var bundleA = this.CreateBundleInstaller("BundleA"); | 63 | var bundleA = this.CreateBundleInstaller("BundleA"); |
| 31 | 64 | ||
| @@ -33,19 +66,132 @@ namespace WixToolsetTest.BurnE2E | |||
| 33 | 66 | ||
| 34 | // Source file should *not* be installed | 67 | // Source file should *not* be installed |
| 35 | Assert.False(File.Exists(packageASourceCodeInstalled), $"Package A payload should not be there on test start: {packageASourceCodeInstalled}"); | 68 | Assert.False(File.Exists(packageASourceCodeInstalled), $"Package A payload should not be there on test start: {packageASourceCodeInstalled}"); |
| 69 | packageC.VerifyInstalled(false); | ||
| 36 | 70 | ||
| 37 | bundleA.Install(E_PREREQBA_INFINITE_LOOP); | 71 | bundleA.Install(E_PREREQBA_INFINITE_LOOP, "CAUSEINFINITELOOP=1"); |
| 38 | 72 | ||
| 39 | // Part of the test is Install actually completing. | 73 | // Part of the test is Install actually completing. |
| 40 | 74 | ||
| 41 | // Source file should be installed | 75 | // Source file should be installed |
| 42 | Assert.True(File.Exists(packageASourceCodeInstalled), String.Concat("Should have found Package A payload installed at: ", packageASourceCodeInstalled)); | 76 | Assert.True(File.Exists(packageASourceCodeInstalled), String.Concat("Should have found Package A payload installed at: ", packageASourceCodeInstalled)); |
| 77 | packageC.VerifyInstalled(false); | ||
| 43 | 78 | ||
| 44 | // No non-permanent packages should have ended up installed or cached so it should have unregistered. | 79 | // No non-permanent packages should have ended up installed or cached so it should have unregistered. |
| 45 | bundleA.VerifyUnregisteredAndRemovedFromPackageCache(); | 80 | bundleA.VerifyUnregisteredAndRemovedFromPackageCache(); |
| 46 | } | 81 | } |
| 47 | 82 | ||
| 48 | /// <summary> | 83 | /// <summary> |
| 84 | /// This bundle purposely provides a .runtimeconfig.json file that requires a version of .NET Core that doesn't exist, | ||
| 85 | /// with an EXE prereq package to swap it out with a good one. | ||
| 86 | /// This verifies that: | ||
| 87 | /// The preqba doesn't infinitely try to install prereqs. | ||
| 88 | /// The managed BA gets loaded after installing prereqs. | ||
| 89 | /// </summary> | ||
| 90 | [RuntimeFact] | ||
| 91 | public void DncAlwaysPreqBaLoadsManagedBaAfterInstallingPrereqs() | ||
| 92 | { | ||
| 93 | var packageA = this.CreatePackageInstaller("PackageA"); | ||
| 94 | var packageC = this.CreatePackageInstaller("PackageC"); | ||
| 95 | |||
| 96 | var bundleC = this.CreateBundleInstaller("BundleC"); | ||
| 97 | |||
| 98 | var packageASourceCodeInstalled = packageA.GetInstalledFilePath("Package.wxs"); | ||
| 99 | |||
| 100 | // Source file should *not* be installed | ||
| 101 | Assert.False(File.Exists(packageASourceCodeInstalled), $"Package A payload should not be there on test start: {packageASourceCodeInstalled}"); | ||
| 102 | packageC.VerifyInstalled(false); | ||
| 103 | |||
| 104 | bundleC.Install(); | ||
| 105 | |||
| 106 | // Source file should be installed | ||
| 107 | Assert.True(File.Exists(packageASourceCodeInstalled), String.Concat("Should have found Package A payload installed at: ", packageASourceCodeInstalled)); | ||
| 108 | packageC.VerifyInstalled(true); | ||
| 109 | |||
| 110 | bundleC.VerifyRegisteredAndInPackageCache(); | ||
| 111 | |||
| 112 | bundleC.Uninstall(); | ||
| 113 | |||
| 114 | bundleC.VerifyUnregisteredAndRemovedFromPackageCache(); | ||
| 115 | } | ||
| 116 | |||
| 117 | /// <summary> | ||
| 118 | /// This bundle purposely provides a .runtimeconfig.json file that requires a version of .NET Core that doesn't exist, | ||
| 119 | /// with an EXE prereq package to swap it out with a good one. | ||
| 120 | /// This verifies that: | ||
| 121 | /// The preqba doesn't infinitely reload itself after failing to load the managed BA. | ||
| 122 | /// The managed BA gets loaded after installing prereqs. | ||
| 123 | /// </summary> | ||
| 124 | [RuntimeFact] | ||
| 125 | public void DncPreqBaLoadsManagedBaAfterInstallingPrereqs() | ||
| 126 | { | ||
| 127 | var packageA = this.CreatePackageInstaller("PackageA"); | ||
| 128 | var packageC = this.CreatePackageInstaller("PackageC"); | ||
| 129 | |||
| 130 | var bundleA = this.CreateBundleInstaller("BundleA"); | ||
| 131 | |||
| 132 | var packageASourceCodeInstalled = packageA.GetInstalledFilePath("Package.wxs"); | ||
| 133 | |||
| 134 | // Source file should *not* be installed | ||
| 135 | Assert.False(File.Exists(packageASourceCodeInstalled), $"Package A payload should not be there on test start: {packageASourceCodeInstalled}"); | ||
| 136 | packageC.VerifyInstalled(false); | ||
| 137 | |||
| 138 | bundleA.Install(); | ||
| 139 | |||
| 140 | // Source file should be installed | ||
| 141 | Assert.True(File.Exists(packageASourceCodeInstalled), String.Concat("Should have found Package A payload installed at: ", packageASourceCodeInstalled)); | ||
| 142 | packageC.VerifyInstalled(true); | ||
| 143 | |||
| 144 | bundleA.VerifyRegisteredAndInPackageCache(); | ||
| 145 | |||
| 146 | bundleA.Uninstall(); | ||
| 147 | |||
| 148 | bundleA.VerifyUnregisteredAndRemovedFromPackageCache(); | ||
| 149 | } | ||
| 150 | |||
| 151 | [RuntimeFact] | ||
| 152 | public void DncAlwaysPreqBaForwardsHelpToManagedBa() | ||
| 153 | { | ||
| 154 | var bundleE = this.CreateBundleInstaller("BundleE"); | ||
| 155 | |||
| 156 | var bundleLog = bundleE.Help(); | ||
| 157 | |||
| 158 | Assert.True(LogVerifier.MessageInLogFile(bundleLog, "This is a BA for automated testing")); | ||
| 159 | } | ||
| 160 | |||
| 161 | /// <summary> | ||
| 162 | /// This bundle purposely provides a WixToolset.Mba.Host.config file that requires a version of .NET Framework that doesn't exist, | ||
| 163 | /// with an MSI package to represent the prerequisite package. | ||
| 164 | /// This verifies that: | ||
| 165 | /// The preqba doesn't infinitely try to install prereqs. | ||
| 166 | /// The engine automatically uninstalls the bundle since only permanent packages were installed. | ||
| 167 | /// </summary> | ||
| 168 | [RuntimeFact] | ||
| 169 | public void MbaAlwaysPreqBaDetectsInfiniteLoop() | ||
| 170 | { | ||
| 171 | var packageB = this.CreatePackageInstaller("PackageB"); | ||
| 172 | var packageC = this.CreatePackageInstaller("PackageC"); | ||
| 173 | |||
| 174 | var bundleD = this.CreateBundleInstaller("BundleD"); | ||
| 175 | |||
| 176 | var packageBSourceCodeInstalled = packageB.GetInstalledFilePath("Package.wxs"); | ||
| 177 | |||
| 178 | // Source file should *not* be installed | ||
| 179 | Assert.False(File.Exists(packageBSourceCodeInstalled), $"Package B payload should not be there on test start: {packageBSourceCodeInstalled}"); | ||
| 180 | packageC.VerifyInstalled(false); | ||
| 181 | |||
| 182 | bundleD.Install(E_PREREQBA_INFINITE_LOOP, "CAUSEINFINITELOOP=1"); | ||
| 183 | |||
| 184 | // Part of the test is Install actually completing. | ||
| 185 | |||
| 186 | // Source file should be installed | ||
| 187 | Assert.True(File.Exists(packageBSourceCodeInstalled), String.Concat("Should have found Package B payload installed at: ", packageBSourceCodeInstalled)); | ||
| 188 | packageC.VerifyInstalled(false); | ||
| 189 | |||
| 190 | // No non-permanent packages should have ended up installed or cached so it should have unregistered. | ||
| 191 | bundleD.VerifyUnregisteredAndRemovedFromPackageCache(); | ||
| 192 | } | ||
| 193 | |||
| 194 | /// <summary> | ||
| 49 | /// This bundle purposely provides a WixToolset.Mba.Host.config file that requires a version of .NET Framework that doesn't exist, | 195 | /// This bundle purposely provides a WixToolset.Mba.Host.config file that requires a version of .NET Framework that doesn't exist, |
| 50 | /// with an MSI package to represent the prerequisite package. | 196 | /// with an MSI package to represent the prerequisite package. |
| 51 | /// This verifies that: | 197 | /// This verifies that: |
| @@ -56,7 +202,7 @@ namespace WixToolsetTest.BurnE2E | |||
| 56 | public void MbaPreqBaDetectsInfiniteLoop() | 202 | public void MbaPreqBaDetectsInfiniteLoop() |
| 57 | { | 203 | { |
| 58 | var packageB = this.CreatePackageInstaller("PackageB"); | 204 | var packageB = this.CreatePackageInstaller("PackageB"); |
| 59 | this.CreatePackageInstaller("PackageF"); | 205 | var packageC = this.CreatePackageInstaller("PackageC"); |
| 60 | 206 | ||
| 61 | var bundleB = this.CreateBundleInstaller("BundleB"); | 207 | var bundleB = this.CreateBundleInstaller("BundleB"); |
| 62 | 208 | ||
| @@ -64,13 +210,84 @@ namespace WixToolsetTest.BurnE2E | |||
| 64 | 210 | ||
| 65 | // Source file should *not* be installed | 211 | // Source file should *not* be installed |
| 66 | Assert.False(File.Exists(packageBSourceCodeInstalled), $"Package B payload should not be there on test start: {packageBSourceCodeInstalled}"); | 212 | Assert.False(File.Exists(packageBSourceCodeInstalled), $"Package B payload should not be there on test start: {packageBSourceCodeInstalled}"); |
| 213 | packageC.VerifyInstalled(false); | ||
| 67 | 214 | ||
| 68 | bundleB.Install(E_PREREQBA_INFINITE_LOOP); | 215 | bundleB.Install(E_PREREQBA_INFINITE_LOOP, "CAUSEINFINITELOOP=1"); |
| 69 | 216 | ||
| 70 | // Part of the test is Install actually completing. | 217 | // Part of the test is Install actually completing. |
| 71 | 218 | ||
| 72 | // Source file should be installed | 219 | // Source file should be installed |
| 73 | Assert.True(File.Exists(packageBSourceCodeInstalled), String.Concat("Should have found Package B payload installed at: ", packageBSourceCodeInstalled)); | 220 | Assert.True(File.Exists(packageBSourceCodeInstalled), String.Concat("Should have found Package B payload installed at: ", packageBSourceCodeInstalled)); |
| 221 | packageC.VerifyInstalled(false); | ||
| 222 | |||
| 223 | // No non-permanent packages should have ended up installed or cached so it should have unregistered. | ||
| 224 | bundleB.VerifyUnregisteredAndRemovedFromPackageCache(); | ||
| 225 | } | ||
| 226 | |||
| 227 | /// <summary> | ||
| 228 | /// This bundle purposely provides a WixToolset.Mba.Host.config file that requires a version of .NET Framework that doesn't exist, | ||
| 229 | /// with an EXE prereq package to swap it out with a good one. | ||
| 230 | /// This verifies that: | ||
| 231 | /// The preqba doesn't infinitely try to install prereqs. | ||
| 232 | /// The managed BA gets loaded after installing prereqs. | ||
| 233 | /// </summary> | ||
| 234 | [RuntimeFact] | ||
| 235 | public void MbaAlwaysPreqBaLoadsManagedBaAfterInstallingPrereqs() | ||
| 236 | { | ||
| 237 | var packageB = this.CreatePackageInstaller("PackageB"); | ||
| 238 | var packageC = this.CreatePackageInstaller("PackageC"); | ||
| 239 | |||
| 240 | var bundleD = this.CreateBundleInstaller("BundleD"); | ||
| 241 | |||
| 242 | var packageBSourceCodeInstalled = packageB.GetInstalledFilePath("Package.wxs"); | ||
| 243 | |||
| 244 | // Source file should *not* be installed | ||
| 245 | Assert.False(File.Exists(packageBSourceCodeInstalled), $"Package B payload should not be there on test start: {packageBSourceCodeInstalled}"); | ||
| 246 | packageC.VerifyInstalled(false); | ||
| 247 | |||
| 248 | bundleD.Install(); | ||
| 249 | |||
| 250 | // Source file should be installed | ||
| 251 | Assert.True(File.Exists(packageBSourceCodeInstalled), String.Concat("Should have found Package B payload installed at: ", packageBSourceCodeInstalled)); | ||
| 252 | packageC.VerifyInstalled(true); | ||
| 253 | |||
| 254 | bundleD.VerifyRegisteredAndInPackageCache(); | ||
| 255 | |||
| 256 | bundleD.Uninstall(); | ||
| 257 | |||
| 258 | bundleD.VerifyUnregisteredAndRemovedFromPackageCache(); | ||
| 259 | } | ||
| 260 | |||
| 261 | /// <summary> | ||
| 262 | /// This bundle purposely provides a WixToolset.Mba.Host.config file that requires a version of .NET Framework that doesn't exist, | ||
| 263 | /// with an EXE prereq package to swap it out with a good one. | ||
| 264 | /// This verifies that: | ||
| 265 | /// The preqba doesn't infinitely reload itself after failing to load the managed BA. | ||
| 266 | /// The managed BA gets loaded after installing prereqs. | ||
| 267 | /// </summary> | ||
| 268 | [RuntimeFact] | ||
| 269 | public void MbaPreqBaLoadsManagedBaAfterInstallingPrereqs() | ||
| 270 | { | ||
| 271 | var packageB = this.CreatePackageInstaller("PackageB"); | ||
| 272 | var packageC = this.CreatePackageInstaller("PackageC"); | ||
| 273 | |||
| 274 | var bundleB = this.CreateBundleInstaller("BundleB"); | ||
| 275 | |||
| 276 | var packageBSourceCodeInstalled = packageB.GetInstalledFilePath("Package.wxs"); | ||
| 277 | |||
| 278 | // Source file should *not* be installed | ||
| 279 | Assert.False(File.Exists(packageBSourceCodeInstalled), $"Package B payload should not be there on test start: {packageBSourceCodeInstalled}"); | ||
| 280 | packageC.VerifyInstalled(false); | ||
| 281 | |||
| 282 | bundleB.Install(); | ||
| 283 | |||
| 284 | // Source file should be installed | ||
| 285 | Assert.True(File.Exists(packageBSourceCodeInstalled), String.Concat("Should have found Package B payload installed at: ", packageBSourceCodeInstalled)); | ||
| 286 | packageC.VerifyInstalled(true); | ||
| 287 | |||
| 288 | bundleB.VerifyRegisteredAndInPackageCache(); | ||
| 289 | |||
| 290 | bundleB.Uninstall(); | ||
| 74 | 291 | ||
| 75 | // No non-permanent packages should have ended up installed or cached so it should have unregistered. | 292 | // No non-permanent packages should have ended up installed or cached so it should have unregistered. |
| 76 | bundleB.VerifyUnregisteredAndRemovedFromPackageCache(); | 293 | bundleB.VerifyUnregisteredAndRemovedFromPackageCache(); |
