public async Task Add(string filePath, AddAppxPackageOptions options = 0, CancellationToken cancellationToken = default, IProgress <ProgressData> progress = default)
        {
            this.SideloadingConfigurator.AssertSideloadingEnabled();

            Logger.Info("Installing package {0}", filePath);
            if (filePath == null)
            {
                throw new ArgumentNullException(nameof(filePath));
            }

            if (string.Equals(Path.GetFileName(filePath), FileConstants.AppxManifestFile, StringComparison.OrdinalIgnoreCase))
            {
                if (options.HasFlag(AddAppxPackageOptions.AllBundleResources))
                {
                    throw new ArgumentException("Cannot use the flag AllBundleResources with non-bundle packages.", nameof(options));
                }

                var reader = await AppxManifestSummaryReader.FromManifest(filePath).ConfigureAwait(false);

                DeploymentOptions deploymentOptions = 0;

                if (options.HasFlag(AddAppxPackageOptions.AllowDowngrade))
                {
                    deploymentOptions |= DeploymentOptions.ForceUpdateFromAnyVersion;
                }

                if (options.HasFlag(AddAppxPackageOptions.KillRunningApps))
                {
                    deploymentOptions |= DeploymentOptions.ForceApplicationShutdown;
                    deploymentOptions |= DeploymentOptions.ForceTargetApplicationShutdown;
                }

                deploymentOptions |= DeploymentOptions.DevelopmentMode;

                await AsyncOperationHelper.ConvertToTask(
                    PackageManagerWrapper.Instance.RegisterPackageAsync(new Uri(filePath), Enumerable.Empty <Uri>(), deploymentOptions),
                    $"Installing {reader.DisplayName} {reader.Version}...",
                    cancellationToken,
                    progress).ConfigureAwait(false);
            }
            else if (string.Equals(FileConstants.AppInstallerExtension, Path.GetExtension(filePath), StringComparison.OrdinalIgnoreCase))
            {
                if (options.HasFlag(AddAppxPackageOptions.AllUsers))
                {
                    throw new ArgumentException("Cannot install a package from .appinstaller for all users.", nameof(options));
                }

                if (options.HasFlag(AddAppxPackageOptions.AllBundleResources))
                {
                    throw new ArgumentException("Cannot use the flag AllBundleResources with non-bundle packages.", nameof(options));
                }

                if (options.HasFlag(AddAppxPackageOptions.AllowDowngrade))
                {
                    throw new ArgumentException("Cannot force a downgrade with .appinstaller. The .appinstaller defines on its own whether the downgrade is allowed.", nameof(options));
                }

                AddPackageByAppInstallerOptions deploymentOptions = 0;

                if (options.HasFlag(AddAppxPackageOptions.KillRunningApps))
                {
                    deploymentOptions |= AddPackageByAppInstallerOptions.ForceTargetAppShutdown;
                }

                var volume = PackageManagerWrapper.Instance.GetDefaultPackageVolume();
                await AsyncOperationHelper.ConvertToTask(
                    PackageManagerWrapper.Instance.AddPackageByAppInstallerFileAsync(new Uri(filePath, UriKind.Absolute), deploymentOptions, volume),
                    "Installing from " + Path.GetFileName(filePath) + "...",
                    cancellationToken,
                    progress).ConfigureAwait(false);
            }
            else
            {
                string name, version, publisher;

                DeploymentOptions deploymentOptions = 0;

                switch (Path.GetExtension(filePath))
                {
                case FileConstants.AppxBundleExtension:
                case FileConstants.MsixBundleExtension:
                {
                    IAppxIdentityReader reader = new AppxIdentityReader();
                    var identity = await reader.GetIdentity(filePath, cancellationToken).ConfigureAwait(false);

                    name      = identity.Name;
                    publisher = identity.Publisher;
                    version   = identity.Version;

                    if (options.HasFlag(AddAppxPackageOptions.AllBundleResources))
                    {
                        deploymentOptions |= DeploymentOptions.InstallAllResources;
                    }

                    break;
                }

                default:
                {
                    if (options.HasFlag(AddAppxPackageOptions.AllBundleResources))
                    {
                        throw new ArgumentException("Cannot use the flag AllBundleResources with non-bundle packages.", nameof(options));
                    }

                    var reader = await AppxManifestSummaryReader.FromMsix(filePath).ConfigureAwait(false);

                    name      = reader.DisplayName;
                    version   = reader.Version;
                    publisher = reader.Publisher;
                    break;
                }
                }

                if (options.HasFlag(AddAppxPackageOptions.AllowDowngrade))
                {
                    deploymentOptions |= DeploymentOptions.ForceUpdateFromAnyVersion;
                }

                if (options.HasFlag(AddAppxPackageOptions.KillRunningApps))
                {
                    deploymentOptions |= DeploymentOptions.ForceApplicationShutdown;
                    deploymentOptions |= DeploymentOptions.ForceTargetApplicationShutdown;
                }

                if (options.HasFlag(AddAppxPackageOptions.AllUsers))
                {
                    var deploymentResult = await AsyncOperationHelper.ConvertToTask(
                        PackageManagerWrapper.Instance.AddPackageAsync(new Uri(filePath, UriKind.Absolute), Enumerable.Empty <Uri>(), deploymentOptions),
                        $"Installing {name} {version}...",
                        cancellationToken,
                        progress).ConfigureAwait(false);

                    if (!deploymentResult.IsRegistered)
                    {
                        throw new InvalidOperationException("The package could not be registered.");
                    }

                    var findInstalled = PackageManagerWrapper.Instance.FindPackages(name, publisher).FirstOrDefault();
                    if (findInstalled == null)
                    {
                        throw new InvalidOperationException("The package could not be registered.");
                    }

                    var familyName = findInstalled.Id.FamilyName;

                    await AsyncOperationHelper.ConvertToTask(
                        PackageManagerWrapper.Instance.ProvisionPackageForAllUsersAsync(familyName),
                        $"Provisioning {name} {version}...",
                        cancellationToken,
                        progress).ConfigureAwait(false);
                }
                else
                {
                    var deploymentResult = await AsyncOperationHelper.ConvertToTask(
                        PackageManagerWrapper.Instance.AddPackageAsync(new Uri(filePath, UriKind.Absolute), Enumerable.Empty <Uri>(), deploymentOptions),
                        "Installing " + name + "...",
                        cancellationToken,
                        progress).ConfigureAwait(false);

                    if (!deploymentResult.IsRegistered)
                    {
                        var message = "Could not install " + name + " " + version + ".";
                        if (!string.IsNullOrEmpty(deploymentResult.ErrorText))
                        {
                            message += " " + deploymentResult.ErrorText;
                        }

                        if (deploymentResult.ExtendedErrorCode != null)
                        {
                            throw new InvalidOperationException(message, deploymentResult.ExtendedErrorCode);
                        }

                        throw new InvalidOperationException(message);
                    }
                }
            }
        }
Exemple #2
0
        public async Task Add(string filePath, AddAppxPackageOptions options = 0, CancellationToken cancellationToken = default, IProgress <ProgressData> progress = default)
        {
            if (SideloadingChecker.GetStatus() < SideloadingStatus.Sideloading)
            {
                throw new DeveloperModeException("Developer mode or sideloading must be enabled to install packages outside of Microsoft Store.");
            }

            Logger.Info("Installing package {0}", filePath);
            if (filePath == null)
            {
                throw new ArgumentNullException(nameof(filePath));
            }

            if (string.Equals(Path.GetFileName(filePath), "AppxManifest.xml", StringComparison.OrdinalIgnoreCase))
            {
                var reader = await AppxManifestSummaryBuilder.FromManifest(filePath).ConfigureAwait(false);

                DeploymentOptions deploymentOptions = 0;

                if (options.HasFlag(AddAppxPackageOptions.AllowDowngrade))
                {
                    deploymentOptions |= DeploymentOptions.ForceUpdateFromAnyVersion;
                }

                if (options.HasFlag(AddAppxPackageOptions.KillRunningApps))
                {
                    deploymentOptions |= DeploymentOptions.ForceApplicationShutdown;
                    deploymentOptions |= DeploymentOptions.ForceTargetApplicationShutdown;
                }

                deploymentOptions |= DeploymentOptions.DevelopmentMode;

                await AsyncOperationHelper.ConvertToTask(
                    PackageManager.Value.RegisterPackageAsync(new Uri(filePath), Enumerable.Empty <Uri>(), deploymentOptions),
                    $"Installing {reader.DisplayName} {reader.Version}...",
                    cancellationToken,
                    progress).ConfigureAwait(false);
            }
            else if (string.Equals(".appinstaller", Path.GetExtension(filePath), StringComparison.OrdinalIgnoreCase))
            {
                if (options.HasFlag(AddAppxPackageOptions.AllUsers))
                {
                    throw new NotSupportedException("Cannot install a package from .appinstaller for all users.");
                }

                AddPackageByAppInstallerOptions deploymentOptions = 0;

                if (options.HasFlag(AddAppxPackageOptions.AllowDowngrade))
                {
                    throw new NotSupportedException("Cannot force a downgrade with .appinstaller. The .appinstaller defines on its own whether the downgrade is allowed.");
                }

                if (options.HasFlag(AddAppxPackageOptions.KillRunningApps))
                {
                    deploymentOptions |= AddPackageByAppInstallerOptions.ForceTargetAppShutdown;
                }

                var volume = PackageManager.Value.GetDefaultPackageVolume();
                await AsyncOperationHelper.ConvertToTask(
                    PackageManager.Value.AddPackageByAppInstallerFileAsync(new Uri(filePath, UriKind.Absolute), deploymentOptions, volume),
                    "Installing from " + Path.GetFileName(filePath) + "...",
                    cancellationToken,
                    progress).ConfigureAwait(false);
            }
            else
            {
                try
                {
                    var reader = await AppxManifestSummaryBuilder.FromMsix(filePath).ConfigureAwait(false);

                    DeploymentOptions deploymentOptions = 0;

                    if (options.HasFlag(AddAppxPackageOptions.AllowDowngrade))
                    {
                        deploymentOptions |= DeploymentOptions.ForceUpdateFromAnyVersion;
                    }

                    if (options.HasFlag(AddAppxPackageOptions.KillRunningApps))
                    {
                        deploymentOptions |= DeploymentOptions.ForceApplicationShutdown;
                        deploymentOptions |= DeploymentOptions.ForceTargetApplicationShutdown;
                    }

                    if (options.HasFlag(AddAppxPackageOptions.AllUsers))
                    {
                        var deploymentResult = await AsyncOperationHelper.ConvertToTask(
                            PackageManager.Value.AddPackageAsync(new Uri(filePath, UriKind.Absolute), Enumerable.Empty <Uri>(), deploymentOptions),
                            $"Installing {reader.DisplayName} {reader.Version}...",
                            cancellationToken,
                            progress).ConfigureAwait(false);

                        if (!deploymentResult.IsRegistered)
                        {
                            throw new InvalidOperationException("The package could not be registered.");
                        }

                        var findInstalled = PackageManager.Value.FindPackages(reader.Name, reader.Publisher).FirstOrDefault();
                        if (findInstalled == null)
                        {
                            throw new InvalidOperationException("The package could not be registered.");
                        }

                        var familyName = findInstalled.Id.FamilyName;

                        await AsyncOperationHelper.ConvertToTask(
                            PackageManager.Value.ProvisionPackageForAllUsersAsync(familyName),
                            $"Provisioning {reader.DisplayName} {reader.Version}...",
                            cancellationToken,
                            progress).ConfigureAwait(false);
                    }
                    else
                    {
                        var deploymentResult = await AsyncOperationHelper.ConvertToTask(
                            PackageManager.Value.AddPackageAsync(new Uri(filePath, UriKind.Absolute), Enumerable.Empty <Uri>(), deploymentOptions),
                            "Installing " + reader.DisplayName + "...",
                            cancellationToken,
                            progress).ConfigureAwait(false);

                        if (!deploymentResult.IsRegistered)
                        {
                            throw new InvalidOperationException("The package could not be registered.");
                        }
                    }
                }
                catch (InvalidDataException e)
                {
                    throw new InvalidOperationException("File " + filePath + " does not seem to be a valid MSIX package." + e, e);
                }
            }
        }