public static bool GetSatelliteFiles(Stream packageStream, PackageIdentity packageIdentity, PackagePathResolver packagePathResolver, out string language, out string runtimePackageDirectory, out IEnumerable <ZipArchiveEntry> satelliteFiles) { var zipArchive = new ZipArchive(packageStream); var packageReader = new PackageReader(zipArchive); var nuspecReader = new NuspecReader(packageReader.GetNuspec()); PackageIdentity runtimePackageIdentity = null; string packageLanguage = null; if (PackageHelper.IsSatellitePackage(nuspecReader, out runtimePackageIdentity, out packageLanguage)) { // Now, we know that the package is a satellite package and that the runtime package is 'runtimePackageId' // Check, if the runtimePackage is installed and get the folder to copy over files string runtimePackageFilePath = packagePathResolver.GetInstalledPackageFilePath(runtimePackageIdentity); if (File.Exists(runtimePackageFilePath)) { runtimePackageDirectory = Path.GetDirectoryName(runtimePackageFilePath); // Existence of the package file is the validation that the package exists var libItemGroups = packageReader.GetLibItems(); List <ZipArchiveEntry> satelliteFileEntries = new List <ZipArchiveEntry>(); foreach (var libItemGroup in libItemGroups) { var satelliteFilesInGroup = libItemGroup.Items.Where(item => Path.GetDirectoryName(item).Split(Path.DirectorySeparatorChar) .Contains(packageLanguage, StringComparer.OrdinalIgnoreCase)); foreach (var satelliteFile in satelliteFilesInGroup) { var zipArchiveEntry = zipArchive.GetEntry(satelliteFile); if (zipArchiveEntry != null) { satelliteFileEntries.Add(zipArchiveEntry); } } } if (satelliteFileEntries.Count > 0) { language = packageLanguage; satelliteFiles = satelliteFileEntries; return(true); } } } language = null; runtimePackageDirectory = null; satelliteFiles = null; return(false); }
public static async Task <IEnumerable <string> > ExtractPackageAsync( PackageReaderBase packageReader, Stream packageStream, PackageIdentity packageIdentity, PackagePathResolver packagePathResolver, PackageExtractionContext packageExtractionContext, PackageSaveModes packageSaveMode, CancellationToken token) { if (packageStream == null) { throw new ArgumentNullException(nameof(packageStream)); } if (packageIdentity == null) { throw new ArgumentNullException(nameof(packageIdentity)); } if (packagePathResolver == null) { throw new ArgumentNullException(nameof(packagePathResolver)); } // TODO: Need to handle PackageSaveMode // TODO: Support overwriting files also? var filesAdded = new List <string>(); var nuspecReader = new NuspecReader(packageReader.GetNuspec()); packageIdentity = nuspecReader.GetIdentity(); var packageDirectoryInfo = Directory.CreateDirectory(packagePathResolver.GetInstallPath(packageIdentity)); var packageDirectory = packageDirectoryInfo.FullName; foreach (var file in packageReader.GetFiles().Where(file => PackageHelper.IsPackageFile(file, packageSaveMode))) { token.ThrowIfCancellationRequested(); var targetPath = Path.Combine(packageDirectory, file); Directory.CreateDirectory(Path.GetDirectoryName(targetPath)); using (var sourceStream = packageReader.GetStream(file)) { using (var targetStream = new FileStream(targetPath, FileMode.Create, FileAccess.Write, FileShare.None, bufferSize: 1024, useAsync: true)) { await sourceStream.CopyToAsync(targetStream); } } filesAdded.Add(file); } var nupkgFilePath = Path.Combine(packageDirectory, packagePathResolver.GetPackageFileName(packageIdentity)); if (packageSaveMode.HasFlag(PackageSaveModes.Nupkg)) { // During package extraction, nupkg is the last file to be created // Since all the packages are already created, the package stream is likely positioned at its end // Reset it if (packageStream.Position != 0) { if (!packageStream.CanSeek) { throw new ArgumentException(Strings.PackageStreamShouldBeSeekable); } packageStream.Position = 0; } filesAdded.Add(await PackageHelper.CreatePackageFile(nupkgFilePath, packageStream, token)); } // Now, copy satellite files unless requested to not copy them if (packageExtractionContext == null || packageExtractionContext.CopySatelliteFiles) { PackageIdentity runtimeIdentity; string packageLanguage; var isSatellitePackage = PackageHelper.IsSatellitePackage(nuspecReader, out runtimeIdentity, out packageLanguage); // Short-circuit this if the package is not a satellite package. if (isSatellitePackage) { filesAdded.AddRange(await CopySatelliteFilesAsync(packageIdentity, packagePathResolver, packageSaveMode, token)); } } return(filesAdded); }