Partager via


Télécharger et installer des mises à jour de package à partir du Windows Store

À compter de Windows 10, version 1607, vous pouvez utiliser des méthodes de la classe StoreContext dans l’espace de noms Windows.Services.Store pour rechercher par programmation les mises à jour de package pour l’application actuelle à partir du Microsoft Store, puis télécharger et installer les packages mis à jour. Vous pouvez également rechercher les packages que vous avez marqués comme obligatoires dans l’Espace partenaires et désactiver les fonctionnalités de votre application jusqu’à ce que la mise à jour obligatoire soit installée.

Des méthodes supplémentaires StoreContext introduites dans Windows 10, version 1803 vous permettent de télécharger et d’installer les mises à jour de package en mode silencieux (sans afficher une interface utilisateur de notification à l’utilisateur), désinstallez un package facultatif , et obtenez des informations sur les packages dans la file d’attente de téléchargement et d’installation de votre application.

Ces fonctionnalités vous aident à maintenir automatiquement votre base d’utilisateurs à jour avec la dernière version de votre application, des packages facultatifs et des services associés dans le Windows Store.

Télécharger et installer les mises à jour du package avec l’autorisation de l’utilisateur

Cet exemple de code montre comment utiliser la méthode GetAppAndOptionalStorePackageUpdatesAsync pour découvrir toutes les mises à jour de package disponibles à partir du Store, puis appeler la méthode RequestDownloadAndInstallStorePackageUpdatesAsync pour télécharger et installer les mises à jour. Lorsque vous utilisez cette méthode pour télécharger et installer les mises à jour, le système d’exploitation affiche une boîte de dialogue qui demande l’autorisation de l’utilisateur avant de télécharger les mises à jour.

Remarque

Ces méthodes prennent en charge les packages obligatoires et facultatifs pour votre application. Les packages facultatifs sont utiles pour les modules complémentaires de contenu téléchargeable (DLC), en divisant votre grande application pour les contraintes de taille ou pour l’expédition de contenu supplémentaire distinct de votre application principale. Pour obtenir l’autorisation d’envoyer une application qui utilise des packages facultatifs (y compris des modules complémentaires DLC) au Windows Store, consultez prise en charge des développeurs Windows.

Cet exemple de code suppose :

  • Le code s’exécute dans le contexte d’une Page.
  • La page contient un ProgressBar nommé pour fournir l’état de l’opération de téléchargement.
  • Le fichier de code a un à l’aide d’une instruction pour l'Windows.Services.Store, Windows.Threading.Taskset espaces de noms Windows.UI.Popups.
  • L’application est une application mono-utilisateur qui s’exécute uniquement dans le contexte de l’utilisateur qui a lancé l’application. Pour uned’application multi-utilisateur , utilisez la méthode GetForUser pour obtenir un objet StoreContext au lieu de la méthode GetDefault .
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();
        }
    }
}

Remarque

Pour télécharger uniquement (mais pas installer) les mises à jour de package disponibles, utilisez la méthode RequestDownloadStorePackageUpdatesAsync.

Afficher les informations de progression du téléchargement et de l’installation

Lorsque vous appelez la méthode RequestDownloadStorePackageUpdatesAsync ou RequestDownloadAndInstallStorePackageUpdatesAsync, vous pouvez affecter un gestionnaire de progression qui est appelé une fois pour chaque étape du processus de téléchargement (ou de téléchargement et d’installation) de chaque package de cette demande. Le gestionnaire reçoit un objet StorePackageUpdateStatus qui fournit des informations sur le package de mise à jour qui a déclenché la notification de progression. L’exemple précédent utilise le champ PackageDownloadProgress de l’objet StorePackageUpdateStatus pour afficher la progression du processus de téléchargement et d’installation.

N’oubliez pas que lorsque vous appelez RequestDownloadAndInstallStorePackageUpdatesAsync pour télécharger et installer les mises à jour de package dans une seule opération, le champ PackageDownloadProgress passe de 0,0 à 0,8 pendant le processus de téléchargement d’un package, puis passe de 0,8 à 1.0 pendant l’installation. Par conséquent, si vous mappez le pourcentage affiché dans votre interface utilisateur de progression personnalisée directement à la valeur du champ PackageDownloadProgress, votre interface utilisateur affiche 80% une fois le téléchargement du package terminé et le système d’exploitation affiche la boîte de dialogue d’installation. Si vous souhaitez que votre interface utilisateur de progression personnalisée affiche 100% lorsque le package est téléchargé et prêt à être installé, vous pouvez modifier votre code pour affecter 100% à votre interface utilisateur de progression lorsque le champ packageDownloadProgress atteint 0,8.

Télécharger et installer les mises à jour de package en mode silencieux

À compter de Windows 10, version 1803, vous pouvez utiliser les méthodes TrySilentDownloadStorePackageUpdatesAsync et TrySilentDownloadAndInstallStorePackageUpdatesAsync pour télécharger et installer les mises à jour de package en mode silencieux, sans afficher une interface utilisateur de notification à l’utilisateur. Cette opération ne réussira que si l'utilisateur a activé le paramètre de mise à jour automatique des applications dans la boutique Microsoft et qu'il n'est pas sur un réseau à débit limité. Avant d’appeler ces méthodes, vous pouvez d’abord vérifier la propriété CanSilentlyDownloadStorePackageUpdates pour déterminer si ces conditions sont actuellement remplies.

Cet exemple de code montre comment utiliser la méthode GetAppAndOptionalStorePackageUpdatesAsync pour découvrir toutes les mises à jour de paquets disponibles, puis exécuter les méthodes TrySilentDownloadStorePackageUpdatesAsync et TrySilentDownloadAndInstallStorePackageUpdatesAsync pour télécharger et installer les mises à jour silencieusement.

Cet exemple de code suppose :

  • Le fichier de code contient une instruction using pour les espaces de noms Windows.Services.Store et System.Threading.Tasks.
  • L’application est une application mono-utilisateur qui s’exécute uniquement dans le contexte de l’utilisateur qui a lancé l’application. Pour uned’application multi-utilisateur , utilisez la méthode GetForUser pour obtenir un objet StoreContext au lieu de la méthode GetDefault .

Remarque

Les méthodes IsNowAGoodTimeToRestartApp, RetryDownloadAndInstallLateret RetryInstallLater, appelées par le code dans cet exemple, sont des méthodes d'espace réservé destinées à être implémentées selon les besoins en fonction de la conception de votre propre application.

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

Mises à jour obligatoires du package

Lorsque vous créez une soumission de package dans l’Espace partenaires pour une application qui cible Windows 10, version 1607 ou ultérieure, vous pouvez marquer le package comme obligatoire et la date et l’heure sur lesquelles il devient obligatoire. Lorsque cette propriété est définie et que votre application découvre que la mise à jour du package est disponible, votre application peut déterminer si le package de mise à jour est obligatoire et modifier son comportement jusqu’à ce que la mise à jour soit installée (par exemple, votre application peut désactiver les fonctionnalités).

Remarque

L’état obligatoire d’une mise à jour de package n’est pas appliqué par Microsoft et le système d’exploitation ne fournit pas d’interface utilisateur pour indiquer aux utilisateurs qu’une mise à jour d’application obligatoire doit être installée. Les développeurs sont destinés à utiliser le paramètre obligatoire pour appliquer les mises à jour d’application obligatoires dans leur propre code.

Pour marquer une soumission de package comme obligatoire :

  1. Connectez-vous à Espace partenaires et accédez à la page vue d’ensemble de votre application.
  2. Cliquez sur le nom de la soumission qui contient la mise à jour du package que vous souhaitez rendre obligatoire.
  3. Accédez à la page Packages pour effectuer la soumission. En bas de cette page, sélectionnez Rendre cette mise à jour obligatoire, puis choisissez le jour et l’heure sur lesquels la mise à jour du package devient obligatoire. Cette option s’applique à tous les packages UWP dans la soumission.

Pour plus d’informations, consultez Charger des packages d’application.

Remarque

Si vous créez un vol de paquets , vous pouvez marquer les paquets comme obligatoires à l'aide d'une interface utilisateur similaire sur la page des paquets pour le vol. Dans ce cas, la mise à jour obligatoire de l'ensemble s’applique uniquement aux clients qui font partie du groupe d’évaluation.

Exemple de code pour les packages obligatoires

L’exemple de code suivant montre comment déterminer si les packages de mise à jour sont obligatoires. En règle générale, vous devez rétrograder votre expérience d’application correctement pour l’utilisateur si une mise à jour de package obligatoire ne télécharge pas ou n’installe pas correctement.

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

Désinstaller des packages facultatifs

À compter de Windows 10, version 1803, vous pouvez utiliser les méthodes RequestUninstallStorePackageA sync ou RequestUninstallStorePackageByStoreIdAsync désinstaller un package facultatif (y compris un package DLC) pour l’application actuelle. Par exemple, si vous disposez d’une application avec du contenu installé via des packages facultatifs, vous pouvez fournir une interface utilisateur qui permet aux utilisateurs de désinstaller les packages facultatifs pour libérer de l’espace disque.

L’exemple de code suivant montre comment appeler RequestUninstallStorePackageAsync. Cet exemple suppose :

  • Le fichier de code contient une instruction using pour les espaces de noms Windows.Services.Store et System.Threading.Tasks.
  • L’application est une application mono-utilisateur qui s’exécute uniquement dans le contexte de l’utilisateur qui a lancé l’application. Pour uned’application multi-utilisateur , utilisez la méthode GetForUser pour obtenir un objet StoreContext au lieu de la méthode GetDefault .
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;
                }
        }
    };
}

Obtenez les informations de la file d'attente de téléchargement

À compter de Windows 10, version 1803, vous pouvez utiliser les méthodes GetAssociatedStoreQueueItemsAsync et GetStoreQueueItemsAsync pour obtenir des informations sur les packages qui se trouvent dans la file d’attente de téléchargement et d’installation actuelle à partir du Windows Store. Ces méthodes sont utiles si votre application ou votre jeu prend en charge des packages facultatifs volumineux (y compris des DLL) qui peuvent prendre des heures ou des jours pour télécharger et installer, et que vous souhaitez gérer correctement le cas où un client ferme votre application ou jeu avant la fin du processus de téléchargement et d’installation. Lorsque le client démarre à nouveau votre application ou votre jeu, votre code peut utiliser ces méthodes pour obtenir des informations sur l’état des packages qui se trouvent toujours dans la file d’attente de téléchargement et d’installation afin de pouvoir afficher l’état de chaque package au client.

L’exemple de code suivant montre comment appeler GetAssociatedStoreQueueItemsAsync pour obtenir la liste des mises à jour de package en cours pour l’application actuelle et récupérer les informations d’état pour chaque package. Cet exemple suppose :

  • Le fichier de code contient une instruction using pour les espaces de noms Windows.Services.Store et System.Threading.Tasks.
  • L’application est une application mono-utilisateur qui s’exécute uniquement dans le contexte de l’utilisateur qui a lancé l’application. Pour uned’application multi-utilisateur , utilisez la méthode GetForUser pour obtenir un objet StoreContext au lieu de la méthode GetDefault .

Remarque

Les méthodes MarkUpdateInProgressInUI, RemoveItemFromUI, MarkInstallCompleteInUI, MarkInstallErrorInUIet MarkInstallPausedInUI, appelées par le code dans cet exemple, sont des méthodes d’espace réservé destinées à être implémentées en fonction de la conception de votre propre application.

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