/// <summary> /// Recupera o enumerador dos itens. /// </summary> /// <returns></returns> private IEnumerator <AssemblyPackageDownloaderResult.Item> GetEnumeratorInternal() { if (_zipArchive == null) { _zipArchive = new IO.Compression.ZipArchive(_stream, System.IO.FileAccess.Read); } foreach (var file in _zipArchive.Files) { Guid uid = Guid.Empty; try { var name = System.IO.Path.GetFileNameWithoutExtension(file.Name); uid = Guid.Parse(name); } catch { continue; } var item = _items.Find(f => f.Uid == uid); if (item == null) { item = new Item(uid, file.LastWriteTime, file.OpenRead()); _items.Add(item); } yield return(item); } }
/// <summary> /// Construtor padrão. /// </summary> /// <param name="appDomain"></param> /// <param name="assemblies"></param> /// <param name="deploymentParts"></param> /// <param name="zipArchive"></param> /// <param name="packageDirectory"></param> public LoadPackageAssemblyResolver(AppDomain appDomain, Dictionary <string, System.Reflection.Assembly> assemblies, IEnumerable <AssemblyPart> deploymentParts, IO.Compression.ZipArchive zipArchive, string packageDirectory) { _appDomain = appDomain; _assemblies = assemblies; _deploymentParts = deploymentParts; _zipArchive = zipArchive; _packageDirectory = packageDirectory; }
/// <summary> /// Libera a instancia /// </summary> /// <param name="disposing"></param> protected virtual void Dispose(bool disposing) { if (_stream != null) { _stream.Dispose(); _stream = null; } if (_zipArchive != null) { _zipArchive.Dispose(); _zipArchive = null; } foreach (var i in _items) { i.Dispose(); } _items.Clear(); }
/// <summary> /// Recupera a stream do assembly. /// </summary> /// <param name="packageStream">Stream do pacote.</param> /// <param name="assemblyStream">Stream onde será salvos os dados do assembly.</param> /// <param name="part">Part com as informações do assembly.</param> /// <return>True caso o assembly tenha sido carregado.</return> public static bool GetAssembly(System.IO.Stream packageStream, System.IO.Stream assemblyStream, AssemblyPart part) { using (var zipArchive = new IO.Compression.ZipArchive(packageStream, System.IO.FileAccess.Read)) { foreach (var i in zipArchive.Files) { if (i.Name == part.Source) { using (var stream = i.OpenRead()) { var buffer = new byte[1024]; var read = 0; while ((read = stream.Read(buffer, 0, buffer.Length)) > 0) { assemblyStream.Write(buffer, 0, read); } } return(true); } } } return(false); }
/// <summary> /// Recupera as partes de implementação contidas na stream do pacote informado. /// </summary> /// <param name="packageStream"></param> /// <returns></returns> public static IEnumerable <AssemblyPart> GetDeploymentParts(System.IO.Stream packageStream) { using (var zipArchive = new IO.Compression.ZipArchive(packageStream, System.IO.FileAccess.Read)) return(GetDeploymentParts(zipArchive)); }
/// <summary> /// Extraí dos assemblies do pacote. /// </summary> /// <param name="packageStream">Stream do pacote.</param> /// <param name="outputDirectory">Diretório de saída dos arquivos do pacote.</param> /// <param name="canOverride">Identifica se pode sobreescreve os arquivos existentes.</param> public static void ExtractPackageAssemblies(System.IO.Stream packageStream, string outputDirectory, bool canOverride = false) { packageStream.Require("packageStream").NotNull(); using (var zipArchive = new IO.Compression.ZipArchive(packageStream, System.IO.FileAccess.Read)) zipArchive.CopyToDirectory("", outputDirectory, canOverride); }
/// <summary> /// Recupera os assemblies contidos na stream informada. /// </summary> /// <param name="resolverManager"></param> /// <param name="assemblyRepositoryDirectory"></param> /// <param name="packageUid">Identificador do pacote.</param> /// <param name="packageStream"></param> /// <param name="canOverride">Identifica se é para sobreescreve os arquivos.</param> /// <param name="aggregateException"></param> /// <returns></returns> public static IEnumerable <System.Reflection.Assembly> LoadPackagedAssemblies(AssemblyResolverManager resolverManager, string assemblyRepositoryDirectory, Guid packageUid, System.IO.Stream packageStream, bool canOverride, out AggregateException aggregateException) { resolverManager.Require("resolverManager").NotNull(); packageStream.Require("packageStream").NotNull(); var exceptions = new List <Exception>(); Dictionary <string, System.Reflection.Assembly> domainAssemblies = new Dictionary <string, System.Reflection.Assembly>(StringComparer.InvariantCultureIgnoreCase); foreach (var i in resolverManager.AppDomain.GetAssemblies()) { var key = string.Format("{0}.dll", i.GetName().Name); if (!domainAssemblies.ContainsKey(key)) { domainAssemblies.Add(key, i); } else { domainAssemblies[key] = i; } } string packageDirectory = null; if (!string.IsNullOrEmpty(assemblyRepositoryDirectory)) { packageDirectory = System.IO.Path.Combine(assemblyRepositoryDirectory, packageUid.ToString()); if (!System.IO.Directory.Exists(packageDirectory)) { System.IO.Directory.CreateDirectory(packageDirectory); } } using (var zipArchive = new IO.Compression.ZipArchive(packageStream, System.IO.FileAccess.Read)) { if (packageDirectory != null) { zipArchive.CopyToDirectory("", packageDirectory, canOverride); } var list = new List <System.Reflection.Assembly>(); IEnumerable <AssemblyPart> deploymentParts = GetDeploymentParts(zipArchive); var resolver = new LoadPackageAssemblyResolver(resolverManager.AppDomain, domainAssemblies, deploymentParts, zipArchive, packageDirectory); resolverManager.Add(resolver); try { foreach (AssemblyPart part in deploymentParts) { System.Reflection.Assembly assembly = null; if (!domainAssemblies.TryGetValue(part.Source, out assembly)) { if (packageDirectory == null) { var fileInfo = zipArchive.Files.Where(f => f.Name == part.Source).FirstOrDefault(); var raw = new byte[fileInfo.Length]; using (var file = zipArchive.OpenRead(part.Source)) file.Read(raw, 0, raw.Length); try { assembly = part.Load(resolverManager.AppDomain, raw); } catch (Exception ex) { exceptions.Add(ex); continue; } } else { try { assembly = part.Load(resolverManager.AppDomain, System.IO.Path.Combine(packageDirectory, part.Source)); } catch (Exception ex) { exceptions.Add(ex); continue; } try { assembly.GetTypes(); } catch (System.Reflection.ReflectionTypeLoadException ex) { exceptions.Add(new System.Reflection.ReflectionTypeLoadException(ex.Types, ex.LoaderExceptions, string.Format("An error ocurred when load types from assembly '{0}'", assembly.FullName))); continue; } catch (Exception ex) { exceptions.Add(new Exception(string.Format("An error ocurred when load types from assembly '{0}'", assembly.FullName), ex)); continue; } } if (!domainAssemblies.ContainsKey(part.Source)) { domainAssemblies.Add(part.Source, assembly); } } list.Add(assembly); } } finally { resolverManager.Remove(resolver); } if (exceptions.Count > 0) { aggregateException = new AggregateException(exceptions); } else { aggregateException = null; } return(list); } }