MainPage.cpp (31028B)
1 #include "pch.h" 2 #include "MainPage.h" 3 #include "MainPage.g.cpp" 4 5 #include <wrl.h> 6 #include <winrt/Microsoft.Management.Deployment.h> 7 #include <winrt/Windows.UI.Core.h> 8 9 using namespace Microsoft::WRL; 10 using namespace std::chrono_literals; 11 using namespace winrt::Microsoft::Management::Deployment; 12 13 namespace winrt 14 { 15 using namespace Windows::UI::Xaml; 16 using namespace Windows::Foundation; 17 using namespace Windows::Foundation::Collections; 18 } 19 20 // CLSIDs for WinGet package 21 const CLSID CLSID_PackageManager = { 0xC53A4F16, 0x787E, 0x42A4, 0xB3, 0x04, 0x29, 0xEF, 0xFB, 0x4B, 0xF5, 0x97 }; //C53A4F16-787E-42A4-B304-29EFFB4BF597 22 const CLSID CLSID_InstallOptions = { 0x1095f097, 0xEB96, 0x453B, 0xB4, 0xE6, 0x16, 0x13, 0x63, 0x7F, 0x3B, 0x14 }; //1095F097-EB96-453B-B4E6-1613637F3B14 23 const CLSID CLSID_FindPackagesOptions = { 0x572DED96, 0x9C60, 0x4526, { 0x8F, 0x92, 0xEE, 0x7D, 0x91, 0xD3, 0x8C, 0x1A } }; //572DED96-9C60-4526-8F92-EE7D91D38C1A 24 const CLSID CLSID_PackageMatchFilter = { 0xD02C9DAF, 0x99DC, 0x429C, { 0xB5, 0x03, 0x4E, 0x50, 0x4E, 0x4A, 0xB0, 0x00 } }; //D02C9DAF-99DC-429C-B503-4E504E4AB000 25 const CLSID CLSID_CreateCompositePackageCatalogOptions = { 0x526534B8, 0x7E46, 0x47C8, { 0x84, 0x16, 0xB1, 0x68, 0x5C, 0x32, 0x7D, 0x37 } }; //526534B8-7E46-47C8-8416-B1685C327D37 26 const CLSID CLSID_DownloadOptions = { 0X4CBABE76, 0X7322, 0X4BE4, {0X9C, 0XEA, 0X25, 0X89, 0XA8, 0X06, 0X82, 0XDC} }; //4CBABE76-7322-4BE4-9CEA-2589A80682DC 27 28 // CLSIDs for WinGetDev package 29 const CLSID CLSID_PackageManager2 = { 0x74CB3139, 0xB7C5, 0x4B9E, { 0x93, 0x88, 0xE6, 0x61, 0x6D, 0xEA, 0x28, 0x8C } }; //74CB3139-B7C5-4B9E-9388-E6616DEA288C 30 const CLSID CLSID_InstallOptions2 = { 0x44FE0580, 0x62F7, 0x44D4, 0x9E, 0x91, 0xAA, 0x96, 0x14, 0xAB, 0x3E, 0x86 }; //44FE0580-62F7-44D4-9E91-AA9614AB3E86 31 const CLSID CLSID_FindPackagesOptions2 = { 0x1BD8FF3A, 0xEC50, 0x4F69, { 0xAE, 0xEE, 0xDF, 0x4C, 0x9D, 0x3B, 0xAA, 0x96 } }; //1BD8FF3A-EC50-4F69-AEEE-DF4C9D3BAA96 32 const CLSID CLSID_PackageMatchFilter2 = { 0x3F85B9F4, 0x487A, 0x4C48, { 0x90, 0x35, 0x29, 0x03, 0xF8, 0xA6, 0xD9, 0xE8 } }; //3F85B9F4-487A-4C48-9035-2903F8A6D9E8 33 const CLSID CLSID_CreateCompositePackageCatalogOptions2 = { 0xEE160901, 0xB317, 0x4EA7, { 0x9C, 0xC6, 0x53, 0x55, 0xC6, 0xD7, 0xD8, 0xA7 } }; //EE160901-B317-4EA7-9CC6-5355C6D7D8A7 34 const CLSID CLSID_DownloadOptions2 = { 0X8EF324ED, 0X367C, 0X4880, {0X83, 0XE5, 0XBB, 0X2A, 0XBD, 0X0B, 0X72, 0XF6} }; //8EF324ED-367C-4880-83E5-BB2ABD0B72F6 35 36 namespace winrt::AppInstallerCaller::implementation 37 { 38 MainPage::MainPage() 39 { 40 InitializeComponent(); 41 m_packageCatalogs = winrt::single_threaded_observable_vector<PackageCatalogReference>(); 42 m_installedPackages = winrt::single_threaded_observable_vector<CatalogPackage>(); 43 m_installingPackageViews = winrt::single_threaded_observable_vector<winrt::AppInstallerCaller::InstallingPackageView>(); 44 } 45 46 PackageManager MainPage::CreatePackageManager() { 47 if (m_useDev) 48 { 49 return winrt::create_instance<PackageManager>(CLSID_PackageManager2, CLSCTX_ALL); 50 } 51 return winrt::create_instance<PackageManager>(CLSID_PackageManager, CLSCTX_ALL); 52 } 53 InstallOptions MainPage::CreateInstallOptions() { 54 if (m_useDev) 55 { 56 return winrt::create_instance<InstallOptions>(CLSID_InstallOptions2, CLSCTX_ALL); 57 } 58 return winrt::create_instance<InstallOptions>(CLSID_InstallOptions, CLSCTX_ALL); 59 } 60 FindPackagesOptions MainPage::CreateFindPackagesOptions() { 61 if (m_useDev) 62 { 63 return winrt::create_instance<FindPackagesOptions>(CLSID_FindPackagesOptions2, CLSCTX_ALL); 64 } 65 return winrt::create_instance<FindPackagesOptions>(CLSID_FindPackagesOptions, CLSCTX_ALL); 66 } 67 CreateCompositePackageCatalogOptions MainPage::CreateCreateCompositePackageCatalogOptions() { 68 if (m_useDev) 69 { 70 return winrt::create_instance<CreateCompositePackageCatalogOptions>(CLSID_CreateCompositePackageCatalogOptions2, CLSCTX_ALL); 71 } 72 return winrt::create_instance<CreateCompositePackageCatalogOptions>(CLSID_CreateCompositePackageCatalogOptions, CLSCTX_ALL); 73 } 74 PackageMatchFilter MainPage::CreatePackageMatchFilter() { 75 if (m_useDev) 76 { 77 return winrt::create_instance<PackageMatchFilter>(CLSID_PackageMatchFilter2, CLSCTX_ALL); 78 } 79 return winrt::create_instance<PackageMatchFilter>(CLSID_PackageMatchFilter, CLSCTX_ALL); 80 } 81 DownloadOptions MainPage::CreateDownloadOptions() { 82 if (m_useDev) 83 { 84 return winrt::create_instance<DownloadOptions>(CLSID_DownloadOptions2, CLSCTX_ALL); 85 } 86 return winrt::create_instance<DownloadOptions>(CLSID_DownloadOptions, CLSCTX_ALL); 87 } 88 89 IAsyncOperation<PackageCatalog> MainPage::FindSourceAsync(std::wstring packageSource) 90 { 91 PackageManager packageManager = CreatePackageManager(); 92 PackageCatalogReference catalogRef{ packageManager.GetPackageCatalogByName(packageSource) }; 93 if (catalogRef) 94 { 95 ConnectResult connectResult{ co_await catalogRef.ConnectAsync() }; 96 // PackageCatalog will be null if connectResult.ErrorCode() is a failure 97 PackageCatalog catalog = connectResult.PackageCatalog(); 98 co_return catalog; 99 } 100 } 101 102 IAsyncOperation<FindPackagesResult> MainPage::TryFindPackageInCatalogAsync(PackageCatalog catalog, std::wstring packageId) 103 { 104 FindPackagesOptions findPackagesOptions = CreateFindPackagesOptions(); 105 PackageMatchFilter filter = CreatePackageMatchFilter(); 106 filter.Field(PackageMatchField::Id); 107 filter.Option(PackageFieldMatchOption::Equals); 108 filter.Value(packageId); 109 findPackagesOptions.Filters().Append(filter); 110 return catalog.FindPackagesAsync(findPackagesOptions); 111 } 112 IAsyncOperation<CatalogPackage> MainPage::FindPackageInCatalogAsync(PackageCatalog catalog, std::wstring packageId) 113 { 114 FindPackagesOptions findPackagesOptions = CreateFindPackagesOptions(); 115 PackageMatchFilter filter = CreatePackageMatchFilter(); 116 filter.Field(PackageMatchField::Id); 117 filter.Option(PackageFieldMatchOption::Equals); 118 filter.Value(packageId); 119 findPackagesOptions.Filters().Append(filter); 120 FindPackagesResult findPackagesResult{ co_await catalog.FindPackagesAsync(findPackagesOptions) }; 121 122 winrt::IVectorView<MatchResult> matches = findPackagesResult.Matches(); 123 if (matches.Size() == 0) 124 { 125 co_return nullptr; 126 } 127 co_return matches.GetAt(0).CatalogPackage(); 128 } 129 130 IAsyncOperationWithProgress<InstallResult, InstallProgress> MainPage::InstallPackage(CatalogPackage package) 131 { 132 PackageManager packageManager = CreatePackageManager(); 133 InstallOptions installOptions = CreateInstallOptions(); 134 135 // Passing PackageInstallScope::User causes the install to fail if there's no installer that supports that. 136 installOptions.PackageInstallScope(PackageInstallScope::Any); 137 installOptions.PackageInstallMode(PackageInstallMode::Silent); 138 139 return packageManager.InstallPackageAsync(package, installOptions); 140 } 141 142 IAsyncOperationWithProgress<DownloadResult, PackageDownloadProgress> MainPage::DownloadPackage(CatalogPackage package, std::wstring downloadDirectory) 143 { 144 PackageManager packageManager = CreatePackageManager(); 145 DownloadOptions downloadOptions = CreateDownloadOptions(); 146 147 if (!downloadDirectory.empty()) 148 { 149 downloadOptions.DownloadDirectory(downloadDirectory); 150 } 151 152 return packageManager.DownloadPackageAsync(package, downloadOptions); 153 } 154 155 IAsyncAction UpdateUIProgress( 156 InstallProgress progress, 157 winrt::Windows::UI::Xaml::Controls::ProgressBar progressBar, 158 winrt::Windows::UI::Xaml::Controls::TextBlock statusText) 159 { 160 co_await winrt::resume_foreground(progressBar.Dispatcher()); 161 progressBar.Value(progress.DownloadProgress*100); 162 163 std::wstring downloadText{ L"Downloading. " }; 164 switch (progress.State) 165 { 166 case PackageInstallProgressState::Queued: 167 statusText.Text(L"Queued"); 168 break; 169 case PackageInstallProgressState::Downloading: 170 downloadText += std::to_wstring(progress.BytesDownloaded) + L" bytes of " + std::to_wstring(progress.BytesRequired); 171 statusText.Text(downloadText); 172 break; 173 case PackageInstallProgressState::Installing: 174 statusText.Text(L"Installing"); 175 progressBar.IsIndeterminate(true); 176 break; 177 case PackageInstallProgressState::PostInstall: 178 statusText.Text(L"Finishing install"); 179 break; 180 case PackageInstallProgressState::Finished: 181 statusText.Text(L"Finished install."); 182 progressBar.IsIndeterminate(false); 183 break; 184 default: 185 statusText.Text(L""); 186 } 187 } 188 189 IAsyncAction UpdateUIDownloadProgress( 190 PackageDownloadProgress progress, 191 winrt::Windows::UI::Xaml::Controls::ProgressBar progressBar, 192 winrt::Windows::UI::Xaml::Controls::TextBlock statusText) 193 { 194 co_await winrt::resume_foreground(progressBar.Dispatcher()); 195 progressBar.Value(progress.DownloadProgress * 100); 196 197 std::wstring downloadText{ L"Downloading. " }; 198 switch (progress.State) 199 { 200 case PackageDownloadProgressState::Queued: 201 statusText.Text(L"Queued"); 202 break; 203 case PackageDownloadProgressState::Downloading: 204 downloadText += std::to_wstring(progress.BytesDownloaded) + L" bytes of " + std::to_wstring(progress.BytesRequired); 205 statusText.Text(downloadText); 206 break; 207 case PackageDownloadProgressState::Finished: 208 statusText.Text(L"Finished download."); 209 progressBar.IsIndeterminate(false); 210 break; 211 default: 212 statusText.Text(L""); 213 } 214 } 215 216 // This method is called from a background thread. 217 IAsyncAction UpdateUIForInstall( 218 IAsyncOperationWithProgress<InstallResult, InstallProgress> installPackageOperation, 219 winrt::Windows::UI::Xaml::Controls::Button installButton, 220 winrt::Windows::UI::Xaml::Controls::Button cancelButton, 221 winrt::Windows::UI::Xaml::Controls::ProgressBar progressBar, 222 winrt::Windows::UI::Xaml::Controls::TextBlock statusText) 223 { 224 installPackageOperation.Progress([=]( 225 IAsyncOperationWithProgress<InstallResult, InstallProgress> const& /* sender */, 226 InstallProgress const& progress) 227 { 228 UpdateUIProgress(progress, progressBar, statusText).get(); 229 }); 230 231 winrt::hresult installOperationHr = S_OK; 232 std::wstring errorMessage{ L"Unknown Error" }; 233 InstallResult installResult{ nullptr }; 234 try 235 { 236 installResult = co_await installPackageOperation; 237 } 238 catch (hresult_canceled const&) 239 { 240 errorMessage = L"Cancelled"; 241 OutputDebugString(L"Operation was cancelled"); 242 } 243 catch (...) 244 { 245 // Operation failed 246 // Example: HRESULT_FROM_WIN32(ERROR_DISK_FULL). 247 installOperationHr = winrt::to_hresult(); 248 // Example: "There is not enough space on the disk." 249 errorMessage = winrt::to_message(); 250 OutputDebugString(L"Operation failed"); 251 } 252 253 // Switch back to ui thread context. 254 co_await winrt::resume_foreground(progressBar.Dispatcher()); 255 256 cancelButton.IsEnabled(false); 257 installButton.IsEnabled(true); 258 progressBar.IsIndeterminate(false); 259 260 if (installPackageOperation.Status() == AsyncStatus::Canceled) 261 { 262 installButton.Content(box_value(L"Retry")); 263 statusText.Text(L"Install cancelled."); 264 } 265 if (installPackageOperation.Status() == AsyncStatus::Error || installResult == nullptr) 266 { 267 installButton.Content(box_value(L"Retry")); 268 statusText.Text(errorMessage); 269 } 270 else if (installResult.RebootRequired()) 271 { 272 installButton.Content(box_value(L"Install")); 273 statusText.Text(L"Reboot to finish installation."); 274 } 275 else if (installResult.Status() == InstallResultStatus::Ok) 276 { 277 installButton.Content(box_value(L"Install")); 278 statusText.Text(L"Finished."); 279 } 280 else 281 { 282 std::wostringstream failText; 283 failText << L"Install failed: " << installResult.ExtendedErrorCode() << L" [" << installResult.InstallerErrorCode() << L"]"; 284 installButton.Content(box_value(L"Install")); 285 statusText.Text(failText.str()); 286 } 287 } 288 289 // This method is called from a background thread. 290 IAsyncAction UpdateUIForDownload( 291 IAsyncOperationWithProgress<DownloadResult, PackageDownloadProgress> operation, 292 winrt::Windows::UI::Xaml::Controls::Button downloadButton, 293 winrt::Windows::UI::Xaml::Controls::Button cancelButton, 294 winrt::Windows::UI::Xaml::Controls::ProgressBar progressBar, 295 winrt::Windows::UI::Xaml::Controls::TextBlock statusText) 296 { 297 operation.Progress([=]( 298 IAsyncOperationWithProgress<DownloadResult, PackageDownloadProgress> const& /* sender */, 299 PackageDownloadProgress const& progress) 300 { 301 UpdateUIDownloadProgress(progress, progressBar, statusText).get(); 302 }); 303 304 winrt::hresult downloadOperationHr = S_OK; 305 std::wstring errorMessage{ L"Unknown Error" }; 306 DownloadResult downloadResult{ nullptr }; 307 try 308 { 309 downloadResult = co_await operation; 310 } 311 catch (hresult_canceled const&) 312 { 313 errorMessage = L"Cancelled"; 314 OutputDebugString(L"Operation was cancelled"); 315 } 316 catch (...) 317 { 318 // Operation failed 319 // Example: HRESULT_FROM_WIN32(ERROR_DISK_FULL). 320 downloadOperationHr = winrt::to_hresult(); 321 // Example: "There is not enough space on the disk." 322 errorMessage = winrt::to_message(); 323 OutputDebugString(L"Operation failed"); 324 } 325 326 // Switch back to ui thread context. 327 co_await winrt::resume_foreground(progressBar.Dispatcher()); 328 329 cancelButton.IsEnabled(false); 330 downloadButton.IsEnabled(true); 331 progressBar.IsIndeterminate(false); 332 333 if (operation.Status() == AsyncStatus::Canceled) 334 { 335 downloadButton.Content(box_value(L"Retry")); 336 statusText.Text(L"Download cancelled."); 337 } 338 if (operation.Status() == AsyncStatus::Error || downloadResult == nullptr) 339 { 340 downloadButton.Content(box_value(L"Retry")); 341 statusText.Text(errorMessage); 342 } 343 else if (downloadResult.Status() == DownloadResultStatus::Ok) 344 { 345 downloadButton.Content(box_value(L"Download")); 346 statusText.Text(L"Finished."); 347 } 348 else 349 { 350 std::wostringstream failText; 351 failText << L"Download failed: " << downloadResult.ExtendedErrorCode(); 352 downloadButton.Content(box_value(L"Download")); 353 statusText.Text(failText.str()); 354 } 355 } 356 357 IAsyncAction MainPage::GetSources(winrt::Windows::UI::Xaml::Controls::Button button) 358 { 359 co_await winrt::resume_background(); 360 361 PackageManager packageManager = CreatePackageManager(); 362 auto catalogs{ packageManager.GetPackageCatalogs() }; 363 auto storeCatalog{ packageManager.GetPredefinedPackageCatalog(PredefinedPackageCatalog::MicrosoftStore) }; 364 365 co_await winrt::resume_foreground(button.Dispatcher()); 366 367 m_packageCatalogs.Clear(); 368 for (auto const catalog : catalogs) 369 { 370 m_packageCatalogs.Append(catalog); 371 } 372 m_packageCatalogs.Append(storeCatalog); 373 374 co_return; 375 } 376 377 IAsyncAction MainPage::GetInstalledPackages(winrt::Windows::UI::Xaml::Controls::TextBlock statusText) 378 { 379 int32_t selectedIndex = catalogsListBox().SelectedIndex(); 380 co_await winrt::resume_background(); 381 382 PackageManager packageManager = CreatePackageManager(); 383 384 PackageCatalogReference installedSearchCatalogRef{ nullptr }; 385 386 if (selectedIndex < 0) 387 { 388 installedSearchCatalogRef = packageManager.GetLocalPackageCatalog(LocalPackageCatalog::InstalledPackages); 389 } 390 else 391 { 392 PackageCatalogReference selectedRemoteCatalogRef = m_packageCatalogs.GetAt(selectedIndex); 393 CreateCompositePackageCatalogOptions createCompositePackageCatalogOptions = CreateCreateCompositePackageCatalogOptions(); 394 createCompositePackageCatalogOptions.Catalogs().Append(selectedRemoteCatalogRef); 395 396 createCompositePackageCatalogOptions.CompositeSearchBehavior(CompositeSearchBehavior::LocalCatalogs); 397 installedSearchCatalogRef = packageManager.CreateCompositePackageCatalog(createCompositePackageCatalogOptions); 398 } 399 400 ConnectResult connectResult{ co_await installedSearchCatalogRef.ConnectAsync() }; 401 PackageCatalog installedCatalog = connectResult.PackageCatalog(); 402 if (!installedCatalog) 403 { 404 // Connect Error. 405 co_await winrt::resume_foreground(statusText.Dispatcher()); 406 statusText.Text(L"Failed to connect to catalog."); 407 co_return; 408 } 409 410 FindPackagesOptions findPackagesOptions = CreateFindPackagesOptions(); 411 412 FindPackagesResult findResult{ TryFindPackageInCatalogAsync(installedCatalog, m_installAppId).get() }; 413 auto matches = findResult.Matches(); 414 415 co_await winrt::resume_foreground(statusText.Dispatcher()); 416 m_installedPackages.Clear(); 417 for (auto const match : matches) 418 { 419 // Filter to only packages that match the selectedCatalogRef 420 auto version = match.CatalogPackage().DefaultInstallVersion(); 421 if (selectedIndex < 0 || (version && version.PackageCatalog().Info().Id() == m_packageCatalogs.GetAt(selectedIndex).Info().Id())) 422 { 423 m_installedPackages.Append(match.CatalogPackage()); 424 } 425 } 426 427 statusText.Text(L""); 428 co_return; 429 } 430 IAsyncAction MainPage::GetInstallingPackages(winrt::Windows::UI::Xaml::Controls::TextBlock statusText) 431 { 432 int32_t selectedIndex = catalogsListBox().SelectedIndex(); 433 co_await winrt::resume_background(); 434 435 PackageManager packageManager = CreatePackageManager(); 436 437 PackageCatalogReference installingSearchCatalogRef{ nullptr }; 438 439 if (selectedIndex < 0) 440 { 441 // Installing package querying is only really useful if you know what Catalog you're interested in. 442 co_await winrt::resume_foreground(statusText.Dispatcher()); 443 statusText.Text(L"No catalog selected."); 444 co_return; 445 } 446 447 installingSearchCatalogRef = packageManager.GetLocalPackageCatalog(LocalPackageCatalog::InstallingPackages); 448 449 PackageCatalogReference selectedRemoteCatalogRef = m_packageCatalogs.GetAt(selectedIndex); 450 ConnectResult remoteConnectResult{ co_await selectedRemoteCatalogRef.ConnectAsync() }; 451 PackageCatalog selectedRemoteCatalog = remoteConnectResult.PackageCatalog(); 452 if (!selectedRemoteCatalog) 453 { 454 co_await winrt::resume_foreground(statusText.Dispatcher()); 455 statusText.Text(L"Failed to connect to catalog."); 456 co_return; 457 } 458 459 ConnectResult connectResult{ co_await installingSearchCatalogRef.ConnectAsync() }; 460 PackageCatalog installingCatalog = connectResult.PackageCatalog(); 461 if (!installingCatalog) 462 { 463 co_await winrt::resume_foreground(statusText.Dispatcher()); 464 statusText.Text(L"Failed to connect to catalog."); 465 co_return; 466 } 467 468 FindPackagesOptions findPackagesOptions = CreateFindPackagesOptions(); 469 470 FindPackagesResult findResult{ TryFindPackageInCatalogAsync(selectedRemoteCatalog, m_installAppId).get() }; 471 auto matches = findResult.Matches(); 472 473 co_await winrt::resume_foreground(statusText.Dispatcher()); 474 475 m_installingPackageViews.Clear(); 476 for (auto const match : matches) 477 { 478 winrt::AppInstallerCaller::InstallingPackageView installingView; 479 installingView.Package(match.CatalogPackage()); 480 auto installOperation = packageManager.GetInstallProgress(installingView.Package(), selectedRemoteCatalog.Info()); 481 if (installOperation) 482 { 483 installingView.Dispatcher(statusText.Dispatcher()); 484 installingView.AsyncOperation(installOperation); 485 m_installingPackageViews.Append(installingView); 486 } 487 } 488 489 statusText.Text(L""); 490 co_return; 491 } 492 493 IAsyncAction MainPage::StartInstall( 494 winrt::Windows::UI::Xaml::Controls::Button installButton, 495 winrt::Windows::UI::Xaml::Controls::Button cancelButton, 496 winrt::Windows::UI::Xaml::Controls::ProgressBar progressBar, 497 winrt::Windows::UI::Xaml::Controls::TextBlock statusText) 498 { 499 installButton.IsEnabled(false); 500 cancelButton.IsEnabled(true); 501 int32_t selectedIndex = catalogsListBox().SelectedIndex(); 502 503 co_await winrt::resume_background(); 504 505 if (selectedIndex < 0) 506 { 507 co_await winrt::resume_foreground(installButton.Dispatcher()); 508 installButton.IsEnabled(false); 509 statusText.Text(L"No catalog selected to install."); 510 co_return; 511 } 512 513 // Get the remote catalog 514 PackageCatalogReference selectedRemoteCatalogRef = m_packageCatalogs.GetAt(selectedIndex); 515 ConnectResult remoteConnectResult{ co_await selectedRemoteCatalogRef.ConnectAsync() }; 516 PackageCatalog selectedRemoteCatalog = remoteConnectResult.PackageCatalog(); 517 if (!selectedRemoteCatalog) 518 { 519 co_await winrt::resume_foreground(progressBar.Dispatcher()); 520 statusText.Text(L"Connecting to catalog failed."); 521 co_return; 522 } 523 FindPackagesResult findPackagesResult{ TryFindPackageInCatalogAsync(selectedRemoteCatalog, m_installAppId).get() }; 524 winrt::IVectorView<MatchResult> matches = findPackagesResult.Matches(); 525 if (matches.Size() > 0) 526 { 527 m_installPackageOperation = InstallPackage(matches.GetAt(0).CatalogPackage()); 528 UpdateUIForInstall(m_installPackageOperation, installButton, cancelButton, progressBar, statusText); 529 } 530 } 531 532 IAsyncAction MainPage::StartDownload( 533 winrt::Windows::UI::Xaml::Controls::Button button, 534 winrt::Windows::UI::Xaml::Controls::Button cancelButton, 535 winrt::Windows::UI::Xaml::Controls::ProgressBar progressBar, 536 winrt::Windows::UI::Xaml::Controls::TextBlock statusText) 537 { 538 button.IsEnabled(false); 539 cancelButton.IsEnabled(true); 540 int32_t selectedIndex = catalogsListBox().SelectedIndex(); 541 542 co_await winrt::resume_background(); 543 544 if (selectedIndex < 0) 545 { 546 co_await winrt::resume_foreground(button.Dispatcher()); 547 button.IsEnabled(false); 548 statusText.Text(L"No catalog selected to download."); 549 co_return; 550 } 551 552 // Get the remote catalog 553 PackageCatalogReference selectedRemoteCatalogRef = m_packageCatalogs.GetAt(selectedIndex); 554 ConnectResult remoteConnectResult{ co_await selectedRemoteCatalogRef.ConnectAsync() }; 555 PackageCatalog selectedRemoteCatalog = remoteConnectResult.PackageCatalog(); 556 if (!selectedRemoteCatalog) 557 { 558 co_await winrt::resume_foreground(progressBar.Dispatcher()); 559 statusText.Text(L"Connecting to catalog failed."); 560 co_return; 561 } 562 FindPackagesResult findPackagesResult{ TryFindPackageInCatalogAsync(selectedRemoteCatalog, m_installAppId).get() }; 563 winrt::IVectorView<MatchResult> matches = findPackagesResult.Matches(); 564 if (matches.Size() > 0) 565 { 566 m_downloadPackageOperation = DownloadPackage(matches.GetAt(0).CatalogPackage(), m_downloadDirectory); 567 UpdateUIForDownload(m_downloadPackageOperation, button, cancelButton, progressBar, statusText); 568 } 569 } 570 571 IAsyncAction MainPage::FindPackage( 572 winrt::Windows::UI::Xaml::Controls::Button installButton, 573 winrt::Windows::UI::Xaml::Controls::Button downloadButton, 574 winrt::Windows::UI::Xaml::Controls::ProgressBar progressBar, 575 winrt::Windows::UI::Xaml::Controls::TextBlock statusText) 576 { 577 int32_t selectedIndex = catalogsListBox().SelectedIndex(); 578 if (selectedIndex < 0) 579 { 580 co_await winrt::resume_foreground(installButton.Dispatcher()); 581 installButton.IsEnabled(false); 582 statusText.Text(L"No catalog selected to search."); 583 co_return; 584 } 585 586 co_await winrt::resume_background(); 587 588 // Get the remote catalog 589 PackageCatalogReference selectedRemoteCatalogRef = m_packageCatalogs.GetAt(selectedIndex); 590 // Create the composite catalog 591 CreateCompositePackageCatalogOptions createCompositePackageCatalogOptions = CreateCreateCompositePackageCatalogOptions(); 592 createCompositePackageCatalogOptions.Catalogs().Append(selectedRemoteCatalogRef); 593 PackageManager packageManager = CreatePackageManager(); 594 PackageCatalogReference catalogRef{ packageManager.CreateCompositePackageCatalog(createCompositePackageCatalogOptions) }; 595 ConnectResult connectResult{ co_await catalogRef.ConnectAsync() }; 596 PackageCatalog compositeCatalog = connectResult.PackageCatalog(); 597 if (!compositeCatalog) 598 { 599 co_await winrt::resume_foreground(installButton.Dispatcher()); 600 installButton.IsEnabled(false); 601 statusText.Text(L"Failed to connect to catalog."); 602 co_return; 603 } 604 605 // Do the search. 606 FindPackagesResult findPackagesResult{ TryFindPackageInCatalogAsync(compositeCatalog, m_installAppId).get() }; 607 608 winrt::IVectorView<MatchResult> matches = findPackagesResult.Matches(); 609 if (matches.Size() > 0) 610 { 611 auto installedVersion = matches.GetAt(0).CatalogPackage().InstalledVersion(); 612 if (installedVersion != nullptr) 613 { 614 co_await winrt::resume_foreground(installButton.Dispatcher()); 615 installButton.IsEnabled(false); 616 statusText.Text(L"Already installed. Product code: " + installedVersion.ProductCodes().GetAt(0)); 617 } 618 else 619 { 620 co_await winrt::resume_foreground(installButton.Dispatcher()); 621 installButton.IsEnabled(true); 622 downloadButton.IsEnabled(true); 623 statusText.Text(L"Found the package to install or download."); 624 } 625 } 626 else 627 { 628 co_await winrt::resume_foreground(installButton.Dispatcher()); 629 installButton.IsEnabled(false); 630 statusText.Text(L"Did not find package."); 631 } 632 co_return; 633 } 634 635 void MainPage::SearchButtonClickHandler(IInspectable const&, RoutedEventArgs const&) 636 { 637 m_installAppId = catalogIdTextBox().Text(); 638 installButton().IsEnabled(false); 639 downloadButton().IsEnabled(false); 640 cancelButton().IsEnabled(false); 641 installStatusText().Text(L"Looking for package."); 642 FindPackage(installButton(), downloadButton(), installProgressBar(), installStatusText()); 643 } 644 645 void MainPage::InstallButtonClickHandler(IInspectable const&, RoutedEventArgs const&) 646 { 647 if (m_installPackageOperation == nullptr || m_installPackageOperation.Status() != AsyncStatus::Started) 648 { 649 StartInstall(installButton(), cancelButton(), installProgressBar(), installStatusText()); 650 } 651 } 652 653 void MainPage::CancelButtonClickHandler(IInspectable const&, RoutedEventArgs const&) 654 { 655 if (m_installPackageOperation && m_installPackageOperation.Status() == AsyncStatus::Started) 656 { 657 m_installPackageOperation.Cancel(); 658 } 659 } 660 661 void MainPage::DownloadButtonClickHandler(IInspectable const&, RoutedEventArgs const&) 662 { 663 m_downloadDirectory = downloadDirectoryTextBox().Text(); 664 665 if (m_downloadPackageOperation == nullptr || m_downloadPackageOperation.Status() != AsyncStatus::Started) 666 { 667 StartDownload(downloadButton(), downloadCancelButton(), downloadProgressBar(), downloadStatusText()); 668 } 669 } 670 671 void MainPage::DownloadCancelButtonClickHandler(IInspectable const&, RoutedEventArgs const&) 672 { 673 if (m_downloadPackageOperation && m_downloadPackageOperation.Status() == AsyncStatus::Started) 674 { 675 m_downloadPackageOperation.Cancel(); 676 } 677 } 678 679 void MainPage::RefreshInstalledButtonClickHandler(IInspectable const&, RoutedEventArgs const&) 680 { 681 GetInstalledPackages(installedStatusText()); 682 } 683 void MainPage::ClearInstalledButtonClickHandler(IInspectable const&, RoutedEventArgs const&) 684 { 685 m_installedPackages.Clear(); 686 } 687 void MainPage::RefreshInstallingButtonClickHandler(IInspectable const&, RoutedEventArgs const&) 688 { 689 GetInstallingPackages(installingStatusText()); 690 } 691 void MainPage::ClearInstallingButtonClickHandler(IInspectable const&, RoutedEventArgs const&) 692 { 693 m_installingPackageViews.Clear(); 694 } 695 696 void MainPage::ToggleDevSwitchToggled(IInspectable const&, winrt::Windows::UI::Xaml::RoutedEventArgs const&) 697 { 698 m_useDev = toggleDevSwitch().IsOn(); 699 } 700 void MainPage::FindSourcesButtonClickHandler(IInspectable const&, RoutedEventArgs const&) 701 { 702 GetSources(installButton()); 703 } 704 705 Windows::Foundation::Collections::IObservableVector<Microsoft::Management::Deployment::PackageCatalogReference> MainPage::PackageCatalogs() 706 { 707 return m_packageCatalogs; 708 } 709 Windows::Foundation::Collections::IObservableVector<Microsoft::Management::Deployment::CatalogPackage> MainPage::InstalledApps() 710 { 711 return m_installedPackages; 712 } 713 Windows::Foundation::Collections::IObservableVector<winrt::AppInstallerCaller::InstallingPackageView> MainPage::InstallingPackages() 714 { 715 return m_installingPackageViews; 716 } 717 }