|
| 1 | +# Background |
| 2 | + |
| 3 | +This is the spec for proposal |
| 4 | +[Windows App Runtime Deployment API #1240](https://github.com/microsoft/WindowsAppSDK/issues/1240). |
| 5 | + |
| 6 | +The Windows App SDK (WinAppSDK) for packaged apps involves the framework, main, and singleton |
| 7 | +packages, which are all signed and published by Microsoft. The framework package contains the |
| 8 | +WinAppSDK binaries used at run time, and it is installed with the application. The main package |
| 9 | +contains out-of-process services that are brokered between apps, such as push notifications, and it |
| 10 | +is also needed for the framework to be serviced by the Microsoft Store. The singleton package |
| 11 | +supports a single long-running process that is brokered between apps for features like push |
| 12 | +notifications. |
| 13 | + |
| 14 | +Currently, packaged apps can only declare dependencies on framework packages. In order to get the |
| 15 | +other packages (main, singleton) deployed, apps can use the mechanism described here as part of |
| 16 | +their first-run experience. |
| 17 | + |
| 18 | +> **Note that in Windows App SDK version 1.0**, only MSIX packaged apps that are full trust or have |
| 19 | +> the packageManagement restricted capability have the permission to use the Deployment API to |
| 20 | +> install the main and singleton package dependencies. Support for partial trust packaged apps will |
| 21 | +> be coming in later releases. Additionally, support for main and singleton package deployment |
| 22 | +> through the Microsoft Store will be coming in later releases. |
| 23 | +
|
| 24 | +# Description |
| 25 | + |
| 26 | +When a packaged app using the WinAppSDK is deployed from the Store, it will be installed with the |
| 27 | +application's main package and the WinAppSDK framework package. The WinAppSDK main and singleton |
| 28 | +packages may not already be present on the system, or may not be at the version required by the |
| 29 | +application. The Deployment API enables a developer to check when the required WinAppSDK main and |
| 30 | +singleton packages are missing and get them installed. |
| 31 | + |
| 32 | +Since the Deployment API is part of the WinAppSDK framework package, the framework itself must be |
| 33 | +present. To deploy the framework package with the MSIX packaged application, the framework must be |
| 34 | +declared as a dependency in the application manifest with a min version specified. For instructions |
| 35 | +on deploying the framework package, see the |
| 36 | +[developer docs](https://docs.microsoft.com/windows/apps/windows-app-sdk/deploy-packaged-apps#deploy-the-windows-app-sdk-framework-package). |
| 37 | + |
| 38 | +If a developer prefers to have the Microsoft Store automatically service the WinAppSDK framework |
| 39 | +package and if features like push notifications are desired, then the main and singleton should also |
| 40 | +be deployed. Developers must not assume that the WinAppSDK main and singleton packages are already |
| 41 | +present on the system, or that the version present is the minimum version required by the |
| 42 | +application. Instead, the Deployment API should be used to validate that the WinAppSDK is at the |
| 43 | +correct version and that all required packages are present. |
| 44 | + |
| 45 | +The Deployment API addresses the following two developer scenarios: |
| 46 | + |
| 47 | +1. Does this system have the min version of the WinAppSDK main and singleton packages required by my |
| 48 | + app? |
| 49 | +2. How do I install these packages, if they are not already present on the system? |
| 50 | + |
| 51 | +The API addresses #1 by a simple query of the version needed and a check for OS updates. |
| 52 | + |
| 53 | +#2 has two possible answers. |
| 54 | + |
| 55 | +- First, the developer can install the packages directly through the app, if possible. These MSIX |
| 56 | + packages can be acquired through |
| 57 | + [Downloads page](https://docs.microsoft.com/windows/apps/windows-app-sdk/downloads). |
| 58 | +- Alternatively, MSIX packaged apps that are full trust or have the packageManagement restricted |
| 59 | + capability can use the Deployment API to get these packages installed. |
| 60 | + |
| 61 | +# Examples |
| 62 | + |
| 63 | +## GetStatus |
| 64 | + |
| 65 | +This is the means by which an app or program can call to verify that all required packages are |
| 66 | +present to a minimum version needed by the framework loaded with the app. A process should call |
| 67 | +GetStatus() after process initialization and before using Windows App Runtime content (e.g. in |
| 68 | +main() or WinMain()). |
| 69 | + |
| 70 | +Developers call this method without parameters, as all information about the version, channel, and |
| 71 | +architecture are derived from the current WinAppSDK framework package loaded. |
| 72 | + |
| 73 | +```C# |
| 74 | + DeploymentResult result = DeploymentManager.GetStatus(); |
| 75 | + if (result.Status == DeploymentStatus.Ok) |
| 76 | + { |
| 77 | + // WindowsAppRuntime is in a good state and ready for use. |
| 78 | + } |
| 79 | + else |
| 80 | + { |
| 81 | + // WindowsAppRuntime is not in a good state. |
| 82 | + // Should call Initialize on another thread, or not use features that require the |
| 83 | + // WindowsAppRuntime. result.ExtendedError has the error code that has the reason |
| 84 | + // for the Status. |
| 85 | + } |
| 86 | +``` |
| 87 | + |
| 88 | +## Initialize |
| 89 | + |
| 90 | +This API performs a status check, and if the main and/or singleton packages are missing or not at |
| 91 | +the required version, it will attempt to deploy those packages and get the WindowsAppRuntime into an |
| 92 | +OK state. All information about the version, channel, and architecture needed are derived from the |
| 93 | +current WinAppSDK framework package. |
| 94 | + |
| 95 | +Since both the main _and_ the singleton packages may need to be installed, it is possible that one |
| 96 | +package is installed successfully but not the other. If so, the returned WindowsAppRuntimeStatus |
| 97 | +will contain the error, if one occurs during package install. There will be no rollback of any |
| 98 | +successfully installed packages. See the |
| 99 | +[developer docs](https://docs.microsoft.com/windows/apps/windows-app-sdk/deploy-packaged-apps#address-installation-errors) |
| 100 | +for instructions on how to handle errors. |
| 101 | + |
| 102 | +The install of the packages may take a couple seconds to complete, which may be a performance |
| 103 | +concern to some developers. To address these concerns, developers can instead call GetStatus() first |
| 104 | +and verify that the required packages are missing. If so, then call Initialize() on another thread |
| 105 | +to handle the time delay more elegantly. |
| 106 | + |
| 107 | +Once the main and singleton packages have been deployed, they generally do not need to be deployed |
| 108 | +again. If a user were to remove the main or singleton package, the API can be used to reinstall them |
| 109 | +again. |
| 110 | + |
| 111 | +```C# |
| 112 | + if (DeploymentManager.GetStatus().Status != DeploymentStatus.Ok) |
| 113 | + { |
| 114 | + // Initialize does a status check, and if the status is not Ok it will attempt to get |
| 115 | + // the WindowsAppRuntime into a good state by deploying packages. Unlike a simple |
| 116 | + // status check, Initialize can sometimes take several seconds to deploy the packages. |
| 117 | + // These should be run on a separate thread so as not to hang your app while the |
| 118 | + // packages deploy. |
| 119 | + var initializeTask = Task.Run(() => DeploymentManager.Initialize()); |
| 120 | + initializeTask.Wait(); |
| 121 | + |
| 122 | + // Check the result. |
| 123 | + if (initializeTask.Result.Status != DeploymentStatus.Ok) |
| 124 | + { |
| 125 | + // The WindowsAppRuntime is in a bad state which Initialize() did not fix. |
| 126 | + // Do error reporting or gather information for submitting a bug. |
| 127 | + // Gracefully exit the program or carry on without using the WindowsAppRuntime. |
| 128 | + } |
| 129 | + } |
| 130 | +``` |
| 131 | + |
| 132 | +# API Details |
| 133 | + |
| 134 | +```c# |
| 135 | +namespace Microsoft.Windows.ApplicationModel.WindowsAppRuntime |
| 136 | +{ |
| 137 | + /// Represents the current Deployment status of the WindowsAppRuntime |
| 138 | + enum DeploymentStatus |
| 139 | + { |
| 140 | + Unknown = 0, |
| 141 | + Ok, |
| 142 | + PackageInstallRequired, |
| 143 | + PackageInstallFailed, |
| 144 | + }; |
| 145 | + |
| 146 | + /// Represents the a result of a Deployment Manager method. |
| 147 | + runtimeclass DeploymentResult |
| 148 | + { |
| 149 | + DeploymentResult(DeploymentStatus status, HRESULT extendedError); |
| 150 | + |
| 151 | + /// Returns the DeploymentStatus of the result. |
| 152 | + DeploymentStatus Status { get; }; |
| 153 | + |
| 154 | + /// Returns the first encountered error if there was an error or S_OK if no error. |
| 155 | + HRESULT ExtendedError{ get; }; |
| 156 | + }; |
| 157 | + |
| 158 | + /// Used to query deployment information for WindowsAppRuntime |
| 159 | + static runtimeclass DeploymentManager |
| 160 | + { |
| 161 | + /// Returns the current deployment status of the current package's Windows App Runtime. |
| 162 | + static DeploymentResult GetStatus(); |
| 163 | + |
| 164 | + /// Checks the status of the WindowsAppRuntime of the current package and attempts to |
| 165 | + /// register any missing packages that can be registered. |
| 166 | + static DeploymentResult Initialize(); |
| 167 | + }; |
| 168 | +} |
| 169 | +``` |
0 commit comments