Partager via


Mettre à jour les packages d’application non publiés dans le Store à partir de votre code

Lors de l’expédition de votre application en tant que MSIX, vous pouvez lancer par programme une mise à jour de votre application. Si vous déployez votre application en dehors du Windows Store, il vous suffit de vérifier votre serveur pour obtenir une nouvelle version de votre application et d’installer la nouvelle version. La façon dont vous appliquez la mise à jour dépend du déploiement de votre package d’application à l’aide d’un fichier Programme d’installation d’application ou non. Pour appliquer des mises à jour à partir de votre code, votre package d’application doit déclarer la packageManagement fonctionnalité. Notez que cela est nécessaire pour le scénario inter-éditeur, mais la gestion de votre propre application doit fonctionner sans avoir à déclarer la fonctionnalité.

Cet article fournit des exemples qui montrent comment déclarer la packageManagement fonctionnalité dans votre manifeste de package et comment appliquer une mise à jour à partir de votre code. La première section explique comment procéder si vous utilisez le fichier Programme d’installation d’application et la deuxième section explique comment procéder lorsque vous n’utilisez pas le fichier Programme d’installation d’application. La dernière section explique comment vérifier que votre application redémarre une fois qu’une mise à jour a été appliquée.

Ajouter la fonctionnalité PackageManagement à votre manifeste de package

Pour utiliser les PackageManager API, votre application doit déclarer la packageManagementfonctionnalité restreinte dans votre manifeste de package.

<Package>
...

  <Capabilities>
    <rescap:Capability Name="packageManagement" />
  </Capabilities>
  
...
</Package>

Mise à jour des packages déployés à l’aide d’un fichier Programme d’installation d’application

Si vous déployez votre application à l’aide du fichier App Installer, toutes les mises à jour pilotées par le code que vous effectuez doivent utiliser les API de fichier App Installer. Cela garantit que les mises à jour de votre fichier programme d’installation d’application standard continueront de fonctionner. Pour intiguer une mise à jour basée sur le programme d’installation d’application à partir de votre code, vous pouvez utiliser PackageManager.AddPackageByAppInstallerFileAsync ou PackageManager.RequestAddPackageByAppInstallerFileAsync. Vous pouvez vérifier si une mise à jour est disponible à l’aide de l’API Package.CheckUpdateAvailabilityAsync . Voici un exemple de code :

using Windows.Management.Deployment;

public async void CheckForAppInstallerUpdatesAndLaunchAsync(string targetPackageFullName, PackageVolume packageVolume)
{
    // Get the current app's package for the current user.
    PackageManager pm = new PackageManager();
    Package package = pm.FindPackageForUser(string.Empty, targetPackageFullName);

    PackageUpdateAvailabilityResult result = await package.CheckUpdateAvailabilityAsync();
    switch (result.Availability)
    {
        case PackageUpdateAvailability.Available:
        case PackageUpdateAvailability.Required:
            //Queue up the update and close the current instance
            await pm.AddPackageByAppInstallerFileAsync(
            new Uri("https://trial3.azurewebsites.net/HRApp/HRApp.appinstaller"),
            AddPackageByAppInstallerOptions.ForceApplicationShutdown,
            packageVolume);
            break;
        case PackageUpdateAvailability.NoUpdates:
            // Close AppInstaller.
            await ConsolidateAppInstallerView();
            break;
        case PackageUpdateAvailability.Unknown:
        default:
            // Log and ignore error.
            Logger.Log($"No update information associated with app {targetPackageFullName}");
            // Launch target app and close AppInstaller.
            await ConsolidateAppInstallerView();
            break;
    }
}

Mise à jour des packages déployés sans fichier programme d’installation d’application

Rechercher les mises à jour sur votre serveur

Si vous n’utilisez pas le fichier Programme d’installation d’application pour déployer votre package d’application, la première étape consiste à vérifier directement si une nouvelle version de votre application est disponible. L’exemple suivant vérifie que la version du package sur un serveur est supérieure à la version actuelle de l’application (cet exemple fait référence à un serveur de test à des fins de démonstration).

using Windows.Management.Deployment;

//check for an update on my server
private async void CheckUpdate(object sender, TappedRoutedEventArgs e)
{
    WebClient client = new WebClient();
    Stream stream = client.OpenRead("https://trial3.azurewebsites.net/HRApp/Version.txt");
    StreamReader reader = new StreamReader(stream);
    var newVersion = new Version(await reader.ReadToEndAsync());
    Package package = Package.Current;
    PackageVersion packageVersion = package.Id.Version;
    var currentVersion = new Version(string.Format("{0}.{1}.{2}.{3}", packageVersion.Major, packageVersion.Minor, packageVersion.Build, packageVersion.Revision));

    //compare package versions
    if (newVersion.CompareTo(currentVersion) > 0)
    {
        var messageDialog = new MessageDialog("Found an update.");
        messageDialog.Commands.Add(new UICommand(
            "Update",
            new UICommandInvokedHandler(this.CommandInvokedHandler)));
        messageDialog.Commands.Add(new UICommand(
            "Close",
            new UICommandInvokedHandler(this.CommandInvokedHandler)));
        messageDialog.DefaultCommandIndex = 0;
        messageDialog.CancelCommandIndex = 1;
        await messageDialog.ShowAsync();
    } else
    {
        var messageDialog = new MessageDialog("Did not find an update.");
        await messageDialog.ShowAsync();
    }
}

Remarque

targetPackageFileName représente le nom complet de l'application conditionnée. (Exemple : Contoso.HeadTrax_1.0.0.0_x64__PublisherHash)

Appliquez la mise à jour

Une fois qu’une mise à jour est disponible, vous pouvez la mettre en file d’attente pour téléchargement et installation à l’aide de l’API AddPackageAsync . Il doit également fonctionner pour installer un package facultatif tant que le package principal est déjà installé sur l’appareil. La mise à jour sera appliquée la prochaine fois que votre application est arrêtée. Une fois l’application redémarrée, la nouvelle version sera disponible pour l’utilisateur. Voici un exemple de code :


// Queue up the update and close the current app instance.
private async void CommandInvokedHandler(IUICommand command)
{
    if (command.Label == "Update")
    {
        PackageManager packagemanager = new PackageManager();
        await packagemanager.AddPackageAsync(
            new Uri("https://trial3.azurewebsites.net/HRApp/HRApp.msix"),
            null,
            AddPackageOptions.ForceApplicationShutdown
        );
    }
}

Redémarrage automatique de votre application après une mise à jour

Si votre application est une application UWP, le passage de AddPackageByAppInstallerOptions.ForceApplicationShutdown OU de AddPackageOptions.ForceTargetAppShutdown lors de l’application d’une mise à jour doit planifier le redémarrage de l’application après l’arrêt et la mise à jour. Pour les applications non UWP, vous devez appeler RegisterApplicationRestart avant d’appliquer la mise à jour.

Vous devez appeler RegisterApplicationRestart avant que votre application ne commence à s’arrêter. Vous trouverez ci-dessous un exemple d’utilisation de services d’interopérabilité pour appeler la méthode native en C# :

 // Register the active instance of an application for restart in your Update method
 uint res = RelaunchHelper.RegisterApplicationRestart(null, RelaunchHelper.RestartFlags.NONE);

Exemple de la classe d’assistance pour appeler la méthode RegisterApplicationRestart native en C# :

using System;
using System.Runtime.InteropServices;

namespace MyEmployees.Helpers
{
    class RelaunchHelper
    {
        #region Restart Manager Methods
        /// <summary>
        /// Registers the active instance of an application for restart.
        /// </summary>
        /// <param name="pwzCommandLine">
        /// A pointer to a Unicode string that specifies the command-line arguments for the application when it is restarted.
        /// The maximum size of the command line that you can specify is RESTART_MAX_CMD_LINE characters. Do not include the name of the executable
        /// in the command line; this function adds it for you.
        /// If this parameter is NULL or an empty string, the previously registered command line is removed. If the argument contains spaces,
        /// use quotes around the argument.
        /// </param>
        /// <param name="dwFlags">One of the options specified in RestartFlags</param>
        /// <returns>
        /// This function returns S_OK on success or one of the following error codes:
        /// E_FAIL for internal error.
        /// E_INVALIDARG if rhe specified command line is too long.
        /// </returns>
        [DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
        internal static extern uint RegisterApplicationRestart(string pwzCommandLine, RestartFlags dwFlags);
        #endregion Restart Manager Methods

        #region Restart Manager Enums
        /// <summary>
        /// Flags for the RegisterApplicationRestart function
        /// </summary>
        [Flags]
        internal enum RestartFlags
        {
            /// <summary>None of the options below.</summary>
            NONE = 0,

            /// <summary>Do not restart the process if it terminates due to an unhandled exception.</summary>
            RESTART_NO_CRASH = 1,
            /// <summary>Do not restart the process if it terminates due to the application not responding.</summary>
            RESTART_NO_HANG = 2,
            /// <summary>Do not restart the process if it terminates due to the installation of an update.</summary>
            RESTART_NO_PATCH = 4,
            /// <summary>Do not restart the process if the computer is restarted as the result of an update.</summary>
            RESTART_NO_REBOOT = 8
        }
        #endregion Restart Manager Enums

    }
}