Skip to content
/ wix Public
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/burn/engine/core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,7 @@ extern "C" HRESULT CoreDetect(
pEngineState->registration.fEligibleForCleanup = FALSE;
}

LogId(REPORT_STANDARD, MSG_DETECTED_PACKAGE, pPackage->sczId, LoggingPackageStateToString(pPackage->currentState), LoggingBoolToString(pPackage->fCached), LoggingPackageRegistrationStateToString(pPackage->fCanAffectRegistration, pPackage->installRegistrationState), LoggingPackageRegistrationStateToString(pPackage->fCanAffectRegistration, pPackage->cacheRegistrationState), LoggingPackageScopeToString(pPackage->scope));
LogId(REPORT_STANDARD, MSG_DETECTED_PACKAGE, pPackage->sczId, LoggingPackageStateToString(pPackage->currentState), LoggingBoolToString(pPackage->fCached), LoggingPackageRegistrationStateToString(pPackage->fCanAffectRegistration, pPackage->installRegistrationState), LoggingPackageRegistrationStateToString(pPackage->fCanAffectRegistration, pPackage->cacheRegistrationState), LoggingPackageScopeToString(pPackage->scope), LoggingInstallScopeToString(pPackage->fDetectedPerMachine));

if (BURN_PACKAGE_TYPE_MSI == pPackage->type)
{
Expand Down Expand Up @@ -469,7 +469,7 @@ extern "C" HRESULT CorePlan(
pEngineState->plan.fDisableRollback = pEngineState->fDisableRollback || BOOTSTRAPPER_ACTION_UNSAFE_UNINSTALL == pEngineState->plan.action;
pEngineState->plan.fPlanPackageCacheRollback = BOOTSTRAPPER_REGISTRATION_TYPE_NONE == pEngineState->registration.detectedRegistrationType;

hr = PlanPackagesAndBundleScope(pEngineState->packages.rgPackages, pEngineState->packages.cPackages, pEngineState->plan.plannedScope, pEngineState->registration.scope, pEngineState->command.commandLineScope, &pEngineState->plan.plannedScope, &pEngineState->registration.fPerMachine);
hr = PlanPackagesAndBundleScope(pEngineState->packages.rgPackages, pEngineState->packages.cPackages, pEngineState->plan.plannedScope, pEngineState->registration.scope, pEngineState->command.commandLineScope, pEngineState->registration.detectedScope, &pEngineState->plan.plannedScope, &pEngineState->registration.fPerMachine);
ExitOnFailure(hr, "Failed to determine packages and bundle scope.");

if (BOOTSTRAPPER_PACKAGE_SCOPE_PER_MACHINE_OR_PER_USER == pEngineState->registration.scope || BOOTSTRAPPER_PACKAGE_SCOPE_PER_USER_OR_PER_MACHINE == pEngineState->registration.scope)
Expand Down
3 changes: 2 additions & 1 deletion src/burn/engine/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,15 @@ const LPCWSTR BURN_COMMANDLINE_SWITCH_PREFIX = L"burn.";
const LPCWSTR BURN_BUNDLE_ACTION = L"WixBundleAction";
const LPCWSTR BURN_BUNDLE_ACTIVE_PARENT = L"WixBundleActiveParent";
const LPCWSTR BURN_BUNDLE_COMMAND_LINE_ACTION = L"WixBundleCommandLineAction";
const LPCWSTR BURN_BUNDLE_DETECTED_SCOPE = L"WixBundleDetectedScope";
const LPCWSTR BURN_BUNDLE_EXECUTE_PACKAGE_CACHE_FOLDER = L"WixBundleExecutePackageCacheFolder";
const LPCWSTR BURN_BUNDLE_EXECUTE_PACKAGE_ACTION = L"WixBundleExecutePackageAction";
const LPCWSTR BURN_BUNDLE_FORCED_RESTART_PACKAGE = L"WixBundleForcedRestartPackage";
const LPCWSTR BURN_BUNDLE_INSTALLED = L"WixBundleInstalled";
const LPCWSTR BURN_BUNDLE_ELEVATED = L"WixBundleElevated";
const LPCWSTR BURN_BUNDLE_PLANNED_SCOPE = L"WixBundlePlannedScope";
const LPCWSTR BURN_BUNDLE_PROVIDER_KEY = L"WixBundleProviderKey";
const LPCWSTR BURN_BUNDLE_SCOPE = L"WixBundleScope";
const LPCWSTR BURN_BUNDLE_AUTHORED_SCOPE = L"WixBundleAuthoredScope";
const LPCWSTR BURN_BUNDLE_SOURCE_PROCESS_PATH = L"WixBundleSourceProcessPath";
const LPCWSTR BURN_BUNDLE_SOURCE_PROCESS_FOLDER = L"WixBundleSourceProcessFolder";
const LPCWSTR BURN_BUNDLE_TAG = L"WixBundleTag";
Expand Down
9 changes: 8 additions & 1 deletion src/burn/engine/engine.mc
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ MessageId=101
Severity=Success
SymbolicName=MSG_DETECTED_PACKAGE
Language=English
Detected package: %1!ls!, state: %2!hs!, authored scope: %6!hs!, cached: %3!hs!, install registration state: %4!hs!, cache registration state: %5!hs!
Detected package: %1!ls!, state: %2!hs!, authored scope: %6!hs!, detected scope: %7!hs!, cached: %3!hs!, install registration state: %4!hs!, cache registration state: %5!hs!
.

MessageId=102
Expand Down Expand Up @@ -414,6 +414,13 @@ Language=English
Planned configurable scope: %1!hs!
.

MessageId=227
Severity=Success
SymbolicName=MSG_PLAN_INSTALLED_SCOPE
Language=English
Bundle was already installed with scope: %1!hs!
.

MessageId=201
Severity=Success
SymbolicName=MSG_PLANNED_PACKAGE
Expand Down
14 changes: 12 additions & 2 deletions src/burn/engine/msiengine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -457,14 +457,24 @@ extern "C" HRESULT MsiEngineDetectPackage(
if (BOOTSTRAPPER_PACKAGE_SCOPE_PER_MACHINE_OR_PER_USER == pPackage->scope || BOOTSTRAPPER_PACKAGE_SCOPE_PER_USER_OR_PER_MACHINE == pPackage->scope)
{
hr = WiuGetProductInfoEx(pPackage->Msi.sczProductCode, NULL, MSIINSTALLCONTEXT_MACHINE, INSTALLPROPERTY_VERSIONSTRING, &sczInstalledVersion);
if (FAILED(hr))
if (SUCCEEDED(hr))
{
pPackage->fDetectedPerMachine = TRUE;
}
else
{
hr = WiuGetProductInfoEx(pPackage->Msi.sczProductCode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, INSTALLPROPERTY_VERSIONSTRING, &sczInstalledVersion);
if (SUCCEEDED(hr))
{
pPackage->fDetectedPerMachine = FALSE;
}
}
}
else
{
hr = WiuGetProductInfoEx(pPackage->Msi.sczProductCode, NULL, pPackage->scope == BOOTSTRAPPER_PACKAGE_SCOPE_PER_MACHINE ? MSIINSTALLCONTEXT_MACHINE : MSIINSTALLCONTEXT_USERUNMANAGED, INSTALLPROPERTY_VERSIONSTRING, &sczInstalledVersion);
pPackage->fDetectedPerMachine = BOOTSTRAPPER_PACKAGE_SCOPE_PER_MACHINE == pPackage->scope;

hr = WiuGetProductInfoEx(pPackage->Msi.sczProductCode, NULL, pPackage->fDetectedPerMachine ? MSIINSTALLCONTEXT_MACHINE : MSIINSTALLCONTEXT_USERUNMANAGED, INSTALLPROPERTY_VERSIONSTRING, &sczInstalledVersion);
}
if (SUCCEEDED(hr))
{
Expand Down
1 change: 1 addition & 0 deletions src/burn/engine/package.h
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,7 @@ typedef struct _BURN_PACKAGE
BURN_ROLLBACK_BOUNDARY* pRollbackBoundaryForward; // used during install and repair.
BURN_ROLLBACK_BOUNDARY* pRollbackBoundaryBackward; // used during uninstall.

BOOL fDetectedPerMachine; // only valid after Detect.
BOOTSTRAPPER_PACKAGE_STATE currentState; // only valid after Detect.
BOOL fCached; // only valid after Detect.
BOOTSTRAPPER_CACHE_TYPE cacheType; // only valid during Plan.
Expand Down
10 changes: 9 additions & 1 deletion src/burn/engine/plan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ extern "C" HRESULT PlanSetVariables(
hr = VariableSetNumeric(pVariables, BURN_BUNDLE_ACTION, action, TRUE);
ExitOnFailure(hr, "Failed to set the bundle action built-in variable.");

hr = VariableSetNumeric(pVariables, BURN_BUNDLE_SCOPE, authoredScope, TRUE);
hr = VariableSetNumeric(pVariables, BURN_BUNDLE_AUTHORED_SCOPE, authoredScope, TRUE);
ExitOnFailure(hr, "Failed to set the bundle authored scope built-in variable.");

hr = VariableSetNumeric(pVariables, BURN_BUNDLE_PLANNED_SCOPE, plannedScope, TRUE);
Expand Down Expand Up @@ -826,6 +826,7 @@ extern "C" HRESULT PlanPackagesAndBundleScope(
__in BOOTSTRAPPER_SCOPE scope,
__in BOOTSTRAPPER_PACKAGE_SCOPE authoredScope,
__in BOOTSTRAPPER_SCOPE commandLineScope,
__in BOOTSTRAPPER_SCOPE detectedScope,
__out BOOTSTRAPPER_SCOPE* pResultingScope,
__out BOOL* pfRegistrationPerMachine
)
Expand Down Expand Up @@ -854,6 +855,13 @@ extern "C" HRESULT PlanPackagesAndBundleScope(
}
}

if (BOOTSTRAPPER_SCOPE_DEFAULT != detectedScope)
{
scope = detectedScope;

LogId(REPORT_WARNING, MSG_PLAN_INSTALLED_SCOPE, LoggingBundleScopeToString(detectedScope));
}

for (DWORD i = 0; i < cPackages; ++i)
{
BURN_PACKAGE* pPackage = rgPackages + i;
Expand Down
1 change: 1 addition & 0 deletions src/burn/engine/plan.h
Original file line number Diff line number Diff line change
Expand Up @@ -488,6 +488,7 @@ HRESULT PlanPackagesAndBundleScope(
__in BOOTSTRAPPER_SCOPE scope,
__in BOOTSTRAPPER_PACKAGE_SCOPE authoredScope,
__in BOOTSTRAPPER_SCOPE commandLineScope,
__in BOOTSTRAPPER_SCOPE detectedScope,
__out BOOTSTRAPPER_SCOPE* pResultingScope,
__out BOOL* pfPerMachine
);
Expand Down
40 changes: 27 additions & 13 deletions src/burn/engine/registration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ const LPCWSTR REGISTRY_BUNDLE_UNINSTALL_STRING = L"UninstallString";
const LPCWSTR REGISTRY_BUNDLE_RESUME_COMMAND_LINE = L"BundleResumeCommandLine";
const LPCWSTR REGISTRY_BUNDLE_VERSION_MAJOR = L"VersionMajor";
const LPCWSTR REGISTRY_BUNDLE_VERSION_MINOR = L"VersionMinor";
const LPCWSTR REGISTRY_BUNDLE_SCOPE = L"BundleScope";
const LPCWSTR SWIDTAG_FOLDER = L"swidtag";
const LPCWSTR REGISTRY_BUNDLE_VARIABLE_KEY = L"variables";

Expand Down Expand Up @@ -303,6 +304,10 @@ extern "C" HRESULT RegistrationParseFromXml(
pRegistration->hkRoot = reinterpret_cast<HKEY>(0ull);
}

// build uninstall registry key path
hr = StrAllocFormatted(&pRegistration->sczRegistrationKey, L"%ls\\%ls", BURN_REGISTRATION_REGISTRY_UNINSTALL_KEY, pRegistration->sczCode);
ExitOnFailure(hr, "Failed to build uninstall registry key path.");

LExit:
ReleaseObject(pixnRegistrationNode);
ReleaseObject(pixnArpNode);
Expand Down Expand Up @@ -458,6 +463,9 @@ extern "C" HRESULT RegistrationSetDynamicVariables(
hr = VariableSetNumeric(pVariables, BURN_BUNDLE_INSTALLED, llInstalled, TRUE);
ExitOnFailure(hr, "Failed to set the bundle installed built-in variable.");

hr = VariableSetNumeric(pVariables, BURN_BUNDLE_DETECTED_SCOPE, pRegistration->detectedScope, TRUE);
ExitOnFailure(hr, "Failed to set the bundle detected scope built-in variable.");

hr = VariableSetNumeric(pVariables, VARIABLE_REBOOTPENDING, IsWuRebootPending() || IsRegistryRebootPending(), TRUE);
ExitOnFailure(hr, "Failed to overwrite the bundle reboot-pending built-in variable.");

Expand All @@ -479,16 +487,20 @@ extern "C" HRESULT RegistrationDetectInstalled(
{
// For PUOM/PMOU bundles, check per-machine then fall back to per-user.
hr = DetectInstalled(pRegistration, HKEY_LOCAL_MACHINE);
ExitOnFailure(hr, "Failed to detect HKEY_LOCAL_MACHINE bundle registration install state.");

if (BOOTSTRAPPER_REGISTRATION_TYPE_NONE == pRegistration->detectedRegistrationType)
if (FAILED(hr))
{
hr = DetectInstalled(pRegistration, HKEY_CURRENT_USER);
ExitOnFailure(hr, "Failed to detect HKEY_CURRENT_USER bundle registration install state.");
}
}

LExit:
//LExit:
// Not finding the key or value is okay.
if (E_FILENOTFOUND == hr || E_PATHNOTFOUND == hr)
{
hr = S_OK;
}

return hr;
}

Expand Down Expand Up @@ -654,6 +666,9 @@ extern "C" HRESULT RegistrationSessionBegin(
hr = RegWriteStringFormatted(hkRegistration, REGISTRY_BUNDLE_DISPLAY_ICON, L"%s,0", pRegistration->sczCacheExecutablePath);
ExitOnFailure(hr, "Failed to write %ls value.", REGISTRY_BUNDLE_DISPLAY_ICON);

hr = RegWriteNumber(hkRegistration, REGISTRY_BUNDLE_SCOPE, pRegistration->fPerMachine ? BOOTSTRAPPER_SCOPE_PER_MACHINE : BOOTSTRAPPER_SCOPE_PER_USER);
ExitOnFailure(hr, "Failed to write %ls value.", REGISTRY_BUNDLE_SCOPE);

// update display name
hr = UpdateBundleNameRegistration(pRegistration, pVariables, hkRegistration, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS == registrationType);
ExitOnFailure(hr, "Failed to update name and publisher.");
Expand Down Expand Up @@ -1054,10 +1069,6 @@ extern "C" HRESULT RegistrationSetPaths(
// save registration key root
pRegistration->hkRoot = pRegistration->fPerMachine ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER;

// build uninstall registry key path
hr = StrAllocFormatted(&pRegistration->sczRegistrationKey, L"%ls\\%ls", BURN_REGISTRATION_REGISTRY_UNINSTALL_KEY, pRegistration->sczCode);
ExitOnFailure(hr, "Failed to build uninstall registry key path.");

// build cache directory
hr = CacheGetCompletedPath(pCache, pRegistration->fPerMachine, pRegistration->sczCode, &sczCacheDirectory);
ExitOnFailure(hr, "Failed to build cache directory.");
Expand Down Expand Up @@ -1754,25 +1765,28 @@ static HRESULT DetectInstalled(
HRESULT hr = S_OK;
HKEY hkRegistration = NULL;
DWORD dwInstalled = 0;
DWORD dwScope = 0;

pRegistration->fCached = pRegistration->sczCacheExecutablePath && FileExistsEx(pRegistration->sczCacheExecutablePath, NULL);
pRegistration->detectedRegistrationType = BOOTSTRAPPER_REGISTRATION_TYPE_NONE;
pRegistration->detectedScope = BOOTSTRAPPER_SCOPE_DEFAULT;

// open registration key
hr = RegOpen(hkRoot, pRegistration->sczRegistrationKey, KEY_QUERY_VALUE, &hkRegistration);
if (SUCCEEDED(hr))
{
hr = RegReadNumber(hkRegistration, REGISTRY_BUNDLE_INSTALLED, &dwInstalled);
ExitOnFailure(hr, "Failed to read registration %ls@%ls.", pRegistration->sczRegistrationKey, REGISTRY_BUNDLE_INSTALLED);

pRegistration->detectedRegistrationType = (1 == dwInstalled) ? BOOTSTRAPPER_REGISTRATION_TYPE_FULL : BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS;
}

// Not finding the key or value is okay.
if (E_FILENOTFOUND == hr || E_PATHNOTFOUND == hr)
{
hr = S_OK;
hr = RegReadNumber(hkRegistration, REGISTRY_BUNDLE_SCOPE, &dwScope);
ExitOnFailure(hr, "Failed to read registration %ls@%ls.", pRegistration->sczRegistrationKey, REGISTRY_BUNDLE_SCOPE);

pRegistration->detectedScope = static_cast<BOOTSTRAPPER_SCOPE>(dwScope);
}

LExit:
ReleaseRegKey(hkRegistration);

return hr;
Expand Down
3 changes: 2 additions & 1 deletion src/burn/engine/registration.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,11 +97,12 @@ typedef struct _BURN_REGISTRATION
// For configurable-scope bundles, fPerMachine is only valid after
// planning when scope is known. For fixed per-machine or per-user
// bundles, valid immediately.
BOOL fPerMachine;
BOOL fPerMachine;
BOOL fForceSystemComponent;
BOOL fDisableResume;
BOOL fCached;
BOOTSTRAPPER_REGISTRATION_TYPE detectedRegistrationType;
BOOTSTRAPPER_SCOPE detectedScope;
BOOTSTRAPPER_PACKAGE_SCOPE scope;
LPWSTR sczCode;
LPWSTR sczTag;
Expand Down
3 changes: 2 additions & 1 deletion src/burn/engine/variable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -305,8 +305,9 @@ extern "C" HRESULT VariableInitialize(
{BURN_BUNDLE_TAG, InitializeVariableString, (DWORD_PTR)L"", FALSE, TRUE},
{BURN_BUNDLE_UILEVEL, InitializeVariableNumeric, 0, FALSE, TRUE},
{BURN_BUNDLE_VERSION, InitializeVariableVersion, (DWORD_PTR)L"0", FALSE, TRUE},
{BURN_BUNDLE_SCOPE, InitializeVariableNumeric, 0, FALSE, TRUE},
{BURN_BUNDLE_AUTHORED_SCOPE, InitializeVariableNumeric, 0, FALSE, TRUE},
{BURN_BUNDLE_PLANNED_SCOPE, InitializeVariableNumeric, 0, FALSE, TRUE},
{BURN_BUNDLE_DETECTED_SCOPE, InitializeVariableNumeric, 0, FALSE, TRUE},
};

const WELL_KNOWN_VARIABLE_DECLARATION vrgWellKnownVariableNames[] =
Expand Down
17 changes: 14 additions & 3 deletions src/test/burn/WixToolsetTest.BurnE2E/ConfigurableScopeTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public void CommandLineScopeTestPerUser()
Assert.True(LogVerifier.MessageInLogFile(log, "Planned package: PmouPkg1.msi, state: Absent, default requested: Present, ba requested: Present, execute: Install, rollback: Uninstall, scope: PerUser"));
Assert.True(LogVerifier.MessageInLogFile(log, "Planned package: PmouPkg2.msi, state: Absent, default requested: Present, ba requested: Present, execute: Install, rollback: Uninstall, scope: PerUser"));

bundle.Uninstall(arguments: "/peruser");
bundle.Uninstall();
bundle.VerifyUnregisteredAndRemovedFromPackageCache(plannedPerMachine: false);
pkg1.VerifyInstalled(false);
pkg2.VerifyInstalled(false);
Expand All @@ -89,7 +89,7 @@ public void CommandLineScopeTestPerMachine()
Assert.True(LogVerifier.MessageInLogFile(log, "Planned package: PuomPkg1.msi, state: Absent, default requested: Present, ba requested: Present, execute: Install, rollback: Uninstall, scope: PerMachine,"));
Assert.True(LogVerifier.MessageInLogFile(log, "Planned package: PuomPkg2.msi, state: Absent, default requested: Present, ba requested: Present, execute: Install, rollback: Uninstall, scope: PerMachine,"));

bundle.Uninstall(arguments: "/permachine");
bundle.Uninstall();
bundle.VerifyUnregisteredAndRemovedFromPackageCache(plannedPerMachine: true);
pkg1.VerifyInstalled(false);
pkg2.VerifyInstalled(false);
Expand All @@ -115,6 +115,11 @@ public void PMOU_Bundle_Default_Plan_Installs_PerMachine()
Assert.True(LogVerifier.MessageInLogFile(log, "Planned package: PmouPkg1.msi, state: Absent, default requested: Present, ba requested: Present, execute: Install, rollback: Uninstall, scope: PerMachine,"));
Assert.True(LogVerifier.MessageInLogFile(log, "Planned package: PmouPkg2.msi, state: Absent, default requested: Present, ba requested: Present, execute: Install, rollback: Uninstall, scope: PerMachine,"));

log = bundle.Repair();
Assert.True(LogVerifier.MessageInLogFile(log, "Bundle was already installed with scope: PerMachine"));
Assert.True(LogVerifier.MessageInLogFile(log, "Detected package: PmouPkg1.msi, state: Present, authored scope: PerMachineOrUser, detected scope: PerMachine,"));
Assert.True(LogVerifier.MessageInLogFile(log, "Detected package: PmouPkg2.msi, state: Present, authored scope: PerMachineOrUser, detected scope: PerMachine,"));

bundle.Uninstall();
bundle.VerifyUnregisteredAndRemovedFromPackageCache(plannedPerMachine: true);
pkg1.VerifyInstalled(false);
Expand Down Expand Up @@ -450,9 +455,15 @@ public void PM_PU_PMOU_Bundle_Default_Plan_Installs_PerMachine()

Assert.True(LogVerifier.MessageInLogFile(log, "Plan begin, 5 packages, action: Install, planned scope: Default"));
Assert.True(LogVerifier.MessageInLogFile(log, "Planned package: PerMachinePkg.msi, state: Absent, default requested: Present, ba requested: Present, execute: Install, rollback: Uninstall, scope: PerMachine,"));
Assert.True(LogVerifier.MessageInLogFile(log, "Planned package: PerUserPkg.msi, state: Absent, default requested: Present, ba requested: Present, execute: Install, rollback: Uninstall, scope: PerUser"));
Assert.True(LogVerifier.MessageInLogFile(log, "Planned package: PmouPkg1.msi, state: Absent, default requested: Present, ba requested: Present, execute: Install, rollback: Uninstall, scope: PerMachine,"));
Assert.True(LogVerifier.MessageInLogFile(log, "Planned package: PmouPkg2.msi, state: Absent, default requested: Present, ba requested: Present, execute: Install, rollback: Uninstall, scope: PerMachine,"));
Assert.True(LogVerifier.MessageInLogFile(log, "Planned package: PerUserPkg.msi, state: Absent, default requested: Present, ba requested: Present, execute: Install, rollback: Uninstall, scope: PerUser"));

log = bundle.Repair();
Assert.True(LogVerifier.MessageInLogFile(log, "Detected package: PerMachinePkg.msi, state: Present, authored scope: PerMachine, detected scope: PerMachine,"));
Assert.True(LogVerifier.MessageInLogFile(log, "Detected package: PmouPkg1.msi, state: Present, authored scope: PerMachineOrUser, detected scope: PerMachine,"));
Assert.True(LogVerifier.MessageInLogFile(log, "Detected package: PmouPkg2.msi, state: Present, authored scope: PerMachineOrUser, detected scope: PerMachine,"));
Assert.True(LogVerifier.MessageInLogFile(log, "Detected package: PerUserPkg.msi, state: Present, authored scope: PerUser, detected scope: PerUser,"));

bundle.Uninstall();
bundle.VerifyUnregisteredAndRemovedFromPackageCache(plannedPerMachine: true);
Expand Down