ストアに公開されていないアプリパッケージをコードから更新するUpdate non-Store published app packages from your code

アプリを MSIX として出荷する場合は、プログラムを使用してアプリケーションの更新プログラムを開始できます。When shipping your app as an MSIX you can programmatically kick-off an update of your application. ストアの外部にアプリを配置する場合は、サーバーで新しいバージョンのアプリを確認し、新しいバージョンをインストールするだけで済みます。If you deploy your app outside the Store, all you need to do is check your server for a new version of your app and install the new version. 更新プログラムの適用方法は、アプリのインストーラーファイルを使用してアプリパッケージを展開するかどうかによって異なります。How you apply the update depends on whether you are deploying your app package using an App Installer file or not. コードから更新プログラムを適用するには、アプリパッケージで機能を宣言する必要があり packageManagement ます。In order to apply updates from your code, your app package must declare the packageManagement capability.

この記事では、 packageManagement パッケージマニフェストで機能を宣言する方法と、コードから更新プログラムを適用する方法を示す例を紹介します。This article provides examples that demonstrate how to declare the packageManagement capability in your package manifest and how to apply an update from your code. 最初のセクションでは、アプリインストーラーファイルを使用している場合にこれを実行する方法について説明します。2番目のセクションでは、アプリインストーラーファイルを使用し ない 場合の方法について説明します。The first section looks at how to do this if you're using the App Installer file and the second section is about how to do so when not using the App Installer file. 最後のセクションでは、更新プログラムが適用された後にアプリが再起動されることを確認する方法について説明します。The last section looks at how to make sure your app restarts after an update has been applied.

PackageManagement 機能をパッケージマニフェストに追加するAdd the PackageManagement Capability to your package manifest

Api を使用するには PackageManager 、アプリ packageManagementパッケージマニフェスト制限付き機能を宣言する必要があります。To use the PackageManager APIs, your app must declare the packageManagement restricted capability in your package manifest.

<Package>
...

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

アプリインストーラーファイルを使用して配置されたパッケージの更新Updating packages deployed using an App Installer file

アプリケーションインストーラーファイルを使用してアプリケーションを配置する場合、実行するコード駆動型の更新では、 アプリインストーラーファイル apiを使用する必要があります。If you are deploying your application using the App Installer file, any code driven updates you perform must make use of the App Installer file APIs. これにより、通常のアプリインストーラーファイルの更新が引き続き機能するようになります。Doing so ensures that your regular App Installer file updates will continue to work. コードからアプリインストーラーベースの更新プログラムを開始するには、 AddPackageByAppInstallerFileAsync または RequestAddPackageByAppInstallerFileAsyncを使用できます。For intiating an App Installer based update from your code you can use PackageManager.AddPackageByAppInstallerFileAsync or PackageManager.RequestAddPackageByAppInstallerFileAsync. CheckUpdateAvailabilityAsync API を使用して更新プログラムが利用可能かどうかを確認できます。You can check if an update is available using the Package.CheckUpdateAvailabilityAsync API. 次にコード例を示します。Below is example 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;
    }
}

アプリのインストーラーファイルを使用せずに配置されたパッケージの更新Updating packages deployed without an App Installer file

サーバーの更新プログラムを確認するCheck for updates on your server

アプリケーションパッケージの展開にアプリインストーラーファイルを使用して いない 場合、最初の手順は、アプリケーションの新しいバージョンが使用可能かどうかを直接確認することです。If you are not using the App Installer file to deploy your app package, the first step is to directly check if a new version of your application available. 次の例では、サーバー上のパッケージのバージョンが、アプリの現在のバージョンよりも大きいかどうかを確認します (この例では、デモンストレーション用のテストサーバーを示しています)。The following example checks to see of the version of the package on a server is greater than the current version of the app (this example refers to a test server for demonstration purposes).

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

更新プログラムを適用するApply the update

更新プログラムが利用可能かどうかを確認したら、 AddPackageAsync API を使用して、更新プログラムをキューに入れて、ダウンロードとインストールを行うことができます。After you determined that an update is available, you can queue it up for download and install using the AddPackageAsync API. 更新プログラムは、次回アプリがシャットダウンされたときに適用されます。The update will be applied the next time your app is shut down. アプリが再起動されると、ユーザーは新しいバージョンを使用できるようになります。After the app is restarted, the new version will be available to the user. 次にコード例を示します。Below is example 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
        );
    }
}

更新後にアプリを自動的に再起動するAutomatically restarting your app after an update

アプリケーションが UWP アプリの場合は、Addpackagebyappインストーラオプションを渡します。また、更新を適用するときに ForceTargetAppShutdown は、シャットダウン + 更新後にアプリを再起動するようにスケジュールする必要があります。If your application is a UWP app, passing in AddPackageByAppInstallerOptions.ForceApplicationShutdown OR AddPackageOptions.ForceTargetAppShutdown when applying an update should schedule the app to restart after the shutdown + update. UWP 以外のアプリの場合は、更新プログラムを適用する前に Registerapplicationrestart を呼び出す必要があります。For non-UWP apps you need to call RegisterApplicationRestart before applying the update.

アプリがシャットダウンを開始する前に、RegisterApplicationRestart を呼び出す必要があります。You must call RegisterApplicationRestart before your app begins to shut down. 相互運用サービスを使用して C# でネイティブメソッドを呼び出す例を次に示します。Below is an example of doing so using interop services to call the native method in C#:

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

C# でネイティブの RegisterApplicationRestart メソッドを呼び出すヘルパークラスの例を次に示します。An example of the helper class to call the native RegisterApplicationRestart method in 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

    }
}