private async Task<CreatedItem> CreateDefaultLogo(CancellationToken cancellationToken = default)
 {
     var logoSourcePath = Path.Combine(Path.GetTempPath(), "Logo-" + Guid.NewGuid().ToString("N").Substring(0, 10) + ".png");
     var bundledLogoPath = GetBundledResourcePath("Logo.png");
     await using var sourceStream = File.OpenRead(bundledLogoPath);
     await using var targetStream = File.OpenWrite(logoSourcePath);
     await sourceStream.CopyToAsync(targetStream, cancellationToken).ConfigureAwait(false);
     return CreatedItem.CreateAsset(logoSourcePath, "Assets/Logo.png");
 }
        private Task<CreatedItem> CreateLogo(FileInfo logoSource)
        {
            string logoSourcePath = Path.Combine(Path.GetTempPath(), "Logo-" + Guid.NewGuid().ToString("N").Substring(0, 10) + ".png");
            
            ExceptionGuard.Guard(() =>
            {
                // ReSharper disable once AccessToModifiedClosure
                using var icon = Icon.ExtractAssociatedIcon(logoSource.FullName);
                if (icon == null)
                {
                    return;
                }

                using var bitmap = icon.ToBitmap();
                bitmap.Save(logoSourcePath, ImageFormat.Png);
            });
        
            if (File.Exists(logoSourcePath))
            {
                return Task.FromResult(CreatedItem.CreateAsset(logoSourcePath, "Assets/Logo.png"));
            }

            return Task.FromResult(default(CreatedItem));
        }
        public async IAsyncEnumerable<CreatedItem> CreateManifestForDirectory(
            DirectoryInfo sourceDirectory,
            AppxManifestCreatorOptions options = default,
            [EnumeratorCancellation] CancellationToken cancellationToken = default,
            IProgress<Progress> progress = null)
        {
            options ??= AppxManifestCreatorOptions.Default;
            
            // Add logo to assets if there is nothing
            if (options.CreateLogo)
            {
                CreatedItem logo = default;
                foreach (var entryPoint in options.EntryPoints ?? Enumerable.Empty<string>())
                {
                    cancellationToken.ThrowIfCancellationRequested();

                    try
                    {
                        var entryPointPath = new FileInfo(Path.Combine(sourceDirectory.FullName, entryPoint));
                        if (entryPointPath.Exists)
                        {
                            logo = await this.CreateLogo(entryPointPath).ConfigureAwait(false);
                        }
                    }
                    // ReSharper disable once EmptyGeneralCatchClause
                    catch
                    {
                    }

                    if (!default(CreatedItem).Equals(logo))
                    {
                        break;
                    }
                }

                if (default(CreatedItem).Equals(logo))
                {
                    logo = await this.CreateDefaultLogo(cancellationToken).ConfigureAwait(false);
                }

                yield return logo;
            }
            
            if (options.RegistryFile?.Exists == true)
            {
                await foreach (var registryItem in this.CreateRegistryEntries(options.RegistryFile).ConfigureAwait(false))
                {
                    cancellationToken.ThrowIfCancellationRequested();

                    if (!registryItem.Equals(default(CreatedItem)))
                    {
                        yield return registryItem;
                    }
                }
            }

            // The actual part - create the manifest
            var modPackageTemplate = GetBundledResourcePath("ModificationPackage.AppxManifest.xml");
            await using var openTemplate = File.OpenRead(modPackageTemplate);
            var xml = await XDocument.LoadAsync(openTemplate, LoadOptions.None, cancellationToken).ConfigureAwait(false);
            var entryPoints = options.EntryPoints;

            if (entryPoints?.Any() != true)
            {
                var getExeFiles = await this.GetEntryPointCandidates(sourceDirectory, cancellationToken).ConfigureAwait(false);
                entryPoints = getExeFiles.ToArray();
            }

            if (options.EntryPoints?.Any() == true)
            {
                foreach (var entryPoint in options.EntryPoints)
                {
                    cancellationToken.ThrowIfCancellationRequested();

                    ExceptionGuard.Guard(() =>
                    {
                        var fvi = FileVersionInfo.GetVersionInfo(Path.Combine(sourceDirectory.FullName, entryPoint));

                        if (options.Version == null)
                        {
                            options.Version = Version.TryParse(fvi.ProductVersion ?? fvi.FileVersion ?? "#", out var v) ? v : null;
                        }

                        if (string.IsNullOrEmpty(options.PackageName) && !string.IsNullOrEmpty(Sanitize(fvi.ProductName)))
                        {
                            options.PackageName = Sanitize(fvi.ProductName, "ProductName")?.Trim();
                        }

                        if (string.IsNullOrEmpty(options.PackageDisplayName) && !string.IsNullOrEmpty(fvi.ProductName))
                        {
                            options.PackageDisplayName = fvi.ProductName?.Trim();
                        }

                        if (string.IsNullOrEmpty(options.PublisherName) && !string.IsNullOrEmpty(Sanitize(fvi.CompanyName)))
                        {
                            options.PublisherName = "CN=" + Sanitize(fvi.CompanyName, "CompanyName");
                        }

                        if (string.IsNullOrEmpty(options.PublisherDisplayName) && !string.IsNullOrEmpty(Sanitize(fvi.CompanyName)))
                        {
                            options.PublisherDisplayName = fvi.CompanyName?.Trim();
                        }
                    });

                    if (options.Version != null &&
                        !string.IsNullOrEmpty(options.PublisherName) &&
                        !string.IsNullOrEmpty(options.PublisherDisplayName) &&
                        !string.IsNullOrEmpty(options.PackageName) &&
                        !string.IsNullOrEmpty(options.PackageDisplayName))
                    {
                        break;
                    }
                }
            }

            if (string.IsNullOrEmpty(options.PackageDisplayName))
            {
                options.PackageDisplayName = "MyPackage";
            }

            if (string.IsNullOrEmpty(options.PackageName))
            {
                options.PackageName = "MyPackage";
            }

            if (string.IsNullOrEmpty(options.PublisherName))
            {
                options.PublisherName = "CN=Publisher";
            }

            if (string.IsNullOrEmpty(options.PublisherDisplayName))
            {
                options.PublisherDisplayName = "Publisher";
            }

            if (options.Version == null)
            {
                options.Version = new Version(1, 0, 0);
            }

            await this.AdjustManifest(xml, options, sourceDirectory, entryPoints).ConfigureAwait(false);
            var manifestContent = xml.ToString(SaveOptions.OmitDuplicateNamespaces);
            
            var manifestFilePath = Path.Combine(Path.GetTempPath(), Path.GetFileName(FileConstants.AppxManifestFile) + "-" + Guid.NewGuid().ToString("N").Substring(0, 10) + ".xml");
            await File.WriteAllTextAsync(manifestFilePath, manifestContent, Encoding.UTF8, cancellationToken);

            yield return CreatedItem.CreateManifest(manifestFilePath);
        }