从 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. 要获取将使用可选包(包括 DLC 加载项)的应用提交到 Microsoft Store 的权限,请参阅 Windows 开发人员支持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.
  • 该应用是单用户应用,仅在启动该应用的用户上下文中运行。The app is a single-user app that runs only in the context of the user that launched the app. 对于多用户应用,使用 GetForUser 方法(而不是 GetDefault 方法)获取 StoreContext 对象。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:

  • 该代码文件需要使用 using 语句导入 Windows.Services.StoreSystem.Threading.Tasks 命名空间。The code file has a using statement for the Windows.Services.Store and System.Threading.Tasks namespaces.
  • 该应用是单用户应用,仅在启动该应用的用户上下文中运行。The app is a single-user app that runs only in the context of the user that launched the app. 对于多用户应用,使用 GetForUser 方法(而不是 GetDefault 方法)获取 StoreContext 对象。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. 通常,如果无法成功下载或安装必需程序包更新,应顺利降级用户的应用体验。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:

  • 该代码文件需要使用 using 语句导入 Windows.Services.StoreSystem.Threading.Tasks 命名空间。The code file has a using statement for the Windows.Services.Store and System.Threading.Tasks namespaces.
  • 该应用是单用户应用,仅在启动该应用的用户上下文中运行。The app is a single-user app that runs only in the context of the user that launched the app. 对于多用户应用,使用 GetForUser 方法(而不是 GetDefault 方法)获取 StoreContext 对象。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:

  • 该代码文件需要使用 using 语句导入 Windows.Services.StoreSystem.Threading.Tasks 命名空间。The code file has a using statement for the Windows.Services.Store and System.Threading.Tasks namespaces.
  • 该应用是单用户应用,仅在启动该应用的用户上下文中运行。The app is a single-user app that runs only in the context of the user that launched the app. 对于多用户应用,使用 GetForUser 方法(而不是 GetDefault 方法)获取 StoreContext 对象。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;
    }
}