코드에서 저장 되지 않은 게시 된 앱 패키지 업데이트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. 첫 번째 섹션에서는 앱 설치 관리자 파일을 사용 하는 경우이 작업을 수행 하는 방법을 확인 하 고, 두 번째 섹션에서는 앱 설치 관리자 파일을 사용 하지 않을 때이 작업을 수행 하는 방법에 대해 살펴봅니다.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. 코드에서 앱 설치 관리자 기반 업데이트를 시작할 PackageManager AddPackageByAppInstallerFileAsync 또는 PackageManager를 사용할 수 있습니다.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 앱 인 경우 AddPackageByAppInstallerOptions를 전달 하면 업데이트를 적용할 때 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. 다음은 interop 서비스를 사용 하 여 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

    }
}