Herunterladen und Installieren von Paketupdates aus dem Store

Ab Windows 10, Version 1607, können Sie Methoden der StoreContext-Klasse im namespace Windows.Services.Store verwenden, um programmgesteuert nach Paketupdates für die aktuelle App aus dem Microsoft Store zu suchen und die aktualisierten Pakete herunterzuladen und zu installieren. Sie können auch Pakete abfragen, die Sie im Partner Center als obligatorisch gekennzeichnet haben, und Funktionen in Ihrer App deaktivieren, bis das obligatorische Update installiert ist.

Zusätzliche in Windows 10, Version 1803 eingeführte StoreContext-Methoden ermöglichen es Ihnen, Paketupdates automatisch herunterzuladen und zu installieren (ohne dem Benutzer eine Benachrichtigungsbenutzeroberfläche anzuzeigen), ein optionales Paket zu deinstallieren und Informationen zu Paketen in der Download- und Installationswarteschlange für Ihre App abzurufen.

Diese Features helfen Ihnen, Ihre Benutzerbasis automatisch auf dem neuesten Stand zu halten, mit der neuesten Version Ihrer App, optionalen Paketen und zugehörigen Diensten im Store.

Hinweis

Die Windows.Services.Store APIs erfordern paketidentität und funktionieren für alle MSIX-verpackten Apps, die über die Microsoft Store verteilt werden, einschließlich WinUI 3-Apps, die mit dem Windows App SDK erstellt wurden. Die Codebeispiele in diesem Artikel wurden ursprünglich für UWP geschrieben. Wenn Sie sie für eine WinUI 3-App anpassen, ersetzen Sie this.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, ...) durch DispatcherQueue.GetForCurrentThread().TryEnqueue(...), und ersetzen Sie MessageDialog (wofür in WinUI 3 HWND-Interop erforderlich ist) durch ContentDialog, oder verwenden Sie WinRT.Interop.InitializeWithWindow.Initialize, um das Dialogfeld Ihrem Fensterhandle zuzuordnen.

Herunterladen und Installieren von Paketupdates mit der Berechtigung des Benutzers

In diesem Codebeispiel wird veranschaulicht, wie Sie mit der GetAppAndOptionalStorePackageUpdatesAsync-Methode alle verfügbaren Paketupdates aus dem Store ermitteln und dann die RequestDownloadAndInstallStorePackageUpdatesAsync-Methode aufrufen, um die Updates herunterzuladen und zu installieren. Wenn Sie diese Methode zum Herunterladen und Installieren von Updates verwenden, zeigt das Betriebssystem ein Dialogfeld an, das die Berechtigung des Benutzers vor dem Herunterladen der Updates anfragt.

Hinweis

Diese Methoden unterstützen erforderliche und optionale Pakete für Ihre App. Optionale Pakete sind nützlich für DLC-Add-Ons (Downloadable Content), dividieren Ihre große App für Größenbeschränkungen oder für den Versand zusätzlicher Inhalte, die von Ihrer Kern-App getrennt sind. Informationen zum Anfordern der Berechtigung zum Übermitteln einer App, die optionale Pakete (einschließlich DLC-Add-Ons) an den Store verwendet, finden Sie unter Windows Entwicklersupport.

In diesem Codebeispiel wird davon ausgegangen:

  • Der Code wird im Kontext einer UWP-XAML-Seite (Windows.UI.Xaml.Controls.Page) ausgeführt. Diese Beispiele sind für UWP geschrieben; weitere Informationen finden Sie oben in diesem Artikel zu WinUI 3-Anpassungen.
  • Die Seite enthält eine ProgressBar mit dem Namen downloadProgressBar, um den Status des Downloadvorgangs anzuzeigen.
  • Die Codedatei enthält eine using-Anweisung für die Namespaces Windows.Services.Store, System.Threading.Tasks und Windows.UI.Popups.
  • Die App ist eine Einzelbenutzer-App, die nur im Kontext des Benutzers ausgeführt wird, der die App gestartet hat. Verwenden Sie für eine Mehrbenutzer-App die GetForUser-Methode , um ein StoreContext-Objekt anstelle der GetDefault-Methode abzurufen.
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();
        }
    }
}

Hinweis

Um nur die verfügbaren Paketupdates herunterzuladen (aber nicht zu installieren), verwenden Sie die RequestDownloadStorePackageUpdatesAsync-Methode .

Anzeigen von Download- und Installationsstatusinformationen

Wenn Sie die RequestDownloadStorePackageUpdatesAsync - oder RequestDownloadAndInstallStorePackageUpdatesAsync-Methode aufrufen, können Sie einen Progress-Handler zuweisen, der für jeden Schritt im Downloadprozess (oder Download und Installation) für jedes Paket in dieser Anforderung einmal aufgerufen wird. Der Handler empfängt ein StorePackageUpdateStatus -Objekt, das Informationen zum Updatepaket bereitstellt, das die Statusbenachrichtigung ausgelöst hat. Im vorherigen Beispiel wird das PackageDownloadProgress-Feld des StorePackageUpdateStatus-Objekts verwendet, um den Fortschritt des Download- und Installationsprozesses anzuzeigen.

Beachten Sie, dass beim Aufrufen von RequestDownloadAndInstallStorePackageUpdatesAsync , um Paketupdates in einem einzigen Vorgang herunterzuladen und zu installieren, das Feld "PackageDownloadProgress " während des Downloadvorgangs für ein Paket von 0,0 auf 0,8 erhöht und dann während der Installation von 0,8 auf 1.0 ansteigt. Wenn Sie daher den in Ihrer benutzerdefinierten Fortschrittsanzeige angezeigten Prozentsatz direkt dem Wert des Felds PackageDownloadProgress zuordnen, zeigt Ihre Benutzeroberfläche 80 % an, wenn der Download des Pakets abgeschlossen ist und das Betriebssystem den Installationsdialog anzeigt. Wenn Sie möchten, dass Ihre benutzerdefinierte Fortschrittsanzeige 100 % anzeigt, wenn das Paket heruntergeladen und zur Installation bereit ist, können Sie Ihren Code so anpassen, dass Ihre Fortschrittsanzeige 100 % anzeigt, wenn das Feld PackageDownloadProgress den Wert 0,8 erreicht.

Herunterladen und Installieren von Paketupdates im Hintergrund

Ab Windows 10, Version 1803, können Sie die Methoden TrySilentDownloadStorePackageUpdatesAsync und TrySilentDownloadAndInstallStorePackageUpdatesAsync verwenden, um Paketupdates im Hintergrund herunterzuladen und zu installieren, ohne dem Benutzer eine Benachrichtigungsbenutzeroberfläche anzuzeigen. Dieser Vorgang wird nur erfolgreich ausgeführt, wenn der Benutzer die Update-Apps automatisch im Store aktiviert hat und sich der Benutzer nicht in einem getakteten Netzwerk befindet. Bevor Sie diese Methoden aufrufen, können Sie zuerst die CanSilentlyDownloadStorePackageUpdates-Eigenschaft überprüfen, um zu ermitteln, ob diese Bedingungen derzeit erfüllt sind.

In diesem Codebeispiel wird veranschaulicht, wie Sie mit der GetAppAndOptionalStorePackageUpdatesAsync-Methode alle verfügbaren Paketupdates ermitteln und dann trySilentDownloadStorePackageUpdatesAsync und TrySilentDownloadAndInstallStorePackageUpdatesAsync-Methoden aufrufen, um die Updates automatisch herunterzuladen und zu installieren.

In diesem Codebeispiel wird davon ausgegangen:

  • Die Codedatei verfügt über eine using-Anweisung für die Namespaces Windows.Services.Store und System.Threading.Tasks.
  • Die App ist eine Einzelbenutzer-App, die nur im Kontext des Benutzers ausgeführt wird, der die App gestartet hat. Verwenden Sie für eine Mehrbenutzer-App die GetForUser-Methode , um ein StoreContext-Objekt anstelle der GetDefault-Methode abzurufen.

Hinweis

Die Methoden IsNowAGoodTimeToRestartApp, RetryDownloadAndInstallLater und RetryInstallLater , die vom Code in diesem Beispiel aufgerufen werden, sind Platzhaltermethoden, die gemäß dem Design Ihrer eigenen App nach Bedarf implementiert werden sollen.

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;
    }
}

Obligatorische Paketupdates

Wenn Sie eine Paketübermittlung in Partner Center für eine App erstellen, die auf Windows 10, Version 1607 oder höher ausgerichtet ist, können Sie das Paket als obligatorisch und das Datum und die Uhrzeit markieren, zu dem es obligatorisch wird. Wenn diese Eigenschaft festgelegt ist und Ihre App feststellt, dass das Paketupdate verfügbar ist, kann Ihre App bestimmen, ob das Updatepaket obligatorisch ist und das Verhalten ändern, bis das Update installiert ist (z. B. kann Ihre App Features deaktivieren).

Hinweis

Der obligatorische Status eines Paketupdates wird nicht durch Microsoft erzwungen, und das Betriebssystem stellt keine Benutzeroberfläche bereit, um Benutzern anzugeben, dass ein obligatorisches App-Update installiert werden muss. Entwickler sollen die obligatorische Einstellung verwenden, um obligatorische App-Updates in ihrem eigenen Code zu erzwingen.

So markieren Sie eine Paketübermittlung als obligatorisch:

  1. Melden Sie sich beim Partner Center an, und navigieren Sie zur Übersichtsseite für Ihre App.
  2. Klicken Sie auf den Namen der Übermittlung, die das Paketupdate enthält, das Sie obligatorisch machen möchten.
  3. Navigieren Sie zur Seite "Pakete" für die Übermittlung. Wählen Sie unten auf dieser Seite die Option "Obligatorisches Update festlegen " aus, und wählen Sie dann den Tag und die Uhrzeit aus, zu dem das Paketupdate obligatorisch wird. Diese Option gilt für alle Pakete in der Übermittlung.

Weitere Informationen finden Sie unter Hochladen von App-Paketen.

Hinweis

Wenn Sie einen Paket-Flight erstellen, können Sie die Pakete auf der Seite Pakete für den Flight mithilfe einer ähnlichen Benutzeroberfläche als erforderlich markieren. In diesem Fall gilt die obligatorische Paketaktualisierung nur für Kunden, die Teil der Fluggruppe sind.

Codebeispiel für obligatorische Pakete

Im folgenden Codebeispiel wird veranschaulicht, wie ermittelt wird, ob Updatepakete obligatorisch sind. In der Regel sollten Sie die App-Erfahrung ordnungsgemäß für den Benutzer herabstufen, wenn ein obligatorisches Paketupdate nicht erfolgreich heruntergeladen oder installiert wird.

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
    // operation 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()
{
}

Optionale Pakete deinstallieren

Ab Windows 10 Version 1803 können Sie die Methoden RequestUninstallStorePackageAsync oder RequestUninstallStorePackageByStoreIdAsync verwenden, um ein optionales Paket (einschließlich eines DLC-Pakets) für die aktuelle App zu deinstallieren. Wenn Sie beispielsweise über eine App mit Inhalten verfügen, die über optionale Pakete installiert sind, sollten Sie eine Benutzeroberfläche bereitstellen, mit der Benutzer die optionalen Pakete deinstallieren können, um Speicherplatz freizugeben.

Im folgenden Codebeispiel wird veranschaulicht, wie RequestUninstallStorePackageAsync aufgerufen wird. In diesem Beispiel wird von Folgendem ausgegangen:

  • Die Codedatei verfügt über eine using-Anweisung für die Namespaces Windows.Services.Store und System.Threading.Tasks.
  • Die App ist eine Einzelbenutzer-App, die nur im Kontext des Benutzers ausgeführt wird, der die App gestartet hat. Verwenden Sie für eine Mehrbenutzer-App die GetForUser-Methode , um ein StoreContext-Objekt anstelle der GetDefault-Methode abzurufen.
public async Task UninstallPackage(Windows.ApplicationModel.Package package)
{
    if (context == null)
    {
        context = StoreContext.GetDefault();
    }

    IAsyncOperation<StoreUninstallStorePackageResult> uninstallOperation =
        context.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;
                }
        }
    };
}

Informationen zur Download-Warteschlange abrufen

Ab Windows 10, Version 1803, können Sie die Methoden GetAssociatedStoreQueueItemsAsync und GetStoreQueueItemsAsync verwenden, um Informationen zu den Paketen abzurufen, die sich in der aktuellen Download- und Installationswarteschlange im Store befinden. Diese Methoden sind nützlich, wenn Ihre App oder Ihr Spiel große optionale Pakete (einschließlich DLCs) unterstützt, die Stunden oder Tage dauern können, um sie herunterzuladen und zu installieren, und Sie möchten den Fall ordnungsgemäß behandeln, in dem ein Kunde Ihre App oder Ihr Spiel schließt, bevor der Download- und Installationsprozess abgeschlossen ist. Wenn der Kunde Ihre App oder Ihr Spiel erneut startet, kann Ihr Code diese Methoden verwenden, um Informationen zum Status der Pakete abzurufen, die sich noch in der Download- und Installationswarteschlange befinden, damit Sie den Status jedes Pakets für den Kunden anzeigen können.

Im folgenden Codebeispiel wird veranschaulicht, wie GetAssociatedStoreQueueItemsAsync aufgerufen wird, um die Liste der laufenden Paketupdates für die aktuelle App abzurufen und Statusinformationen für jedes Paket abzurufen. In diesem Beispiel wird von Folgendem ausgegangen:

  • Die Codedatei verfügt über eine using-Anweisung für die Namespaces Windows.Services.Store und System.Threading.Tasks.
  • Die App ist eine Einzelbenutzer-App, die nur im Kontext des Benutzers ausgeführt wird, der die App gestartet hat. Verwenden Sie für eine Mehrbenutzer-App die GetForUser-Methode , um ein StoreContext-Objekt anstelle der GetDefault-Methode abzurufen.

Hinweis

Die vom Code in diesem Beispiel aufgerufenen Methoden MarkUpdateInProgressInUI, RemoveItemFromUI, MarkInstallCompleteInUI, MarkInstallErrorInUI und MarkInstallPausedInUI sind Platzhaltermethoden, die gemäß dem Design Ihrer eigenen App nach Bedarf implementiert werden sollen.

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;
    }
}