aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSean Hall <r.sean.hall@gmail.com>2022-02-11 13:05:23 -0600
committerSean Hall <r.sean.hall@gmail.com>2022-02-12 22:56:39 -0600
commit1f422997c701625a53d08648521de709e280f4af (patch)
treea04ab5c32983c297dbd354725b479065cdf5c3bf
parent40492973be6075efbfbd231aed7168194d36cc73 (diff)
downloadwix-1f422997c701625a53d08648521de709e280f4af.tar.gz
wix-1f422997c701625a53d08648521de709e280f4af.tar.bz2
wix-1f422997c701625a53d08648521de709e280f4af.zip
Detect MinorUpgrade MsiPackages independently of the base product.
Fixes #6535
-rw-r--r--src/burn/engine/detect.cpp2
-rw-r--r--src/burn/engine/msiengine.cpp57
-rw-r--r--src/burn/engine/package.h3
-rw-r--r--src/test/burn/WixToolsetTest.BurnE2E/DependencyTests.cs30
-rw-r--r--src/wix/WixToolset.Core.Burn/Bind/ProcessDependencyProvidersCommand.cs2
-rw-r--r--src/wix/test/WixToolsetTest.CoreIntegration/ContainerFixture.cs4
6 files changed, 46 insertions, 52 deletions
diff --git a/src/burn/engine/detect.cpp b/src/burn/engine/detect.cpp
index e251871c..3bd39784 100644
--- a/src/burn/engine/detect.cpp
+++ b/src/burn/engine/detect.cpp
@@ -64,6 +64,8 @@ extern "C" void DetectReset(
64 64
65 if (BURN_PACKAGE_TYPE_MSI == pPackage->type) 65 if (BURN_PACKAGE_TYPE_MSI == pPackage->type)
66 { 66 {
67 pPackage->Msi.operation = BOOTSTRAPPER_RELATED_OPERATION_NONE;
68
67 for (DWORD iFeature = 0; iFeature < pPackage->Msi.cFeatures; ++iFeature) 69 for (DWORD iFeature = 0; iFeature < pPackage->Msi.cFeatures; ++iFeature)
68 { 70 {
69 BURN_MSIFEATURE* pFeature = pPackage->Msi.rgFeatures + iFeature; 71 BURN_MSIFEATURE* pFeature = pPackage->Msi.rgFeatures + iFeature;
diff --git a/src/burn/engine/msiengine.cpp b/src/burn/engine/msiengine.cpp
index c8f68184..c27dd8c2 100644
--- a/src/burn/engine/msiengine.cpp
+++ b/src/burn/engine/msiengine.cpp
@@ -443,7 +443,6 @@ extern "C" HRESULT MsiEngineDetectPackage(
443 LPWSTR sczInstalledVersion = NULL; 443 LPWSTR sczInstalledVersion = NULL;
444 LPWSTR sczInstalledLanguage = NULL; 444 LPWSTR sczInstalledLanguage = NULL;
445 INSTALLSTATE installState = INSTALLSTATE_UNKNOWN; 445 INSTALLSTATE installState = INSTALLSTATE_UNKNOWN;
446 BOOTSTRAPPER_RELATED_OPERATION operation = BOOTSTRAPPER_RELATED_OPERATION_NONE;
447 BOOTSTRAPPER_RELATED_OPERATION relatedMsiOperation = BOOTSTRAPPER_RELATED_OPERATION_NONE; 446 BOOTSTRAPPER_RELATED_OPERATION relatedMsiOperation = BOOTSTRAPPER_RELATED_OPERATION_NONE;
448 WCHAR wzProductCode[MAX_GUID_CHARS + 1] = { }; 447 WCHAR wzProductCode[MAX_GUID_CHARS + 1] = { };
449 VERUTIL_VERSION* pVersion = NULL; 448 VERUTIL_VERSION* pVersion = NULL;
@@ -455,39 +454,39 @@ extern "C" HRESULT MsiEngineDetectPackage(
455 hr = WiuGetProductInfoEx(pPackage->Msi.sczProductCode, NULL, pPackage->fPerMachine ? MSIINSTALLCONTEXT_MACHINE : MSIINSTALLCONTEXT_USERUNMANAGED, INSTALLPROPERTY_VERSIONSTRING, &sczInstalledVersion); 454 hr = WiuGetProductInfoEx(pPackage->Msi.sczProductCode, NULL, pPackage->fPerMachine ? MSIINSTALLCONTEXT_MACHINE : MSIINSTALLCONTEXT_USERUNMANAGED, INSTALLPROPERTY_VERSIONSTRING, &sczInstalledVersion);
456 if (SUCCEEDED(hr)) 455 if (SUCCEEDED(hr))
457 { 456 {
458 hr = VerParseVersion(sczInstalledVersion, 0, FALSE, &pPackage->Msi.pInstalledVersion); 457 hr = VerParseVersion(sczInstalledVersion, 0, FALSE, &pVersion);
459 ExitOnFailure(hr, "Failed to parse installed version: '%ls' for ProductCode: %ls", sczInstalledVersion, pPackage->Msi.sczProductCode); 458 ExitOnFailure(hr, "Failed to parse installed version: '%ls' for ProductCode: %ls", sczInstalledVersion, pPackage->Msi.sczProductCode);
460 459
461 if (pPackage->Msi.pInstalledVersion->fInvalid) 460 if (pVersion->fInvalid)
462 { 461 {
463 LogId(REPORT_WARNING, MSG_DETECTED_MSI_PACKAGE_INVALID_VERSION, pPackage->Msi.sczProductCode, sczInstalledVersion); 462 LogId(REPORT_WARNING, MSG_DETECTED_MSI_PACKAGE_INVALID_VERSION, pPackage->Msi.sczProductCode, sczInstalledVersion);
464 } 463 }
465 464
466 // compare versions 465 // compare versions
467 hr = VerCompareParsedVersions(pPackage->Msi.pVersion, pPackage->Msi.pInstalledVersion, &nCompareResult); 466 hr = VerCompareParsedVersions(pPackage->Msi.pVersion, pVersion, &nCompareResult);
468 ExitOnFailure(hr, "Failed to compare version '%ls' to installed version: '%ls'", pPackage->Msi.pVersion->sczVersion, pPackage->Msi.pInstalledVersion->sczVersion); 467 ExitOnFailure(hr, "Failed to compare version '%ls' to installed version: '%ls'", pPackage->Msi.pVersion->sczVersion, pVersion->sczVersion);
469 468
470 if (nCompareResult < 0) 469 if (nCompareResult < 0)
471 { 470 {
472 operation = BOOTSTRAPPER_RELATED_OPERATION_DOWNGRADE; 471 pPackage->Msi.operation = BOOTSTRAPPER_RELATED_OPERATION_DOWNGRADE;
473 pPackage->currentState = BOOTSTRAPPER_PACKAGE_STATE_SUPERSEDED; 472 pPackage->currentState = BOOTSTRAPPER_PACKAGE_STATE_SUPERSEDED;
474 } 473 }
474 else if (nCompareResult > 0)
475 {
476 pPackage->Msi.operation = BOOTSTRAPPER_RELATED_OPERATION_MINOR_UPDATE;
477 pPackage->currentState = BOOTSTRAPPER_PACKAGE_STATE_ABSENT;
478 }
475 else 479 else
476 { 480 {
477 if (nCompareResult > 0)
478 {
479 operation = BOOTSTRAPPER_RELATED_OPERATION_MINOR_UPDATE;
480 }
481
482 pPackage->currentState = BOOTSTRAPPER_PACKAGE_STATE_PRESENT; 481 pPackage->currentState = BOOTSTRAPPER_PACKAGE_STATE_PRESENT;
483 } 482 }
484 483
485 // Report related MSI package to BA. 484 // Report related MSI package to BA.
486 if (BOOTSTRAPPER_RELATED_OPERATION_NONE != operation) 485 if (BOOTSTRAPPER_RELATED_OPERATION_NONE != pPackage->Msi.operation)
487 { 486 {
488 LogId(REPORT_STANDARD, MSG_DETECTED_RELATED_PACKAGE, pPackage->Msi.sczProductCode, LoggingPerMachineToString(pPackage->fPerMachine), pPackage->Msi.pInstalledVersion->sczVersion, pPackage->Msi.dwLanguage, LoggingRelatedOperationToString(operation)); 487 LogId(REPORT_STANDARD, MSG_DETECTED_RELATED_PACKAGE, pPackage->Msi.sczProductCode, LoggingPerMachineToString(pPackage->fPerMachine), pVersion->sczVersion, pPackage->Msi.dwLanguage, LoggingRelatedOperationToString(pPackage->Msi.operation));
489 488
490 hr = UserExperienceOnDetectRelatedMsiPackage(pUserExperience, pPackage->sczId, pPackage->Msi.sczUpgradeCode, pPackage->Msi.sczProductCode, pPackage->fPerMachine, pPackage->Msi.pInstalledVersion, operation); 489 hr = UserExperienceOnDetectRelatedMsiPackage(pUserExperience, pPackage->sczId, pPackage->Msi.sczUpgradeCode, pPackage->Msi.sczProductCode, pPackage->fPerMachine, pVersion, pPackage->Msi.operation);
491 ExitOnRootFailure(hr, "BA aborted detect related MSI package."); 490 ExitOnRootFailure(hr, "BA aborted detect related MSI package.");
492 } 491 }
493 } 492 }
@@ -623,7 +622,7 @@ extern "C" HRESULT MsiEngineDetectPackage(
623 { 622 {
624 // If we've already detected a major upgrade that trumps any guesses that the detect is a downgrade 623 // If we've already detected a major upgrade that trumps any guesses that the detect is a downgrade
625 // or even something else. 624 // or even something else.
626 if (BOOTSTRAPPER_RELATED_OPERATION_MAJOR_UPGRADE == operation) 625 if (BOOTSTRAPPER_RELATED_OPERATION_MAJOR_UPGRADE == pPackage->Msi.operation)
627 { 626 {
628 relatedMsiOperation = BOOTSTRAPPER_RELATED_OPERATION_NONE; 627 relatedMsiOperation = BOOTSTRAPPER_RELATED_OPERATION_NONE;
629 } 628 }
@@ -632,7 +631,7 @@ extern "C" HRESULT MsiEngineDetectPackage(
632 pPackage->Msi.sczUpgradeCode && CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, NORM_IGNORECASE, pPackage->Msi.sczUpgradeCode, -1, pRelatedMsi->sczUpgradeCode, -1)) 631 pPackage->Msi.sczUpgradeCode && CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, NORM_IGNORECASE, pPackage->Msi.sczUpgradeCode, -1, pRelatedMsi->sczUpgradeCode, -1))
633 { 632 {
634 relatedMsiOperation = BOOTSTRAPPER_RELATED_OPERATION_DOWNGRADE; 633 relatedMsiOperation = BOOTSTRAPPER_RELATED_OPERATION_DOWNGRADE;
635 operation = BOOTSTRAPPER_RELATED_OPERATION_DOWNGRADE; 634 pPackage->Msi.operation = BOOTSTRAPPER_RELATED_OPERATION_DOWNGRADE;
636 pPackage->currentState = BOOTSTRAPPER_PACKAGE_STATE_OBSOLETE; 635 pPackage->currentState = BOOTSTRAPPER_PACKAGE_STATE_OBSOLETE;
637 } 636 }
638 else // we're already on the machine so the detect-only *must* be for detection purposes only. 637 else // we're already on the machine so the detect-only *must* be for detection purposes only.
@@ -643,7 +642,7 @@ extern "C" HRESULT MsiEngineDetectPackage(
643 else 642 else
644 { 643 {
645 relatedMsiOperation = BOOTSTRAPPER_RELATED_OPERATION_MAJOR_UPGRADE; 644 relatedMsiOperation = BOOTSTRAPPER_RELATED_OPERATION_MAJOR_UPGRADE;
646 operation = BOOTSTRAPPER_RELATED_OPERATION_MAJOR_UPGRADE; 645 pPackage->Msi.operation = BOOTSTRAPPER_RELATED_OPERATION_MAJOR_UPGRADE;
647 } 646 }
648 647
649 LogId(REPORT_STANDARD, MSG_DETECTED_RELATED_PACKAGE, wzProductCode, LoggingPerMachineToString(fPerMachine), pVersion->sczVersion, uLcid, LoggingRelatedOperationToString(relatedMsiOperation)); 648 LogId(REPORT_STANDARD, MSG_DETECTED_RELATED_PACKAGE, wzProductCode, LoggingPerMachineToString(fPerMachine), pVersion->sczVersion, uLcid, LoggingRelatedOperationToString(relatedMsiOperation));
@@ -858,9 +857,6 @@ extern "C" HRESULT MsiEnginePlanCalculatePackage(
858 Trace(REPORT_STANDARD, "Planning MSI package 0x%p", pPackage); 857 Trace(REPORT_STANDARD, "Planning MSI package 0x%p", pPackage);
859 858
860 HRESULT hr = S_OK; 859 HRESULT hr = S_OK;
861 VERUTIL_VERSION* pVersion = pPackage->Msi.pVersion;
862 VERUTIL_VERSION* pInstalledVersion = pPackage->Msi.pInstalledVersion;
863 int nCompareResult = 0;
864 BOOTSTRAPPER_ACTION_STATE execute = BOOTSTRAPPER_ACTION_STATE_NONE; 860 BOOTSTRAPPER_ACTION_STATE execute = BOOTSTRAPPER_ACTION_STATE_NONE;
865 BOOTSTRAPPER_ACTION_STATE rollback = BOOTSTRAPPER_ACTION_STATE_NONE; 861 BOOTSTRAPPER_ACTION_STATE rollback = BOOTSTRAPPER_ACTION_STATE_NONE;
866 BOOL fFeatureActionDelta = FALSE; 862 BOOL fFeatureActionDelta = FALSE;
@@ -892,17 +888,7 @@ extern "C" HRESULT MsiEnginePlanCalculatePackage(
892 case BOOTSTRAPPER_PACKAGE_STATE_SUPERSEDED: 888 case BOOTSTRAPPER_PACKAGE_STATE_SUPERSEDED:
893 if (BOOTSTRAPPER_REQUEST_STATE_PRESENT == pPackage->requested || BOOTSTRAPPER_REQUEST_STATE_REPAIR == pPackage->requested) 889 if (BOOTSTRAPPER_REQUEST_STATE_PRESENT == pPackage->requested || BOOTSTRAPPER_REQUEST_STATE_REPAIR == pPackage->requested)
894 { 890 {
895 hr = VerCompareParsedVersions(pVersion, pInstalledVersion, &nCompareResult); 891 if (BOOTSTRAPPER_REQUEST_STATE_REPAIR == pPackage->requested)
896 ExitOnFailure(hr, "Failed to compare '%ls' to '%ls' for planning.", pVersion->sczVersion, pInstalledVersion->sczVersion);
897
898 // Take a look at the version and determine if this is a potential
899 // minor upgrade (same ProductCode newer ProductVersion), otherwise,
900 // there is a newer version so no work necessary.
901 if (nCompareResult > 0)
902 {
903 execute = BOOTSTRAPPER_ACTION_STATE_MINOR_UPGRADE;
904 }
905 else if (BOOTSTRAPPER_REQUEST_STATE_REPAIR == pPackage->requested)
906 { 892 {
907 execute = BOOTSTRAPPER_ACTION_STATE_REPAIR; 893 execute = BOOTSTRAPPER_ACTION_STATE_REPAIR;
908 } 894 }
@@ -937,7 +923,14 @@ extern "C" HRESULT MsiEnginePlanCalculatePackage(
937 case BOOTSTRAPPER_REQUEST_STATE_PRESENT: __fallthrough; 923 case BOOTSTRAPPER_REQUEST_STATE_PRESENT: __fallthrough;
938 case BOOTSTRAPPER_REQUEST_STATE_FORCE_PRESENT: __fallthrough; 924 case BOOTSTRAPPER_REQUEST_STATE_FORCE_PRESENT: __fallthrough;
939 case BOOTSTRAPPER_REQUEST_STATE_REPAIR: 925 case BOOTSTRAPPER_REQUEST_STATE_REPAIR:
940 execute = BOOTSTRAPPER_ACTION_STATE_INSTALL; 926 if (BOOTSTRAPPER_RELATED_OPERATION_MINOR_UPDATE == pPackage->Msi.operation)
927 {
928 execute = BOOTSTRAPPER_ACTION_STATE_MINOR_UPGRADE;
929 }
930 else
931 {
932 execute = BOOTSTRAPPER_ACTION_STATE_INSTALL;
933 }
941 break; 934 break;
942 935
943 case BOOTSTRAPPER_REQUEST_STATE_FORCE_ABSENT: 936 case BOOTSTRAPPER_REQUEST_STATE_FORCE_ABSENT:
diff --git a/src/burn/engine/package.h b/src/burn/engine/package.h
index 1e61d92b..eb40443d 100644
--- a/src/burn/engine/package.h
+++ b/src/burn/engine/package.h
@@ -341,9 +341,10 @@ typedef struct _BURN_PACKAGE
341 LPWSTR sczProductCode; 341 LPWSTR sczProductCode;
342 DWORD dwLanguage; 342 DWORD dwLanguage;
343 VERUTIL_VERSION* pVersion; 343 VERUTIL_VERSION* pVersion;
344 VERUTIL_VERSION* pInstalledVersion;
345 LPWSTR sczUpgradeCode; 344 LPWSTR sczUpgradeCode;
346 345
346 BOOTSTRAPPER_RELATED_OPERATION operation;
347
347 BURN_MSIPROPERTY* rgProperties; 348 BURN_MSIPROPERTY* rgProperties;
348 DWORD cProperties; 349 DWORD cProperties;
349 350
diff --git a/src/test/burn/WixToolsetTest.BurnE2E/DependencyTests.cs b/src/test/burn/WixToolsetTest.BurnE2E/DependencyTests.cs
index ba02d8ee..3437bf00 100644
--- a/src/test/burn/WixToolsetTest.BurnE2E/DependencyTests.cs
+++ b/src/test/burn/WixToolsetTest.BurnE2E/DependencyTests.cs
@@ -730,22 +730,21 @@ namespace WixToolsetTest.BurnE2E
730 bundleNv101.VerifyUnregisteredAndRemovedFromPackageCache(); 730 bundleNv101.VerifyUnregisteredAndRemovedFromPackageCache();
731 bundleNv1.VerifyRegisteredAndInPackageCache(); 731 bundleNv1.VerifyRegisteredAndInPackageCache();
732 732
733 // The expected values will change after implementing https://github.com/wixtoolset/issues/issues/6535 and https://github.com/wixtoolset/issues/issues/3421
734 packageAv1.VerifyInstalled(true); 733 packageAv1.VerifyInstalled(true);
735 packageC.VerifyInstalled(false); 734 packageC.VerifyInstalled(false);
736 packageFv1.VerifyInstalledWithVersion(false); 735 packageFv1.VerifyInstalledWithVersion(true);
737 packageFv101.VerifyInstalledWithVersion(true); 736 packageFv101.VerifyInstalledWithVersion(false);
738 packageGv1.VerifyInstalledWithVersion(false); 737 packageGv1.VerifyInstalledWithVersion(true);
739 packageGv101.VerifyInstalledWithVersion(true); 738 packageGv101.VerifyInstalledWithVersion(false);
740 739
741 bundleM.Uninstall(); 740 bundleM.Uninstall();
742 bundleM.VerifyUnregisteredAndRemovedFromPackageCache(); 741 bundleM.VerifyUnregisteredAndRemovedFromPackageCache();
743 742
744 packageAv1.VerifyInstalled(false); 743 packageAv1.VerifyInstalled(false);
745 packageFv1.VerifyInstalledWithVersion(false); 744 packageFv1.VerifyInstalledWithVersion(true);
746 packageFv101.VerifyInstalledWithVersion(true); 745 packageFv101.VerifyInstalledWithVersion(false);
747 packageGv1.VerifyInstalledWithVersion(false); 746 packageGv1.VerifyInstalledWithVersion(true);
748 packageGv101.VerifyInstalledWithVersion(true); 747 packageGv101.VerifyInstalledWithVersion(false);
749 748
750 bundleNv1.Uninstall(); 749 bundleNv1.Uninstall();
751 bundleNv1.VerifyUnregisteredAndRemovedFromPackageCache(); 750 bundleNv1.VerifyUnregisteredAndRemovedFromPackageCache();
@@ -804,20 +803,19 @@ namespace WixToolsetTest.BurnE2E
804 bundleNv101.VerifyUnregisteredAndRemovedFromPackageCache(); 803 bundleNv101.VerifyUnregisteredAndRemovedFromPackageCache();
805 bundleNv1.VerifyRegisteredAndInPackageCache(); 804 bundleNv1.VerifyRegisteredAndInPackageCache();
806 805
807 // The expected values will change after implementing https://github.com/wixtoolset/issues/issues/6535 and https://github.com/wixtoolset/issues/issues/3421
808 packageAv1.VerifyInstalled(true); 806 packageAv1.VerifyInstalled(true);
809 packageC.VerifyInstalled(false); 807 packageC.VerifyInstalled(false);
810 packageFv1.VerifyInstalledWithVersion(false); 808 packageFv1.VerifyInstalledWithVersion(true);
811 packageFv101.VerifyInstalledWithVersion(true); 809 packageFv101.VerifyInstalledWithVersion(false);
812 packageGv1.VerifyInstalledWithVersion(false); 810 packageGv1.VerifyInstalledWithVersion(true);
813 packageGv101.VerifyInstalledWithVersion(true); 811 packageGv101.VerifyInstalledWithVersion(false);
814 812
815 bundleNv1.Uninstall(); 813 bundleNv1.Uninstall();
816 bundleNv1.VerifyUnregisteredAndRemovedFromPackageCache(); 814 bundleNv1.VerifyUnregisteredAndRemovedFromPackageCache();
817 815
818 packageAv1.VerifyInstalled(true); 816 packageAv1.VerifyInstalled(true);
819 packageFv1.VerifyInstalledWithVersion(false); 817 packageFv1.VerifyInstalledWithVersion(true);
820 packageFv101.VerifyInstalledWithVersion(true); 818 packageFv101.VerifyInstalledWithVersion(false);
821 packageGv1.VerifyInstalledWithVersion(false); 819 packageGv1.VerifyInstalledWithVersion(false);
822 packageGv101.VerifyInstalledWithVersion(false); 820 packageGv101.VerifyInstalledWithVersion(false);
823 821
diff --git a/src/wix/WixToolset.Core.Burn/Bind/ProcessDependencyProvidersCommand.cs b/src/wix/WixToolset.Core.Burn/Bind/ProcessDependencyProvidersCommand.cs
index 5df6c887..e4e04845 100644
--- a/src/wix/WixToolset.Core.Burn/Bind/ProcessDependencyProvidersCommand.cs
+++ b/src/wix/WixToolset.Core.Burn/Bind/ProcessDependencyProvidersCommand.cs
@@ -107,7 +107,7 @@ namespace WixToolset.Core.Burn.Bind
107 this.Section.AddSymbol(new WixDependencyProviderSymbol(facade.PackageSymbol.SourceLineNumbers, facade.PackageSymbol.Id) 107 this.Section.AddSymbol(new WixDependencyProviderSymbol(facade.PackageSymbol.SourceLineNumbers, facade.PackageSymbol.Id)
108 { 108 {
109 ParentRef = facade.PackageId, 109 ParentRef = facade.PackageId,
110 ProviderKey = key, 110 ProviderKey = $"{key}_v{facade.PackageSymbol.Version}",
111 Version = facade.PackageSymbol.Version, 111 Version = facade.PackageSymbol.Version,
112 DisplayName = facade.PackageSymbol.DisplayName 112 DisplayName = facade.PackageSymbol.DisplayName
113 }); 113 });
diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/ContainerFixture.cs b/src/wix/test/WixToolsetTest.CoreIntegration/ContainerFixture.cs
index e41986ee..7cfcdded 100644
--- a/src/wix/test/WixToolsetTest.CoreIntegration/ContainerFixture.cs
+++ b/src/wix/test/WixToolsetTest.CoreIntegration/ContainerFixture.cs
@@ -150,7 +150,7 @@ namespace WixToolsetTest.CoreIntegration
150 { 150 {
151 "<MsiPackage Id='FirstX86.msi' Cache='keep' CacheId='*' InstallSize='*' Size='*' PerMachine='yes' Permanent='no' Vital='yes' RollbackBoundaryForward='WixDefaultBoundary' LogPathVariable='WixBundleLog_FirstX86.msi' RollbackLogPathVariable='WixBundleRollbackLog_FirstX86.msi' ProductCode='*' Language='1033' Version='1.0.0.0' UpgradeCode='{12E4699F-E774-4D05-8A01-5BDD41BBA127}'>" + 151 "<MsiPackage Id='FirstX86.msi' Cache='keep' CacheId='*' InstallSize='*' Size='*' PerMachine='yes' Permanent='no' Vital='yes' RollbackBoundaryForward='WixDefaultBoundary' LogPathVariable='WixBundleLog_FirstX86.msi' RollbackLogPathVariable='WixBundleRollbackLog_FirstX86.msi' ProductCode='*' Language='1033' Version='1.0.0.0' UpgradeCode='{12E4699F-E774-4D05-8A01-5BDD41BBA127}'>" +
152 "<MsiProperty Id='ARPSYSTEMCOMPONENT' Value='1' />" + 152 "<MsiProperty Id='ARPSYSTEMCOMPONENT' Value='1' />" +
153 $"<Provides Key='{GetProductCodeFromMsiPdb(pdbPaths[0])}' Version='1.0.0.0' DisplayName='MsiPackage' />" + 153 $"<Provides Key='{GetProductCodeFromMsiPdb(pdbPaths[0])}_v1.0.0.0' Version='1.0.0.0' DisplayName='MsiPackage' />" +
154 "<RelatedPackage Id='{12E4699F-E774-4D05-8A01-5BDD41BBA127}' MaxVersion='1.0.0.0' MaxInclusive='no' OnlyDetect='no' LangInclusive='yes'><Language Id='1033' /></RelatedPackage>" + 154 "<RelatedPackage Id='{12E4699F-E774-4D05-8A01-5BDD41BBA127}' MaxVersion='1.0.0.0' MaxInclusive='no' OnlyDetect='no' LangInclusive='yes'><Language Id='1033' /></RelatedPackage>" +
155 "<RelatedPackage Id='{12E4699F-E774-4D05-8A01-5BDD41BBA127}' MinVersion='1.0.0.0' MinInclusive='no' OnlyDetect='yes' LangInclusive='yes'><Language Id='1033' /></RelatedPackage>" + 155 "<RelatedPackage Id='{12E4699F-E774-4D05-8A01-5BDD41BBA127}' MinVersion='1.0.0.0' MinInclusive='no' OnlyDetect='yes' LangInclusive='yes'><Language Id='1033' /></RelatedPackage>" +
156 "<PayloadRef Id='FirstX86.msi' />" + 156 "<PayloadRef Id='FirstX86.msi' />" +
@@ -158,7 +158,7 @@ namespace WixToolsetTest.CoreIntegration
158 "</MsiPackage>", 158 "</MsiPackage>",
159 "<MsiPackage Id='FirstX64.msi' Cache='keep' CacheId='*' InstallSize='*' Size='*' PerMachine='yes' Permanent='no' Vital='yes' RollbackBoundaryBackward='WixDefaultBoundary' LogPathVariable='WixBundleLog_FirstX64.msi' RollbackLogPathVariable='WixBundleRollbackLog_FirstX64.msi' ProductCode='*' Language='1033' Version='1.0.0.0' UpgradeCode='{12E4699F-E774-4D05-8A01-5BDD41BBA127}'>" + 159 "<MsiPackage Id='FirstX64.msi' Cache='keep' CacheId='*' InstallSize='*' Size='*' PerMachine='yes' Permanent='no' Vital='yes' RollbackBoundaryBackward='WixDefaultBoundary' LogPathVariable='WixBundleLog_FirstX64.msi' RollbackLogPathVariable='WixBundleRollbackLog_FirstX64.msi' ProductCode='*' Language='1033' Version='1.0.0.0' UpgradeCode='{12E4699F-E774-4D05-8A01-5BDD41BBA127}'>" +
160 "<MsiProperty Id='ARPSYSTEMCOMPONENT' Value='1' />" + 160 "<MsiProperty Id='ARPSYSTEMCOMPONENT' Value='1' />" +
161 $"<Provides Key='{GetProductCodeFromMsiPdb(pdbPaths[1])}' Version='1.0.0.0' DisplayName='MsiPackage' />" + 161 $"<Provides Key='{GetProductCodeFromMsiPdb(pdbPaths[1])}_v1.0.0.0' Version='1.0.0.0' DisplayName='MsiPackage' />" +
162 "<RelatedPackage Id='{12E4699F-E774-4D05-8A01-5BDD41BBA127}' MaxVersion='1.0.0.0' MaxInclusive='no' OnlyDetect='no' LangInclusive='yes'><Language Id='1033' /></RelatedPackage>" + 162 "<RelatedPackage Id='{12E4699F-E774-4D05-8A01-5BDD41BBA127}' MaxVersion='1.0.0.0' MaxInclusive='no' OnlyDetect='no' LangInclusive='yes'><Language Id='1033' /></RelatedPackage>" +
163 "<RelatedPackage Id='{12E4699F-E774-4D05-8A01-5BDD41BBA127}' MinVersion='1.0.0.0' MinInclusive='no' OnlyDetect='yes' LangInclusive='yes'><Language Id='1033' /></RelatedPackage>" + 163 "<RelatedPackage Id='{12E4699F-E774-4D05-8A01-5BDD41BBA127}' MinVersion='1.0.0.0' MinInclusive='no' OnlyDetect='yes' LangInclusive='yes'><Language Id='1033' /></RelatedPackage>" +
164 "<PayloadRef Id='FirstX64.msi' />" + 164 "<PayloadRef Id='FirstX64.msi' />" +