55#include < winget/ManifestCommon.h>
66#include < winget/Runtime.h>
77#include < AppInstallerFileLogger.h>
8+ #include < AppInstallerDeployment.h>
89#include < AppInstallerErrors.h>
910#include < winrt/Windows.ApplicationModel.h>
1011
@@ -14,6 +15,7 @@ namespace AppInstaller::MSStore
1415 using namespace winrt ::Windows::Foundation;
1516 using namespace winrt ::Windows::Foundation::Collections;
1617 using namespace winrt ::Windows::ApplicationModel::Store::Preview::InstallControl;
18+ using namespace winrt ::Windows::Management::Deployment;
1719
1820 namespace
1921 {
@@ -213,6 +215,50 @@ namespace AppInstaller::MSStore
213215 std::atomic_bool m_isUpdating = false ;
214216 };
215217
218+ // After a successful machine-scope Store install, the package may not be provisioned on older
219+ // Windows versions (fixed in Windows 11 26100). This helper ensures the package is provisioned
220+ // as a best-effort mitigation.
221+ void EnsureProvisionedForMachineScope (const IVectorView<AppInstallItem>& installItems, std::wstring_view productId, IProgressCallback& progress) try
222+ {
223+ PackageManager packageManager;
224+ auto provisionedPackages = packageManager.FindProvisionedPackages ();
225+
226+ for (auto const & installItem : installItems)
227+ {
228+ if (Utility::CaseInsensitiveEquals (installItem.ProductId (), productId))
229+ {
230+ std::wstring familyName{ installItem.PackageFamilyName () };
231+ if (familyName.empty ())
232+ {
233+ continue ;
234+ }
235+
236+ bool isProvisioned = false ;
237+ for (auto const & provisionedPkg : provisionedPackages)
238+ {
239+ if (provisionedPkg.Id ().FamilyName () == familyName)
240+ {
241+ isProvisioned = true ;
242+ break ;
243+ }
244+ }
245+
246+ if (!isProvisioned)
247+ {
248+ AICLI_LOG (Core, Info, << " Package not provisioned after machine scope install, provisioning: " << Utility::ConvertToUTF8 (familyName));
249+ try
250+ {
251+ auto operation = packageManager.ProvisionPackageForAllUsersAsync (familyName);
252+ Deployment::WaitForDeployment (operation, progress);
253+ AICLI_LOG (Core, Info, << " Successfully provisioned package: " << Utility::ConvertToUTF8 (familyName));
254+ }
255+ CATCH_LOG ();
256+ }
257+ }
258+ }
259+ }
260+ CATCH_LOG ();
261+
216262 HRESULT WaitForOperation (const std::wstring& productId, bool isSilentMode, IVectorView<AppInstallItem>& installItems, IProgressCallback& progress, const PackageUpdateMonitor& monitor)
217263 {
218264 auto cancelIfOperationFailed = wil::scope_exit (
@@ -321,6 +367,18 @@ namespace AppInstaller::MSStore
321367 }
322368 }
323369
370+ #ifndef AICLI_DISABLE_TEST_HOOKS
371+ namespace TestHooks
372+ {
373+ static bool * s_ProvisionAfterInstall = nullptr ;
374+
375+ void TestHook_SetProvisionAfterInstall (bool * value)
376+ {
377+ s_ProvisionAfterInstall = value;
378+ }
379+ }
380+ #endif
381+
324382 HRESULT MSStoreOperation::InstallPackage (IProgressCallback& progress)
325383 {
326384 PackageUpdateMonitor monitor;
@@ -378,7 +436,25 @@ namespace AppInstaller::MSStore
378436 installOptions).get ();
379437 }
380438
381- return WaitForOperation (m_productId, m_isSilentMode, installItems, progress, monitor);
439+ HRESULT hr = WaitForOperation (m_productId, m_isSilentMode, installItems, progress, monitor);
440+
441+ bool shouldProvision = m_scope == Manifest::ScopeEnum::Machine;
442+ #ifndef AICLI_DISABLE_TEST_HOOKS
443+ if (TestHooks::s_ProvisionAfterInstall)
444+ {
445+ shouldProvision = *TestHooks::s_ProvisionAfterInstall;
446+ }
447+ #endif
448+
449+ if (SUCCEEDED (hr) && shouldProvision)
450+ {
451+ // Mitigation: on older OS versions (fixed in Windows 11 26100) the Store install service
452+ // may not provision the package even when InstallForAllUsers was set.
453+ // Explicitly provision if not already provisioned.
454+ EnsureProvisionedForMachineScope (installItems, m_productId, progress);
455+ }
456+
457+ return hr;
382458 }
383459
384460 HRESULT MSStoreOperation::UpdatePackage (IProgressCallback& progress)
0 commit comments