public async Task PackFiles( string directory, string packagePath, AppxPackerOptions options = 0, CancellationToken cancellationToken = default, IProgress <ProgressData> progress = default) { var manifestFile = Path.Combine(directory, FileConstants.AppxManifestFile); if (!File.Exists(manifestFile)) { throw new FileNotFoundException("Manifest file has not been found.", manifestFile); } XDocument xmlDocument; await using (var stream = File.OpenRead(manifestFile)) { using var streamReader = new StreamReader(stream); xmlDocument = await XDocument.LoadAsync(streamReader, LoadOptions.None, cancellationToken).ConfigureAwait(false); } var injector = new MsixHeroBrandingInjector(); await injector.Inject(xmlDocument).ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested(); await File.WriteAllTextAsync(manifestFile, xmlDocument.ToString(), Encoding.UTF8, cancellationToken).ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested(); var compress = !options.HasFlag(AppxPackerOptions.NoCompress); var validate = !options.HasFlag(AppxPackerOptions.NoValidation); var allDirs = new DirectoryInfo(directory).EnumerateDirectories("*", SearchOption.AllDirectories); foreach (var emptyDir in allDirs.Where(d => !d.EnumerateFiles("*", SearchOption.TopDirectoryOnly).Any() && !d.EnumerateDirectories("*", SearchOption.TopDirectoryOnly).Any())) { // this means we have an empty folder, which requires some special handling await File.WriteAllBytesAsync(Path.Combine(emptyDir.FullName, "GeneratedFile.txt"), Array.Empty <byte>(), cancellationToken).ConfigureAwait(false); } await new MakeAppxWrapper().PackPackageDirectory(directory, packagePath, compress, validate, cancellationToken, progress).ConfigureAwait(false); }
public async Task Pack(string directory, string packagePath, AppxPackerOptions options = 0, CancellationToken cancellationToken = default, IProgress <ProgressData> progress = null) { if (!Directory.Exists(directory)) { throw new DirectoryNotFoundException($"Folder {directory} does not exist."); } var fileInfo = new FileInfo(packagePath); if (fileInfo.Directory == null) { throw new ArgumentException($"File path {packagePath} is not supported.", nameof(packagePath)); } if (!fileInfo.Directory.Exists) { fileInfo.Directory.Create(); } var tempFile = Path.GetTempFileName(); var tempManifest = Path.GetTempFileName(); var tempAutoGenerated = Path.GetTempFileName(); try { var inputDirectory = new DirectoryInfo(directory); var stringBuilder = new StringBuilder(); stringBuilder.AppendLine("[Files]"); foreach (var item in inputDirectory.EnumerateFiles("*", SearchOption.AllDirectories)) { cancellationToken.ThrowIfCancellationRequested(); var relativePath = Path.GetRelativePath(directory, item.FullName); if (string.IsNullOrEmpty(relativePath)) { continue; } // ReSharper disable once ConvertIfStatementToConditionalTernaryExpression if (string.Equals(FileConstants.AppxManifestFile, relativePath, StringComparison.OrdinalIgnoreCase)) { stringBuilder.AppendLine($"\"{tempManifest}\"\t\"{relativePath}\""); item.CopyTo(tempManifest, true); continue; } if ( string.Equals("AppxBlockMap.xml", relativePath, StringComparison.OrdinalIgnoreCase) || string.Equals("AppxSignature.p7x", relativePath, StringComparison.OrdinalIgnoreCase)) { continue; } stringBuilder.AppendLine($"\"{item.FullName}\"\t\"{relativePath}\""); } var allDirs = inputDirectory.EnumerateDirectories("*", SearchOption.AllDirectories); foreach (var emptyDir in allDirs.Where(d => !d.EnumerateFiles("*", SearchOption.TopDirectoryOnly).Any() && !d.EnumerateDirectories("*", SearchOption.TopDirectoryOnly).Any())) { // this means we have an empty folder, which requires some special handling if (new FileInfo(tempAutoGenerated).Length == 0) { await File.WriteAllBytesAsync(tempAutoGenerated, new byte[0], cancellationToken).ConfigureAwait(false); } var relativePath = Path.GetRelativePath(inputDirectory.FullName, emptyDir.FullName); stringBuilder.AppendLine($"\"{tempAutoGenerated}\"\t\"{relativePath}\\GeneratedFile.txt\""); } await File.WriteAllTextAsync(tempFile, stringBuilder.ToString(), Encoding.UTF8, cancellationToken).ConfigureAwait(false); var xmlDocument = XDocument.Load(tempManifest); var injector = new MsixHeroBrandingInjector(); injector.Inject(xmlDocument); cancellationToken.ThrowIfCancellationRequested(); await File.WriteAllTextAsync(tempManifest, xmlDocument.ToString(), Encoding.UTF8, cancellationToken).ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested(); var compress = !options.HasFlag(AppxPackerOptions.NoCompress); var validate = !options.HasFlag(AppxPackerOptions.NoValidation); await new MsixSdkWrapper().PackPackageFiles(tempFile, packagePath, compress, validate, cancellationToken, progress).ConfigureAwait(false); } finally { if (File.Exists(tempFile)) { File.Delete(tempFile); } if (File.Exists(tempManifest)) { File.Delete(tempManifest); } if (File.Exists(tempAutoGenerated)) { File.Delete(tempAutoGenerated); } } }
public async Task Pack( string directory, string packagePath, IDictionary <string, string> extraFiles, AppxPackerOptions options = 0, CancellationToken cancellationToken = default, IProgress <ProgressData> progress = null) { if (!Directory.Exists(directory)) { throw new DirectoryNotFoundException($"Folder {directory} does not exist."); } var fileInfo = new FileInfo(packagePath); if (fileInfo.Directory == null) { throw new ArgumentException($"File path {packagePath} is not supported.", nameof(packagePath)); } if (!fileInfo.Directory.Exists) { fileInfo.Directory.Create(); } var tempFile = Path.GetTempFileName(); var tempManifestFilePath = Path.GetTempFileName(); var tempAutoGenerated = Path.GetTempFileName(); try { var inputDirectory = new DirectoryInfo(directory); var listBuilder = new PackageFileListBuilder(); foreach (var item in inputDirectory.EnumerateFiles("*", SearchOption.AllDirectories)) { cancellationToken.ThrowIfCancellationRequested(); var relativePath = Path.GetRelativePath(directory, item.FullName); if (string.IsNullOrEmpty(relativePath)) { continue; } // ReSharper disable once ConvertIfStatementToConditionalTernaryExpression if (string.Equals(FileConstants.AppxManifestFile, relativePath, StringComparison.OrdinalIgnoreCase)) { listBuilder.AddManifest(tempManifestFilePath); item.CopyTo(tempManifestFilePath, true); continue; } listBuilder.AddFile(item.FullName, relativePath); } if (extraFiles != null) { foreach (var item in extraFiles) { cancellationToken.ThrowIfCancellationRequested(); if (string.Equals(Path.GetFileName(item.Key), FileConstants.AppxManifestFile, StringComparison.OrdinalIgnoreCase)) { tempManifestFilePath = item.Value; listBuilder.AddFile(item.Value, item.Key); } else { listBuilder.AddFile(item.Value, item.Key); } } } var allDirs = inputDirectory.EnumerateDirectories("*", SearchOption.AllDirectories); foreach (var emptyDir in allDirs.Where(d => !d.EnumerateFiles("*", SearchOption.TopDirectoryOnly).Any() && !d.EnumerateDirectories("*", SearchOption.TopDirectoryOnly).Any())) { // this means we have an empty folder, which requires some special handling if (new FileInfo(tempAutoGenerated).Length == 0) { await File.WriteAllBytesAsync(tempAutoGenerated, Array.Empty <byte>(), cancellationToken).ConfigureAwait(false); } var relativePath = Path.GetRelativePath(inputDirectory.FullName, emptyDir.FullName); listBuilder.AddFile(tempAutoGenerated, $"{relativePath}\\GeneratedFile.txt\""); } await File.WriteAllTextAsync(tempFile, listBuilder.ToString(), Encoding.UTF8, cancellationToken).ConfigureAwait(false); XDocument xmlManifestDocument; await using (var tempManifestStream = File.OpenRead(tempManifestFilePath)) { using var tempManifestReader = new StreamReader(tempManifestStream); xmlManifestDocument = await XDocument.LoadAsync(tempManifestReader, LoadOptions.None, cancellationToken).ConfigureAwait(false); var injector = new MsixHeroBrandingInjector(); await injector.Inject(xmlManifestDocument).ConfigureAwait(false); } cancellationToken.ThrowIfCancellationRequested(); var appxWriter = new AppxDocumentWriter(xmlManifestDocument); await appxWriter.WriteAsync(tempManifestFilePath).ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested(); var compress = !options.HasFlag(AppxPackerOptions.NoCompress); var validate = !options.HasFlag(AppxPackerOptions.NoValidation); await new MakeAppxWrapper().PackPackageFiles(tempFile, packagePath, compress, validate, cancellationToken, progress).ConfigureAwait(false); } finally { if (File.Exists(tempFile)) { File.Delete(tempFile); } if (File.Exists(tempManifestFilePath)) { File.Delete(tempManifestFilePath); } if (File.Exists(tempAutoGenerated)) { File.Delete(tempAutoGenerated); } } }