From 943d47dcfae62e8d1baa450ccf6f3cfe975c8509 Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Wed, 23 Feb 2011 19:38:34 +0100 Subject: [PATCH] Export embedded resources when exporting a project. --- ILSpy/CSharpLanguage.cs | 54 ++++++++++++++++++++++++++++++++--------- 1 file changed, 43 insertions(+), 11 deletions(-) diff --git a/ILSpy/CSharpLanguage.cs b/ILSpy/CSharpLanguage.cs index ca17d220c..8502d4a85 100644 --- a/ILSpy/CSharpLanguage.cs +++ b/ILSpy/CSharpLanguage.cs @@ -115,7 +115,9 @@ namespace ICSharpCode.ILSpy { if (options.FullDecompilation) { if (options.SaveAsProjectDirectory != null) { - var files = WriteFilesInProject(assembly, options); + HashSet directories = new HashSet(StringComparer.OrdinalIgnoreCase); + var files = WriteCodeFilesInProject(assembly, options, directories).ToList(); + files.AddRange(WriteResourceFilesInProject(assembly, options, directories)); WriteProjectFile(new TextOutputWriter(output), files, assembly.MainModule); } else { foreach (TypeDefinition type in assembly.MainModule.Types) { @@ -130,7 +132,8 @@ namespace ICSharpCode.ILSpy } } - void WriteProjectFile(TextWriter writer, IEnumerable files, ModuleDefinition module) + #region WriteProjectFile + void WriteProjectFile(TextWriter writer, IEnumerable> files, ModuleDefinition module) { const string ns = "http://schemas.microsoft.com/developer/msbuild/2003"; string platformName; @@ -236,13 +239,15 @@ namespace ICSharpCode.ILSpy } w.WriteEndElement(); // (References) - w.WriteStartElement("ItemGroup"); // Code - foreach (string file in files.OrderBy(f => f, StringComparer.OrdinalIgnoreCase)) { - w.WriteStartElement("Compile"); - w.WriteAttributeString("Include", file); + foreach (IGrouping gr in (from f in files group f.Item2 by f.Item1 into g orderby g.Key select g)) { + w.WriteStartElement("ItemGroup"); + foreach (string file in gr.OrderBy(f => f, StringComparer.OrdinalIgnoreCase)) { + w.WriteStartElement(gr.Key); + w.WriteAttributeString("Include", file); + w.WriteEndElement(); + } w.WriteEndElement(); } - w.WriteEndElement(); w.WriteStartElement("Import"); w.WriteAttributeString("Project", "$(MSBuildToolsPath)\\Microsoft.CSharp.targets"); @@ -251,8 +256,10 @@ namespace ICSharpCode.ILSpy w.WriteEndDocument(); } } + #endregion - IEnumerable WriteFilesInProject(AssemblyDefinition assembly, DecompilationOptions options) + #region WriteCodeFilesInProject + IEnumerable> WriteCodeFilesInProject(AssemblyDefinition assembly, DecompilationOptions options, HashSet directories) { var files = assembly.MainModule.Types.Where(t => t.Name != "").GroupBy( delegate (TypeDefinition type) { @@ -261,11 +268,11 @@ namespace ICSharpCode.ILSpy return file; } else { string dir = TextView.DecompilerTextView.CleanUpName(type.Namespace); - Directory.CreateDirectory(Path.Combine(options.SaveAsProjectDirectory, dir)); + if (directories.Add(dir)) + Directory.CreateDirectory(Path.Combine(options.SaveAsProjectDirectory, dir)); return Path.Combine(dir, file); } }, StringComparer.OrdinalIgnoreCase).ToList(); - AstMethodBodyBuilder.ClearUnhandledOpcodes(); Parallel.ForEach( files, @@ -279,8 +286,33 @@ namespace ICSharpCode.ILSpy } }); AstMethodBodyBuilder.PrintNumberOfUnhandledOpcodes(); - return files.Select(f => f.Key); + return files.Select(f => Tuple.Create("Compile", f.Key)); + } + #endregion + + #region WriteResourceFilesInProject + IEnumerable> WriteResourceFilesInProject(AssemblyDefinition assembly, DecompilationOptions options, HashSet directories) + { + foreach (EmbeddedResource r in assembly.MainModule.Resources.OfType()) { + string[] splitName = r.Name.Split('.'); + string fileName = TextView.DecompilerTextView.CleanUpName(r.Name); + for (int i = splitName.Length - 1; i > 0; i--) { + string ns = string.Join(".", splitName, 0, i); + if (directories.Contains(ns)) { + string name = string.Join(".", splitName, i, splitName.Length - i); + fileName = Path.Combine(ns, TextView.DecompilerTextView.CleanUpName(name)); + break; + } + } + Stream s = r.GetResourceStream(); + s.Position = 0; + using (FileStream fs = new FileStream(Path.Combine(options.SaveAsProjectDirectory, fileName), FileMode.Create, FileAccess.Write)) { + s.CopyTo(fs); + } + yield return Tuple.Create("EmbeddedResource", fileName); + } } + #endregion AstBuilder CreateAstBuilder(DecompilationOptions options, TypeDefinition currentType) {