從 Microsoft Store 下載與安裝套件更新Download and install package updates from the Store

從 Windows 10 版本 1607 開始,您可以使用 Windows.Services.Store 命名空間中 StoreContext 類別的方法,以程式設計方式檢查 Microsoft Store 中目前應用程式的套件更新,以及下載並安裝更新的套件。Starting in Windows 10, version 1607, you can use methods of the StoreContext class in the Windows.Services.Store namespace to programmatically check for package updates for the current app from the Microsoft Store, and download and install the updated packages. 您也可以在合作夥伴中心上查詢已標示為強制性的套件,並在安裝強制更新之前在您的應用程式中停用功能。You can also query for packages that you have marked as mandatory in Partner Center and disable functionality in your app until the mandatory update is installed.

在 Windows 10 版本 1803 中導入的其他 StoreContext 方法可讓您下載及以無訊息方式安裝套件更新 (不向使用者顯示 UI 通知)、解除安裝選用套件,以及取得應用程式下載和安裝佇列中套件的資訊。Additional StoreContext methods introduced in Windows 10, version 1803 enable you to download and install package updates silently (without displaying a notification UI to the user), uninstall an optional package, and get info about packages in the download and install queue for your app.

這些功能可協助您讓您的使用者從 Microsoft Store 自動獲得應用程式最新版本、選用套件、相關服務的最新資訊。These features help you automatically keep your user base up to date with the latest version of your app, optional packages, and related services in the Store.

經使用者同意,下載並安裝套件更新Download and install package updates with the user's permission

此程式碼範例示範如何使用 GetAppAndOptionalStorePackageUpdatesAsync 方法來探索 Microsoft Store 中的所有可用套件更新,然後呼叫 RequestDownloadAndInstallStorePackageUpdatesAsync 方法下載並安裝更新。This code example demonstrates how to use the GetAppAndOptionalStorePackageUpdatesAsync method to discover all available package updates from the Store and then call the RequestDownloadAndInstallStorePackageUpdatesAsync method to download and install the updates. 使用此方法來下載並安裝更新時,作業系統會在下載更新之前顯示對話方塊,徵求使用者同意。When using this method to download and install updates, the OS displays a dialog that asks the user's permission before downloading the updates.

注意

這些方法支援應用程式的所需和選用套件These methods support required and optional packages for your app. 選用套件相當適合用於附加可下載內容 (DLC)、根據大小限制將大型應用程式進行分割,或是傳送與您核心應用程式分離的額外內容。Optional packages are useful for downloadable content (DLC) add-ons, dividing your large app for size constraints, or for shipping additional content separate from your core app. 請參閱 Windows 開發人員支援,以取得將使用選用套件 (包括 DLC 附加內容) 的應用程式提交至 Microsoft Store 的權限。To get permission to submit an app that uses optional packages (including DLC add-ons) to the Store, see Windows developer support.

此程式碼範例假設:This code example assumes:

  • 程式碼會在 Page 的內容中執行。The code runs in the context of a Page.
  • Page 包含名為 downloadProgressBarProgressBar,可提供下載作業的狀態。The Page contains a ProgressBar named downloadProgressBar to provide status for the download operation.
  • 程式碼檔案含有使用 Windows.Services.StoreWindows.Threading.TasksWindows.UI.Popups 命名空間的 using 陳述式。The code file has a using statement for the Windows.Services.Store, Windows.Threading.Tasks, and Windows.UI.Popups namespaces.
  • App 是單一使用者 app,僅會在啟動 app 的使用者內容中執行。The app is a single-user app that runs only in the context of the user that launched the app. 針對多使用者應用程式,使用 GetForUser 方法來取得 StoreContext 物件,而不是 GetDefault 方法。For a multi-user app, use the GetForUser method to get a StoreContext object instead of the GetDefault method.
private StoreContext context = null;

public async Task DownloadAndInstallAllUpdatesAsync()
{
    if (context == null)
    {
        context = StoreContext.GetDefault();
    }

    // Get the updates that are available.
    IReadOnlyList<StorePackageUpdate> updates =
        await context.GetAppAndOptionalStorePackageUpdatesAsync();

    if (updates.Count > 0)
    {
        // Alert the user that updates are available and ask for their consent
        // to start the updates.
        MessageDialog dialog = new MessageDialog(
            "Download and install updates now? This may cause the application to exit.", "Download and Install?");
        dialog.Commands.Add(new UICommand("Yes"));
        dialog.Commands.Add(new UICommand("No"));
        IUICommand command = await dialog.ShowAsync();

        if (command.Label.Equals("Yes", StringComparison.CurrentCultureIgnoreCase))
        {
            // Download and install the updates.
            IAsyncOperationWithProgress<StorePackageUpdateResult, StorePackageUpdateStatus> downloadOperation =
                context.RequestDownloadAndInstallStorePackageUpdatesAsync(updates);

            // The Progress async method is called one time for each step in the download
            // and installation process for each package in this request.
            downloadOperation.Progress = async (asyncInfo, progress) =>
            {
                await this.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal,
                () =>
                {
                    downloadProgressBar.Value = progress.PackageDownloadProgress;
                });
            };

            StorePackageUpdateResult result = await downloadOperation.AsTask();
        }
    }
}

注意

若只要下載 (而不安裝) 可用的套件更新,請使用 RequestDownloadStorePackageUpdatesAsync 方法。To only download (but not install) the available package updates, use the RequestDownloadStorePackageUpdatesAsync method.

顯示下載與安裝進度資訊Display download and install progress info

呼叫 RequestDownloadStorePackageUpdatesAsyncRequestDownloadAndInstallStorePackageUpdatesAsync 方法時,您可以在此要求中,為每個套件的下載 (或下載與安裝) 程序指派其中每個步驟各呼叫一次的 Progress 處理常式。When you call the RequestDownloadStorePackageUpdatesAsync or RequestDownloadAndInstallStorePackageUpdatesAsync method, you can assign a Progress handler that is called one time for each step in the download (or download and install) process for each package in this request. 處理常式會收到 StorePackageUpdateStatus 物件,這個物件提供關於引發進度通知之更新套件的資訊。The handler receives a StorePackageUpdateStatus object that provides info about the update package that raised the progress notification. 先前的範例使用 StorePackageUpdateStatus 物件的 PackageDownloadProgress 欄位來顯示下載與安裝程序的進度。The previous example uses the PackageDownloadProgress field of the StorePackageUpdateStatus object to display the progress of the download and install process.

請注意,當您在單一作業中呼叫 RequestDownloadAndInstallStorePackageUpdatesAsync 下載並安裝套件更新時,PackageDownloadProgress 欄位會在下載套件的過程中從 0.0 增加至 0.8,然後再於安裝期間從 0.8 增加至 1.0。Be aware that when you call RequestDownloadAndInstallStorePackageUpdatesAsync to download and install package updates in a single operation, the PackageDownloadProgress field increases from 0.0 to 0.8 during the download process for a package, and then it increases from 0.8 to 1.0 during the install. 因此,如果直接將自訂進度 UI 顯示的百分比對應至 PackageDownloadProgress 欄位的值,您的 UI 將會在完成套件下載且作業系統顯示安裝對話方塊時顯示 80%。Therefore, if you map the percentage shown in your custom progress UI directly to the value of the PackageDownloadProgress field, your UI will show 80% when the package is finished downloading and the OS displays the installation dialog. 如果您希望自訂進度 UI 在套件已下載且準備好要安裝時顯示 100%,您可以將程式碼修改為,在 PackageDownloadProgress 欄位到達 0.8 時指派 100% 給自訂進度 UI。If you want your custom progress UI to display 100% when the package is downloaded and ready to be installed, you can modify your code to assign 100% to your progress UI when the PackageDownloadProgress field reaches 0.8.

以無訊息方式下載及安裝套件更新Download and install package updates silently

從 Windows 10 版本 1803 起,您可以使用 TrySilentDownloadStorePackageUpdatesAsyncTrySilentDownloadAndInstallStorePackageUpdatesAsync 方法以無訊息方式下載及安裝套件更新 (不向使用者顯示 UI 通知)。Starting in Windows 10, version 1803, you can use the TrySilentDownloadStorePackageUpdatesAsync and TrySilentDownloadAndInstallStorePackageUpdatesAsync methods to download and install package updates silently, without displaying a notification UI to the user. 只有在使用者已在 Microsoft Store 中啟用 [自動更新應用程式] 設定,而且使用者不是在計量付費網路上,這項作業才會成功。This operation will succeed only if the user has enabled the Update apps automatically setting in the Store and the user is not on a metered network. 呼叫這些方法之前,您可以先查看 CanSilentlyDownloadStorePackageUpdates 屬性,判斷目前是否符合這些條件。Before calling these methods, you can first check the CanSilentlyDownloadStorePackageUpdates property to determine whether these conditions are currently met.

此程式碼範例示範如何使用 GetAppAndOptionalStorePackageUpdatesAsync 方法來探索所有可用的套件更新,然後呼叫 TrySilentDownloadStorePackageUpdatesAsyncTrySilentDownloadAndInstallStorePackageUpdatesAsync 方法以無訊息方式下載並安裝更新。This code example demonstrates how to use the GetAppAndOptionalStorePackageUpdatesAsync method to discover all available package updates and then call the TrySilentDownloadStorePackageUpdatesAsync and TrySilentDownloadAndInstallStorePackageUpdatesAsync methods to download and install the updates silently.

此程式碼範例假設:This code example assumes:

  • 程式碼檔案含有 Windows.Services.StoreSystem.Threading.Tasks 命名空間的 using 陳述式。The code file has a using statement for the Windows.Services.Store and System.Threading.Tasks namespaces.
  • App 是單一使用者 app,僅會在啟動 app 的使用者內容中執行。The app is a single-user app that runs only in the context of the user that launched the app. 針對多使用者應用程式,使用 GetForUser 方法來取得 StoreContext 物件,而不是 GetDefault 方法。For a multi-user app, use the GetForUser method to get a StoreContext object instead of the GetDefault method.

注意

此範例程式碼所呼叫的 IsNowAGoodTimeToRestartAppRetryDownloadAndInstallLaterRetryInstallLater 方法是預留位置方法,用來依據您自己的應用程式設計視需要實作。The IsNowAGoodTimeToRestartApp, RetryDownloadAndInstallLater, and RetryInstallLater methods called by the code in this example are placeholder methods that are intended to be implemented as needed according to your own app's design.

private StoreContext context = null;

public async Task DownloadAndInstallAllUpdatesInBackgroundAsync()
{
    if (context == null)
    {
        context = StoreContext.GetDefault();
    }

    // Get the updates that are available.
    IReadOnlyList<StorePackageUpdate> storePackageUpdates =
        await context.GetAppAndOptionalStorePackageUpdatesAsync();

    if (storePackageUpdates.Count > 0)
    {

        if (!context.CanSilentlyDownloadStorePackageUpdates)
        {
            return;
        }

        // Start the silent downloads and wait for the downloads to complete.
        StorePackageUpdateResult downloadResult =
            await context.TrySilentDownloadStorePackageUpdatesAsync(storePackageUpdates);

        switch (downloadResult.OverallState)
        {
            case StorePackageUpdateState.Completed:
                // The download has completed successfully. At this point, confirm whether your app
                // can restart now and then install the updates (for example, you might only install
                // packages silently if your app has been idle for a certain period of time). The
                // IsNowAGoodTimeToRestartApp method is not implemented in this example, you should
                // implement it as needed for your own app.
                if (IsNowAGoodTimeToRestartApp())
                {
                    await InstallUpdate(storePackageUpdates);
                }
                else
                {
                    // Retry/reschedule the installation later. The RetryInstallLater method is not  
                    // implemented in this example, you should implement it as needed for your own app.
                    RetryInstallLater();
                    return;
                }
                break;
            // If the user cancelled the download or you can't perform the download for some other
            // reason (for example, Wi-Fi might have been turned off and the device is now on
            // a metered network) try again later. The RetryDownloadAndInstallLater method is not  
            // implemented in this example, you should implement it as needed for your own app.
            case StorePackageUpdateState.Canceled:
            case StorePackageUpdateState.ErrorLowBattery:
            case StorePackageUpdateState.ErrorWiFiRecommended:
            case StorePackageUpdateState.ErrorWiFiRequired:
            case StorePackageUpdateState.OtherError:
                RetryDownloadAndInstallLater();
                return;
            default:
                break;
        }
    }
}

private async Task InstallUpdate(IReadOnlyList<StorePackageUpdate> storePackageUpdates)
{
    // Start the silent installation of the packages. Because the packages have already
    // been downloaded in the previous method, the following line of code just installs
    // the downloaded packages.
    StorePackageUpdateResult downloadResult =
        await context.TrySilentDownloadAndInstallStorePackageUpdatesAsync(storePackageUpdates);

    switch (downloadResult.OverallState)
    {
        // If the user cancelled the installation or you can't perform the installation  
        // for some other reason, try again later. The RetryInstallLater method is not  
        // implemented in this example, you should implement it as needed for your own app.
        case StorePackageUpdateState.Canceled:
        case StorePackageUpdateState.ErrorLowBattery:
        case StorePackageUpdateState.OtherError:
            RetryInstallLater();
            return;
        default:
            break;
    }
}

強制性套件更新Mandatory package updates

當您針對目標為 Windows 10 版本 1607 或更新版本的應用程式在合作夥伴中心建立套件提交時,可以將套件標示為強制性,並標示其成為強制性的日期和時間。When you create a package submission in Partner Center for an app that targets Windows 10, version 1607 or later, you can mark the package as mandatory and the date and time on which it becomes mandatory. 當設定此屬性,且應用程式發現有套件更新可供使用時,應用程式就可以判斷更新套件是否為強制,並變更其行為,直到安裝更新為止 (例如,應用程式可以停用功能)。When this property is set and your app discovers that the package update is available, your app can determine whether the update package is mandatory and alter its behavior until the update is installed (for example, your app can disable features).

注意

套件更新的強制狀態並非由 Microsoft 實施,作業系統不會提供 UI 來指示使用者必須安裝強制性應用程式更新。The mandatory status of a package update is not enforced by Microsoft, and the OS does not provide a UI to indicate to users that a mandatory app update must be installed. 開發人員必須刻意使用強制性設定,以便在程式碼中實施強制性應用程式更新。Developers are intended to use the mandatory setting to enforce mandatory app updates in their own code.

將套件提交標記為強制性:To mark a package submission as mandatory:

  1. 登入合作夥伴中心並瀏覽至您應用程式的總覽頁面。Sign in to Partner Center and navigate to the overview page for your app.
  2. 按一下提交的名稱,其中包含您想要變成強制性的套件更新。Click the name of the submission that contains the package update you want to make mandatory.
  3. 瀏覽到提交的 [套件] 頁面。Navigate to the Packages page for the submission. 在此頁面底部附近選取 [使此更新變成強制性] ,然後選擇套件更新變成強制性的日期和時間。Near the bottom of this page, select Make this update mandatory and then choose the day and time on which the package update becomes mandatory. 這個選項適用於提交中的所有 UWP 套件。This option applies to all UWP packages in the submission.

如需詳細資訊,請參閱上傳應用程式套件For more information, see Upload app packages.

注意

如果您建立套件正式發行前小眾測試版,就可以使用正式發行前小眾測試版 [套件] 頁面上的類似 UI,將套件標示為強制性。If you create a package flight, you can mark the packages as mandatory using a similar UI on the Packages page for the flight. 在此情況下,強制性套件更新只適用於正式發行前小眾測試版群組的客戶。In this case, the mandatory package update applies only to the customers who are part of the flight group.

強制性套件的程式碼範例Code example for mandatory packages

下列程式碼範例示範如何判斷任何更新套件是否為強制性。The following code example demonstrates how to determine whether any update packages are mandatory. 通常,如果無法成功下載或安裝強制性套件更新,則您應該針對使用者適當地將您的 app 體驗降級。Typically, you should downgrade your app experience gracefully for the user if a mandatory package update does not successfully download or install.

private StoreContext context = null;

// Downloads and installs package updates in separate steps.
public async Task DownloadAndInstallAllUpdatesAsync()
{
    if (context == null)
    {
        context = StoreContext.GetDefault();
    }  

    // Get the updates that are available.
    IReadOnlyList<StorePackageUpdate> updates =
        await context.GetAppAndOptionalStorePackageUpdatesAsync();

    if (updates.Count != 0)
    {
        // Download the packages.
        bool downloaded = await DownloadPackageUpdatesAsync(updates);

        if (downloaded)
        {
            // Install the packages.
            await InstallPackageUpdatesAsync(updates);
        }
    }
}

// Helper method for downloading package updates.
private async Task<bool> DownloadPackageUpdatesAsync(IEnumerable<StorePackageUpdate> updates)
{
    bool downloadedSuccessfully = false;

    IAsyncOperationWithProgress<StorePackageUpdateResult, StorePackageUpdateStatus> downloadOperation =
        this.context.RequestDownloadStorePackageUpdatesAsync(updates);

    // The Progress async method is called one time for each step in the download process for each
    // package in this request.
    downloadOperation.Progress = async (asyncInfo, progress) =>
    {
        await this.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal,
        () =>
        {
            downloadProgressBar.Value = progress.PackageDownloadProgress;
        });
    };

    StorePackageUpdateResult result = await downloadOperation.AsTask();

    switch (result.OverallState)
    {
        case StorePackageUpdateState.Completed:
            downloadedSuccessfully = true;
            break;
        default:
            // Get the failed updates.
            var failedUpdates = result.StorePackageUpdateStatuses.Where(
                status => status.PackageUpdateState != StorePackageUpdateState.Completed);

            // See if any failed updates were mandatory
            if (updates.Any(u => u.Mandatory && failedUpdates.Any(
                failed => failed.PackageFamilyName == u.Package.Id.FamilyName)))
            {
                // At least one of the updates is mandatory. Perform whatever actions you
                // want to take for your app: for example, notify the user and disable
                // features in your app.
                HandleMandatoryPackageError();
            }
            break;
    }

    return downloadedSuccessfully;
}

// Helper method for installing package updates.
private async Task InstallPackageUpdatesAsync(IEnumerable<StorePackageUpdate> updates)
{
    IAsyncOperationWithProgress<StorePackageUpdateResult, StorePackageUpdateStatus> installOperation =
        this.context.RequestDownloadAndInstallStorePackageUpdatesAsync(updates);

    // The package updates were already downloaded separately, so this method skips the download
    // operatation and only installs the updates; no download progress notifications are provided.
    StorePackageUpdateResult result = await installOperation.AsTask();

    switch (result.OverallState)
    {
        case StorePackageUpdateState.Completed:
            break;
        default:
            // Get the failed updates.
            var failedUpdates = result.StorePackageUpdateStatuses.Where(
                status => status.PackageUpdateState != StorePackageUpdateState.Completed);

            // See if any failed updates were mandatory
            if (updates.Any(u => u.Mandatory && failedUpdates.Any(failed => failed.PackageFamilyName == u.Package.Id.FamilyName)))
            {
                // At least one of the updates is mandatory, so tell the user.
                HandleMandatoryPackageError();
            }
            break;
    }
}

// Helper method for handling the scenario where a mandatory package update fails to
// download or install. Add code to this method to perform whatever actions you want
// to take, such as notifying the user and disabling features in your app.
private void HandleMandatoryPackageError()
{
}

解除安裝選用套件Uninstall optional packages

從 Windows 10 版本 1803 起,您可以使用 RequestUninstallStorePackageAsyncRequestUninstallStorePackageByStoreIdAsync 方法解除安裝目前應用程式的選用套件 (包括 DLC 套件)。Starting in Windows 10, version 1803, you can use the RequestUninstallStorePackageAsync or RequestUninstallStorePackageByStoreIdAsync methods to uninstall an optional package (including a DLC package) for the current app. 例如,如果您的應用程式能透過選用套件安裝內容,可能會想要提供 UI,讓使用者解除安裝選用套件以釋放磁碟空間。For example, if you have an app with content that is installed via optional packages, you might want to provide a UI that enables users to uninstall the optional packages to free up disk space.

下列程式碼範例示範如何呼叫 RequestUninstallStorePackageAsyncThe following code example demonstrates how to call RequestUninstallStorePackageAsync. 此範例假設:This example assumes:

  • 程式碼檔案含有 Windows.Services.StoreSystem.Threading.Tasks 命名空間的 using 陳述式。The code file has a using statement for the Windows.Services.Store and System.Threading.Tasks namespaces.
  • App 是單一使用者 app,僅會在啟動 app 的使用者內容中執行。The app is a single-user app that runs only in the context of the user that launched the app. 針對多使用者應用程式,使用 GetForUser 方法來取得 StoreContext 物件,而不是 GetDefault 方法。For a multi-user app, use the GetForUser method to get a StoreContext object instead of the GetDefault method.
public async Task UninstallPackage(Windows.ApplicationModel.Package package)
{
    if (context == null)
    {
        context = StoreContext.GetDefault();
    }

    var storeContext = StoreContext.GetDefault();
    IAsyncOperation<StoreUninstallStorePackageResult> uninstallOperation =
        storeContext.RequestUninstallStorePackageAsync(package);

    // At this point, you can update your app UI to show that the package
    // is installing.

    uninstallOperation.Completed += (asyncInfo, status) =>
    {
        StoreUninstallStorePackageResult result = uninstallOperation.GetResults();
        switch (result.Status)
        {
            case StoreUninstallStorePackageStatus.Succeeded:
                {
                    // Update your app UI to show the package as uninstalled.
                    break;
                }
            default:
                {
                    // Update your app UI to show that the package uninstall failed.
                    break;
                }
        }
    };
}

取得下載佇列資訊Get download queue info

從 Windows 10 版本 1803 起,您可以使用 GetAssociatedStoreQueueItemsAsyncGetStoreQueueItemsAsync 方法取得 Microsoft Store 目前下載和安裝佇列中套件的資訊。Starting in Windows 10, version 1803, you can use the GetAssociatedStoreQueueItemsAsync and GetStoreQueueItemsAsync methods to get info about the packages that are in the current download and installation queue from the Store. 如果您的應用程式或遊戲支援需要數小時或數天才能下載並安裝的大型選用套件 (包括 DLC),而您想要正常處理客戶在下載和安裝程序完成之前關閉應用程式或遊戲的案例,這些方法會非常有用。These methods are useful if your app or game supports large optional packages (including DLCs) that can take hours or days to download and install, and you want to gracefully handle the case where a customer closes your app or game before the download and installation process is complete. 當客戶再次啟動您的應用程式或遊戲,您的程式碼可以使用這些方法取得仍然在下載和安裝佇列中的套件狀態資訊,讓您可以向客戶顯示每個套件的狀態。When the customer starts your app or game again, your code can use these methods to get info about the state of the packages that are still in the download and installation queue so you can display the status of each package to the customer.

下列程式碼範例示範如何呼叫 GetAssociatedStoreQueueItemsAsync,針對目前的應用程式取得進行中套件更新的清單中,並擷取每個套件的狀態資訊。The following code example demonstrates how to call GetAssociatedStoreQueueItemsAsync to get the list of in-progress package updates for the current app and retrieve status info for each package. 此範例假設:This example assumes:

  • 程式碼檔案含有 Windows.Services.StoreSystem.Threading.Tasks 命名空間的 using 陳述式。The code file has a using statement for the Windows.Services.Store and System.Threading.Tasks namespaces.
  • App 是單一使用者 app,僅會在啟動 app 的使用者內容中執行。The app is a single-user app that runs only in the context of the user that launched the app. 針對多使用者應用程式,使用 GetForUser 方法來取得 StoreContext 物件,而不是 GetDefault 方法。For a multi-user app, use the GetForUser method to get a StoreContext object instead of the GetDefault method.

注意

此範例程式碼所呼叫的 MarkUpdateInProgressInUIRemoveItemFromUIMarkInstallCompleteInUIMarkInstallErrorInUIMarkInstallPausedInUI 方法是預留位置方法,用來依據您自己的應用程式設計視需要實作。The MarkUpdateInProgressInUI, RemoveItemFromUI, MarkInstallCompleteInUI, MarkInstallErrorInUI, and MarkInstallPausedInUI methods called by the code in this example are placeholder methods that are intended to be implemented as needed according to your own app's design.

private StoreContext context = null;

private async Task GetQueuedInstallItemsAndBuildInitialStoreUI()
{
    if (context == null)
    {
        context = StoreContext.GetDefault();
    }

    // Get the Store packages in the install queue.
    IReadOnlyList<StoreQueueItem> storeUpdateItems = await context.GetAssociatedStoreQueueItemsAsync();

    foreach (StoreQueueItem storeItem in storeUpdateItems)
    {
        // In this example we only care about package updates.
        if (storeItem.InstallKind != StoreQueueItemKind.Update)
            continue;

        StoreQueueItemStatus currentStatus = storeItem.GetCurrentStatus();
        StoreQueueItemState installState = currentStatus.PackageInstallState;
        StoreQueueItemExtendedState extendedInstallState =
            currentStatus.PackageInstallExtendedState;

        // Handle the StatusChanged event to display current status to the customer.
        storeItem.StatusChanged += StoreItem_StatusChanged;

        switch (installState)
        {
            // Download and install are still in progress, so update the status for this  
            // item and provide the extended state info. The following methods are not
            // implemented in this example; you should implement them as needed for your
            // app's UI.
            case StoreQueueItemState.Active:
                MarkUpdateInProgressInUI(storeItem, extendedInstallState);
                break;
            case StoreQueueItemState.Canceled:
                RemoveItemFromUI(storeItem);
                break;
            case StoreQueueItemState.Completed:
                MarkInstallCompleteInUI(storeItem);
                break;
            case StoreQueueItemState.Error:
                MarkInstallErrorInUI(storeItem);
                break;
            case StoreQueueItemState.Paused:
                MarkInstallPausedInUI(storeItem, installState, extendedInstallState);
                break;
        }
    }
}

private void StoreItem_StatusChanged(StoreQueueItem sender, object args)
{
    StoreQueueItemStatus currentStatus = sender.GetCurrentStatus();
    StoreQueueItemState installState = currentStatus.PackageInstallState;
    StoreQueueItemExtendedState extendedInstallState = currentStatus.PackageInstallExtendedState;

    switch (installState)
    {
        // Download and install are still in progress, so update the status for this  
        // item and provide the extended state info. The following methods are not
        // implemented in this example; you should implement them as needed for your
        // app's UI.
        case StoreQueueItemState.Active:
            MarkUpdateInProgressInUI(sender, extendedInstallState);
            break;
        case StoreQueueItemState.Canceled:
            RemoveItemFromUI(sender);
            break;
        case StoreQueueItemState.Completed:
            MarkInstallCompleteInUI(sender);
            break;
        case StoreQueueItemState.Error:
            MarkInstallErrorInUI(sender);
            break;
        case StoreQueueItemState.Paused:
            MarkInstallPausedInUI(sender, installState, extendedInstallState);
            break;
    }
}