static byte[] PackDnaLibrary(byte[] dnaContent, string dnaDirectory, ResourceHelper.ResourceUpdater ru) { DnaLibrary dna = DnaLibrary.LoadFrom(dnaContent, dnaDirectory); if (dna == null) { // TODO: Better error handling here. Console.WriteLine(".dna file could not be loaded. Possibly malformed xml content? Aborting."); Environment.Exit(1); } if (dna.ExternalLibraries != null) { foreach (ExternalLibrary ext in dna.ExternalLibraries) { if (ext.Pack) { string path = dna.ResolvePath(ext.Path); Console.WriteLine(" ~~> ExternalLibrary path {0} resolved to {1}.", ext.Path, path); if (Path.GetExtension(path).Equals(".DNA", StringComparison.OrdinalIgnoreCase)) { string name = Path.GetFileNameWithoutExtension(path).ToUpperInvariant() + "_" + lastPackIndex++ + ".DNA"; byte[] dnaContentForPacking = PackDnaLibrary(File.ReadAllBytes(path), Path.GetDirectoryName(path), ru); ru.AddDnaFile(dnaContentForPacking, name); ext.Path = "packed:" + name; } else { string packedName = ru.AddAssembly(path); if (packedName != null) { ext.Path = "packed:" + packedName; } } if (ext.ComServer == true) { // Check for a TypeLib to pack //string tlbPath = dna.ResolvePath(ext.TypeLibPath); string resolvedTypeLibPath = null; if (!string.IsNullOrEmpty(ext.TypeLibPath)) { resolvedTypeLibPath = dna.ResolvePath(ext.TypeLibPath); // null is unresolved if (resolvedTypeLibPath == null) { // Try relative to .dll resolvedTypeLibPath = DnaLibrary.ResolvePath(ext.TypeLibPath, System.IO.Path.GetDirectoryName(path)); // null is unresolved if (resolvedTypeLibPath == null) { Console.WriteLine("!!! ExternalLibrary TypeLib path {0} could not be resolved.", ext.TypeLibPath); } } } else { // Check for .tlb string tlbCheck = System.IO.Path.ChangeExtension(path, "tlb"); if (System.IO.File.Exists(tlbCheck)) { resolvedTypeLibPath = tlbCheck; } } if (resolvedTypeLibPath != null) { Console.WriteLine(" ~~> ExternalLibrary typelib path {0} resolved to {1}.", ext.TypeLibPath, resolvedTypeLibPath); int packedIndex = ru.AddTypeLib(File.ReadAllBytes(resolvedTypeLibPath)); ext.TypeLibPath = "packed:" + packedIndex.ToString(); } } } } } // Collect the list of all the references. List <Reference> refs = new List <Reference>(); foreach (Project proj in dna.GetProjects()) { if (proj.References != null) { refs.AddRange(proj.References); } } // Fix-up if Reference is not part of a project, but just used to add an assembly for packing. foreach (Reference rf in dna.References) { if (!refs.Contains(rf)) { refs.Add(rf); } } // Now pack the references foreach (Reference rf in refs) { if (rf.Pack) { string path = null; if (rf.Path != null) { if (rf.Path.StartsWith("packed:")) { break; } path = dna.ResolvePath(rf.Path); Console.WriteLine(" ~~> Assembly path {0} resolved to {1}.", rf.Path, path); } if (path == null && rf.Name != null) { // Try Load as as last resort (and opportunity to load by FullName) try { #pragma warning disable 0618 Assembly ass = Assembly.LoadWithPartialName(rf.Name); #pragma warning restore 0618 if (ass != null) { path = ass.Location; Console.WriteLine(" ~~> Assembly {0} 'Load'ed from location {1}.", rf.Name, path); } } catch (Exception e) { Console.WriteLine(" ~~> Assembly {0} not 'Load'ed. Exception: {1}", rf.Name, e); } } if (path == null) { Console.WriteLine(" ~~> Reference with Path: {0} and Name: {1} not found.", rf.Path, rf.Name); break; } // It worked! string packedName = ru.AddAssembly(path); if (packedName != null) { rf.Path = "packed:" + packedName; } } } foreach (Image image in dna.Images) { if (image.Pack) { string path = dna.ResolvePath(image.Path); if (path == null) { Console.WriteLine(" ~~> Image path {0} not resolved.", image.Path); break; } string name = Path.GetFileNameWithoutExtension(path).ToUpperInvariant() + "_" + lastPackIndex++ + Path.GetExtension(path).ToUpperInvariant(); byte[] imageBytes = File.ReadAllBytes(path); ru.AddImage(imageBytes, name); image.Path = "packed:" + name; } } foreach (Project project in dna.Projects) { foreach (SourceItem source in project.SourceItems) { if (source.Pack && !string.IsNullOrEmpty(source.Path)) { string path = dna.ResolvePath(source.Path); if (path == null) { Console.WriteLine(" ~~> Source path {0} not resolved.", source.Path); break; } string name = Path.GetFileNameWithoutExtension(path).ToUpperInvariant() + "_" + lastPackIndex++ + Path.GetExtension(path).ToUpperInvariant(); byte[] sourceBytes = Encoding.UTF8.GetBytes(File.ReadAllText(path)); ru.AddSource(sourceBytes, name); source.Path = "packed:" + name; } } } return(DnaLibrary.Save(dna)); }
static byte[] PackDnaLibrary(byte[] dnaContent, string dnaDirectory, ResourceHelper.ResourceUpdater ru, bool compress, bool multithreading) { string errorMessage; DnaLibrary dna = DnaLibrary.LoadFrom(dnaContent, dnaDirectory); if (dna == null) { // TODO: Better error handling here. errorMessage = "ERROR: .dna file could not be loaded. Possibly malformed xml content? ABORTING."; throw new InvalidOperationException(errorMessage); } if (dna.ExternalLibraries != null) { bool copiedVersion = false; foreach (ExternalLibrary ext in dna.ExternalLibraries) { var path = dna.ResolvePath(ext.Path); if (!File.Exists(path)) { errorMessage = string.Format("!!! ERROR: ExternalLibrary `{0}` not found. ABORTING.", ext.Path); throw new InvalidOperationException(errorMessage); } if (ext.Pack) { Console.WriteLine(" ~~> ExternalLibrary path {0} resolved to {1}.", ext.Path, path); if (Path.GetExtension(path).Equals(".DNA", StringComparison.OrdinalIgnoreCase)) { string name = Path.GetFileNameWithoutExtension(path).ToUpperInvariant() + "_" + lastPackIndex++ + ".DNA"; byte[] dnaContentForPacking = PackDnaLibrary(File.ReadAllBytes(path), Path.GetDirectoryName(path), ru, compress, multithreading); ru.AddFile(dnaContentForPacking, name, ResourceHelper.TypeName.DNA, compress, multithreading); ext.Path = "packed:" + name; } else { string packedName = ru.AddAssembly(path, compress, multithreading, ext.IncludePdb); if (packedName != null) { ext.Path = "packed:" + packedName; } } if (ext.ComServer == true) { // Check for a TypeLib to pack //string tlbPath = dna.ResolvePath(ext.TypeLibPath); string resolvedTypeLibPath = null; if (!string.IsNullOrEmpty(ext.TypeLibPath)) { resolvedTypeLibPath = dna.ResolvePath(ext.TypeLibPath); // null is unresolved if (resolvedTypeLibPath == null) { // Try relative to .dll resolvedTypeLibPath = DnaLibrary.ResolvePath(ext.TypeLibPath, System.IO.Path.GetDirectoryName(path)); // null is unresolved if (resolvedTypeLibPath == null) { errorMessage = string.Format("!!! ERROR: ExternalLibrary TypeLib path {0} could not be resolved.", ext.TypeLibPath); throw new InvalidOperationException(errorMessage); } } } else { // Check for .tlb string tlbCheck = System.IO.Path.ChangeExtension(path, "tlb"); if (System.IO.File.Exists(tlbCheck)) { resolvedTypeLibPath = tlbCheck; } } if (resolvedTypeLibPath != null) { Console.WriteLine(" ~~> ExternalLibrary typelib path {0} resolved to {1}.", ext.TypeLibPath, resolvedTypeLibPath); int packedIndex = ru.AddTypeLib(File.ReadAllBytes(resolvedTypeLibPath)); ext.TypeLibPath = "packed:" + packedIndex.ToString(); } } } if (ext.UseVersionAsOutputVersion) { if (copiedVersion) { Console.WriteLine(" ~~> Assembly version already copied from previous ExternalLibrary; ignoring 'UseVersionAsOutputVersion' attribute."); continue; } try { ru.CopyFileVersion(path); copiedVersion = true; } catch (Exception e) { errorMessage = string.Format(" ~~> ERROR: Error copying version to output version: {0}", e.Message); throw new InvalidOperationException(errorMessage); } } } } // Collect the list of all the references. List <Reference> refs = new List <Reference>(); foreach (Project proj in dna.GetProjects()) { if (proj.References != null) { refs.AddRange(proj.References); } } // Fix-up if Reference is not part of a project, but just used to add an assembly for packing. foreach (Reference rf in dna.References) { if (!refs.Contains(rf)) { refs.Add(rf); } } // Expand asterisk in filename of reference path, e.g. "./*.dll" List <Reference> expandedReferences = new List <Reference>(); for (int i = refs.Count - 1; i >= 0; i--) { string path = refs[i].Path; if (path != null && path.Contains("*")) { var files = Directory.GetFiles(Path.GetDirectoryName(path), Path.GetFileName(path)); foreach (var file in files) { expandedReferences.Add(new Reference(Path.GetFullPath(file)) { Pack = true }); } refs.RemoveAt(i); } } refs.AddRange(expandedReferences); // Now pack the references foreach (Reference rf in refs) { if (rf.Pack) { string path = null; if (rf.Path != null) { if (rf.Path.StartsWith("packed:")) { continue; } path = dna.ResolvePath(rf.Path); Console.WriteLine(" ~~> Assembly path {0} resolved to {1}.", rf.Path, path); } if (path == null && rf.Name != null) { // Try Load as as last resort (and opportunity to load by FullName) try { #pragma warning disable 0618 Assembly ass = Assembly.LoadWithPartialName(rf.Name); #pragma warning restore 0618 if (ass != null) { path = ass.Location; Console.WriteLine(" ~~> Assembly {0} 'Load'ed from location {1}.", rf.Name, path); } } catch (Exception e) { Console.WriteLine(" ~~> Assembly {0} not 'Load'ed. Exception: {1}", rf.Name, e); } } if (path == null) { errorMessage = string.Format(" ~~> ERROR: Reference with Path: {0} and Name: {1} NOT FOUND.", rf.Path, rf.Name); throw new InvalidOperationException(errorMessage); } // It worked! string packedName = ru.AddAssembly(path, compress, multithreading, rf.IncludePdb); if (packedName != null) { rf.Path = "packed:" + packedName; } } } foreach (Image image in dna.Images) { if (image.Pack) { string path = dna.ResolvePath(image.Path); if (path == null) { errorMessage = string.Format(" ~~> ERROR: Image path {0} NOT RESOLVED.", image.Path); throw new InvalidOperationException(errorMessage); } string name = Path.GetFileNameWithoutExtension(path).ToUpperInvariant() + "_" + lastPackIndex++ + Path.GetExtension(path).ToUpperInvariant(); byte[] imageBytes = File.ReadAllBytes(path); ru.AddFile(imageBytes, name, ResourceHelper.TypeName.IMAGE, compress, multithreading); image.Path = "packed:" + name; } } foreach (Project project in dna.Projects) { foreach (SourceItem source in project.SourceItems) { if (source.Pack && !string.IsNullOrEmpty(source.Path)) { string path = dna.ResolvePath(source.Path); if (path == null) { errorMessage = string.Format(" ~~> ERROR: Source path {0} NOT RESOLVED.", source.Path); throw new InvalidOperationException(errorMessage); } string name = Path.GetFileNameWithoutExtension(path).ToUpperInvariant() + "_" + lastPackIndex++ + Path.GetExtension(path).ToUpperInvariant(); byte[] sourceBytes = File.ReadAllBytes(path); ru.AddFile(sourceBytes, name, ResourceHelper.TypeName.SOURCE, compress, multithreading); source.Path = "packed:" + name; } } } return(DnaLibrary.Save(dna)); }