Beispiel #1
0
        public void TestInvalidXmlFile()
        {
            var invalidContent =
                @"<?xml version=""1.0""?>
<NotSupportedRoot xmlns=""http://schemas.microsoft.com/appx/manifest/foundation/windows10"">
  <Identity 
    Name=""SampleProduct"" 
    Publisher=""CN=me"" 
    Version=""1.2.3.4"" 
    ProcessorArchitecture=""x64"" />
</NotSupportedRoot>
";

            var utfEncoding = new UTF8Encoding(false, false);
            var xmlStream   = new MemoryStream(utfEncoding.GetBytes(invalidContent));

            IAppxIdentityReader reader = new AppxIdentityReader();

            Assert.Throws <ArgumentException>(() =>
            {
                GuardAggregateExceptions(() =>
                {
                    reader.GetIdentity(xmlStream).Wait();
                });
            },
                                              "This must throw because the file is definitely not in MSIX, APPX or any other supported format.");
        }
Beispiel #2
0
        public void TestMismatchedExtension()
        {
            GuardTempDirectory(tempDirectory =>
            {
                // Build an APPX package which is in reality an appx bundle.
                var tempFile = Path.Combine(tempDirectory.FullName, "bundle.appx");
                using (var fileStream = File.OpenWrite(tempFile))
                {
                    using (var zip = new ZipArchive(fileStream, ZipArchiveMode.Create, true))
                    {
                        var entry       = zip.CreateEntry(FileConstants.AppxBundleManifestFilePath);
                        var entryStream = entry.Open();

                        var embeddedResourceName = this.GetType().Assembly.GetManifestResourceNames().First(rn => rn.Contains("resources.appxbundlemanifest.xml", StringComparison.OrdinalIgnoreCase));
                        using var bundleManifest = this.GetType().Assembly.GetManifestResourceStream(embeddedResourceName);

                        // ReSharper disable once PossibleNullReferenceException
                        bundleManifest.CopyTo(entryStream);
                    }
                }

                IAppxIdentityReader reader = new AppxIdentityReader();
                Assert.Throws <ArgumentException>(() =>
                {
                    GuardAggregateExceptions(() =>
                    {
                        reader.GetIdentity(tempFile).Wait();
                    });
                },
                                                  "This must throw, because the file on a disk has an APPX extension but the content is a bundle.");

                using (var fileStream = File.OpenRead(tempFile))
                {
                    Assert.Throws <ArgumentException>(() =>
                    {
                        GuardAggregateExceptions(() =>
                        {
                            // ReSharper disable once AccessToDisposedClosure
                            reader.GetIdentity(fileStream).Wait();
                        });
                    },
                                                      "This must throw, because file stream points to a concrete file on a disk which has an APPX extension but the content is a bundle.");
                }

                using var memoryStream = new MemoryStream(File.ReadAllBytes(tempFile));
                // The following may not throw, because a memory stream will be tried for various options and asserted to be an APPX bundle.
                reader.GetIdentity(memoryStream).Wait();
            });
        }
Beispiel #3
0
        public void TestInvalidZipFile()
        {
            using var memoryStream = new MemoryStream();
            using (var zipArchive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true))
            {
                // add some dummy file = not a manifest
                var dummyFile = zipArchive.CreateEntry("dummyFile.xml");
                var s         = dummyFile.Open();
                s.WriteByte(128);
            }

            IAppxIdentityReader reader = new AppxIdentityReader();

            Assert.Throws <ArgumentException>(() =>
            {
                GuardAggregateExceptions(() =>
                {
                    // ReSharper disable once AccessToDisposedClosure
                    reader.GetIdentity(memoryStream).Wait();
                });
            },
                                              "This must throw because the file is a ZIP-like but contains no manifest.");
        }
        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);
                    }
                }
            }
        }
        public AppInstallerConfig Build(PackageType packageType = PackageType.Package)
        {
            var appIns = new AppInstallerConfig();

            appIns.UpdateSettings = new UpdateSettings();
            switch (this.CheckForUpdates)
            {
            case AppInstallerUpdateCheckingMethod.Never:
                appIns.UpdateSettings.OnLaunch = null;
                appIns.UpdateSettings.AutomaticBackgroundTask = null;
                break;

            case AppInstallerUpdateCheckingMethod.Launch:
                appIns.UpdateSettings.OnLaunch = new OnLaunchSettings();
                appIns.UpdateSettings.AutomaticBackgroundTask = null;
                break;

            case AppInstallerUpdateCheckingMethod.LaunchAndBackground:
                appIns.UpdateSettings.OnLaunch = new OnLaunchSettings();
                appIns.UpdateSettings.AutomaticBackgroundTask = new AutomaticBackgroundTaskSettings();
                break;

            case AppInstallerUpdateCheckingMethod.Background:
                appIns.UpdateSettings.OnLaunch = null;
                appIns.UpdateSettings.AutomaticBackgroundTask = new AutomaticBackgroundTaskSettings();
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            if (this.AllowDowngrades)
            {
                appIns.UpdateSettings.ForceUpdateFromAnyVersion = true;
            }

            appIns.UpdateSettings.ForceUpdateFromAnyVersion = this.AllowDowngrades;

            if (appIns.UpdateSettings.OnLaunch != null)
            {
                appIns.UpdateSettings.OnLaunch.UpdateBlocksActivation = this.UpdateBlocksActivation;
                appIns.UpdateSettings.OnLaunch.ShowPrompt             = this.ShowPrompt;

                if (this.HoursBetweenUpdateChecks != 24)
                {
                    appIns.UpdateSettings.OnLaunch.HoursBetweenUpdateChecks = this.HoursBetweenUpdateChecks;
                }
            }

            if (this.MainPackageSource != null)
            {
                AppxIdentity identity;
                var          identityReader = new AppxIdentityReader();

                try
                {
                    identity = identityReader.GetIdentity(this.MainPackageSource.FullName).Result;
                }
                catch (AggregateException e)
                {
                    throw e.GetBaseException();
                }

                if (packageType == PackageType.Bundle)
                {
                    appIns.MainBundle = new AppInstallerBundleEntry
                    {
                        Name      = identity.Name,
                        Version   = identity.Version,
                        Publisher = identity.Publisher,
                        Uri       = this.MainPackageUri?.ToString()
                    };
                }
                else
                {
                    appIns.MainPackage = new AppInstallerPackageEntry
                    {
                        Name      = identity.Name,
                        Version   = identity.Version,
                        Publisher = identity.Publisher,
                        Uri       = this.MainPackageUri?.ToString()
                    };

                    if (identity.Architectures?.Any() != true)
                    {
                        appIns.MainPackage.Architecture = AppInstallerPackageArchitecture.neutral;
                    }
                    else
                    {
                        var arch = identity.Architectures.First().ToString("G");
                        if (Enum.TryParse(arch, true, out AppInstallerPackageArchitecture parsed))
                        {
                            appIns.MainPackage.Architecture = parsed;
                        }
                    }
                }
            }
            else
            {
                if (packageType == PackageType.Bundle)
                {
                    appIns.MainBundle = new AppInstallerBundleEntry
                    {
                        Name      = this.MainPackageName,
                        Version   = this.MainPackageVersion,
                        Publisher = MainPackagePublisher,
                        Uri       = this.MainPackageUri?.ToString()
                    };
                }
                else if (packageType == PackageType.Package)
                {
                    appIns.MainPackage = new AppInstallerPackageEntry
                    {
                        Name         = this.MainPackageName,
                        Version      = this.MainPackageVersion,
                        Publisher    = MainPackagePublisher,
                        Uri          = this.MainPackageUri?.ToString(),
                        Architecture = (AppInstallerPackageArchitecture)Enum.Parse(typeof(AppInstallerPackageArchitecture), this.MainPackageArchitecture.ToString("G"), true)
                    };
                }
            }

            if (!appIns.UpdateSettings.ForceUpdateFromAnyVersion && appIns.UpdateSettings.OnLaunch == null && appIns.UpdateSettings.AutomaticBackgroundTask == null)
            {
                appIns.UpdateSettings = null;
            }

            if (this.RedirectUri != null)
            {
                appIns.Uri = this.RedirectUri.ToString();
            }

            appIns.Version = this.Version ?? "1.0.0.0";

            return(appIns);
        }
Beispiel #6
0
        public void TestAppxBundleManifest()
        {
            // in a manifest, from memory
            GuardAggregateExceptions(() =>
            {
                IAppxIdentityReader reader = new AppxIdentityReader();

                var embeddedResourceName = this.GetType().Assembly.GetManifestResourceNames().First(rn => rn.Contains("resources.appxbundlemanifest.xml", StringComparison.OrdinalIgnoreCase));
                using var bundleManifest = this.GetType().Assembly.GetManifestResourceStream(embeddedResourceName);

                var identity = reader.GetIdentity(bundleManifest).Result;

                Assert.AreEqual("Microsoft.DesktopAppInstaller", identity.Name);
                Assert.AreEqual("CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US", identity.Publisher);
                Assert.AreEqual("2021.119.2316.0", identity.Version);
                Assert.NotNull(identity.Architectures);
                Assert.AreEqual(3, identity.Architectures.Length);
                Assert.IsTrue(identity.Architectures.Contains(AppxPackageArchitecture.Arm));
                Assert.IsTrue(identity.Architectures.Contains(AppxPackageArchitecture.x64));
                Assert.IsTrue(identity.Architectures.Contains(AppxPackageArchitecture.x86));
            });

            // in a manifest, saved on disk
            GuardTempDirectory(tempDirectory =>
            {
                IAppxIdentityReader reader = new AppxIdentityReader();

                var manifestFile = Path.Combine(tempDirectory.FullName, FileConstants.AppxBundleManifestFile);

                using (var fs = File.OpenWrite(manifestFile))
                {
                    var embeddedResourceName = this.GetType().Assembly.GetManifestResourceNames().First(rn => rn.Contains("resources.appxbundlemanifest.xml", StringComparison.OrdinalIgnoreCase));
                    using var bundleManifest = this.GetType().Assembly.GetManifestResourceStream(embeddedResourceName);

                    // ReSharper disable once PossibleNullReferenceException
                    bundleManifest.CopyTo(fs);
                    fs.Flush();
                }

                var identity = reader.GetIdentity(manifestFile).Result;
                Assert.AreEqual("Microsoft.DesktopAppInstaller", identity.Name);
                Assert.AreEqual("CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US", identity.Publisher);
                Assert.AreEqual("2021.119.2316.0", identity.Version);
                Assert.NotNull(identity.Architectures);
                Assert.AreEqual(3, identity.Architectures.Length);
                Assert.IsTrue(identity.Architectures.Contains(AppxPackageArchitecture.Arm));
                Assert.IsTrue(identity.Architectures.Contains(AppxPackageArchitecture.x64));
                Assert.IsTrue(identity.Architectures.Contains(AppxPackageArchitecture.x86));
            });

            // in a zip file
            GuardAggregateExceptions(() =>
            {
                using var memStream = new MemoryStream();

                // build package resembling MSIX structure
                using (var stream = new ZipArchive(memStream, ZipArchiveMode.Create, true))
                {
                    var entry       = stream.CreateEntry(FileConstants.AppxBundleManifestFilePath);
                    var entryStream = entry.Open();

                    var embeddedResourceName = this.GetType().Assembly.GetManifestResourceNames().First(rn => rn.Contains("resources.appxbundlemanifest.xml", StringComparison.OrdinalIgnoreCase));
                    using var bundleManifest = this.GetType().Assembly.GetManifestResourceStream(embeddedResourceName);

                    // ReSharper disable once PossibleNullReferenceException
                    bundleManifest.CopyTo(entryStream);
                }

                memStream.Seek(0, SeekOrigin.Begin);
                IAppxIdentityReader reader = new AppxIdentityReader();
                var identity = reader.GetIdentity(memStream).Result;
                Assert.AreEqual("Microsoft.DesktopAppInstaller", identity.Name);
                Assert.AreEqual("CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US", identity.Publisher);
                Assert.AreEqual("2021.119.2316.0", identity.Version);
                Assert.NotNull(identity.Architectures);
                Assert.AreEqual(3, identity.Architectures.Length);
                Assert.IsTrue(identity.Architectures.Contains(AppxPackageArchitecture.Arm));
                Assert.IsTrue(identity.Architectures.Contains(AppxPackageArchitecture.x64));
                Assert.IsTrue(identity.Architectures.Contains(AppxPackageArchitecture.x86));
            });

            // in a zip file, saved on disk
            GuardTempDirectory(tempDirectory =>
            {
                var tempFile = Path.Combine(tempDirectory.FullName, "testpackage.appxbundle");

                using (var tempFileStream = File.OpenWrite(tempFile))
                {
                    // build package resembling MSIX structure
                    using var stream = new ZipArchive(tempFileStream, ZipArchiveMode.Create, false);
                    var entry        = stream.CreateEntry(FileConstants.AppxBundleManifestFilePath);
                    var entryStream  = entry.Open();

                    var embeddedResourceName = this.GetType().Assembly.GetManifestResourceNames().First(rn => rn.Contains("resources.appxbundlemanifest.xml", StringComparison.OrdinalIgnoreCase));
                    using var bundleManifest = this.GetType().Assembly.GetManifestResourceStream(embeddedResourceName);

                    // ReSharper disable once PossibleNullReferenceException
                    bundleManifest.CopyTo(entryStream);
                }

                IAppxIdentityReader reader = new AppxIdentityReader();
                var identity = reader.GetIdentity(tempFile).Result;
                Assert.AreEqual("Microsoft.DesktopAppInstaller", identity.Name);
                Assert.AreEqual("CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US", identity.Publisher);
                Assert.AreEqual("2021.119.2316.0", identity.Version);
                Assert.NotNull(identity.Architectures);
                Assert.AreEqual(3, identity.Architectures.Length);
                Assert.IsTrue(identity.Architectures.Contains(AppxPackageArchitecture.Arm));
                Assert.IsTrue(identity.Architectures.Contains(AppxPackageArchitecture.x64));
                Assert.IsTrue(identity.Architectures.Contains(AppxPackageArchitecture.x86));
            });
        }
Beispiel #7
0
        public void TestAppxManifest()
        {
            // in a manifest, from memory
            GuardAggregateExceptions(() =>
            {
                IAppxIdentityReader reader = new AppxIdentityReader();

                var utfEncoding = new UTF8Encoding(false, false);

                var stream   = new MemoryStream(utfEncoding.GetBytes(SimpleAppxManifestContent));
                var identity = reader.GetIdentity(stream).Result;
                Assert.AreEqual("SampleProduct", identity.Name);
                Assert.AreEqual("CN=me", identity.Publisher);
                Assert.AreEqual("1.2.3.4", identity.Version);
                Assert.NotNull(identity.Architectures);
                Assert.AreEqual(1, identity.Architectures.Length);
                Assert.AreEqual(AppxPackageArchitecture.x64, identity.Architectures[0]);
            });

            // in a manifest, saved on disk
            GuardTempDirectory(tempDirectory =>
            {
                IAppxIdentityReader reader = new AppxIdentityReader();

                var manifestFile = Path.Combine(tempDirectory.FullName, FileConstants.AppxManifestFile);
                var utfEncoding  = new UTF8Encoding(false, false);
                File.WriteAllText(manifestFile, SimpleAppxManifestContent, utfEncoding);

                var identity = reader.GetIdentity(manifestFile).Result;
                Assert.AreEqual("SampleProduct", identity.Name);
                Assert.AreEqual("CN=me", identity.Publisher);
                Assert.AreEqual("1.2.3.4", identity.Version);
                Assert.NotNull(identity.Architectures);
                Assert.AreEqual(1, identity.Architectures.Length);
                Assert.AreEqual(AppxPackageArchitecture.x64, identity.Architectures[0]);
            });

            // in a zip file
            GuardAggregateExceptions(() =>
            {
                using var memStream = new MemoryStream();

                // build package resembling MSIX structure
                using (var stream = new ZipArchive(memStream, ZipArchiveMode.Create, true))
                {
                    var entry       = stream.CreateEntry(FileConstants.AppxManifestFile);
                    var entryStream = entry.Open();
                    var utfEncoding = new UTF8Encoding(false, false);
                    using (var streamWriter = new StreamWriter(entryStream, utfEncoding, leaveOpen: true))
                    {
                        streamWriter.Write(SimpleAppxManifestContent);
                    }
                }

                memStream.Seek(0, SeekOrigin.Begin);
                IAppxIdentityReader reader = new AppxIdentityReader();
                var identity = reader.GetIdentity(memStream).Result;
                Assert.AreEqual("SampleProduct", identity.Name);
                Assert.AreEqual("CN=me", identity.Publisher);
                Assert.AreEqual("1.2.3.4", identity.Version);
                Assert.NotNull(identity.Architectures);
                Assert.AreEqual(1, identity.Architectures.Length);
                Assert.AreEqual(AppxPackageArchitecture.x64, identity.Architectures[0]);
            });

            // in a zip file, saved on disk
            GuardTempDirectory(tempDirectory =>
            {
                var tempFile = Path.Combine(tempDirectory.FullName, "testpackage.appx");

                using (var tempFileStream = File.OpenWrite(tempFile))
                {
                    // build package resembling MSIX structure
                    using (var stream = new ZipArchive(tempFileStream, ZipArchiveMode.Create, false))
                    {
                        var entry       = stream.CreateEntry(FileConstants.AppxManifestFile);
                        var entryStream = entry.Open();
                        var utfEncoding = new UTF8Encoding(false, false);
                        using (var streamWriter = new StreamWriter(entryStream, utfEncoding, leaveOpen: true))
                        {
                            streamWriter.Write(SimpleAppxManifestContent);
                        }
                    }
                }

                IAppxIdentityReader reader = new AppxIdentityReader();
                var identity = reader.GetIdentity(tempFile).Result;
                Assert.AreEqual("SampleProduct", identity.Name);
                Assert.AreEqual("CN=me", identity.Publisher);
                Assert.AreEqual("1.2.3.4", identity.Version);
                Assert.NotNull(identity.Architectures);
                Assert.AreEqual(1, identity.Architectures.Length);
                Assert.AreEqual(AppxPackageArchitecture.x64, identity.Architectures[0]);
            });
        }