2

I need to get either the whole IL Code or Decompiled Source Code to a text file. Is that possible with the ILSpy Decompile Engine ICSharpCode.Decompiler?

Rosen Petrov
  • 183
  • 1
  • 9
  • 1
    Have you tried dotpeek? https://www.jetbrains.com/decompiler/ – cccmir Jul 04 '19 at 19:10
  • 2
    Maybe microsofts ilasm and ildasm can help you, they can roundtrip il as text and assembly as binary together. You can see an example here: https://stackoverflow.com/a/52023423 – thehennyy Jul 04 '19 at 19:17
  • Yeah, I've looked into ildasm but I am not sure if the ildasm version should somehow be corresponding to the framework version or not. I have multiple versions of ildasm on my machine. Also, I have to 'carry' the ildasm exe along with my C# implementation which adds some complexity. It just looked like that it would be much smarter with ICSharpCode. Decompiler because it comes as a Nuget package. I need to do the decompilation in a custom C# application. The root reason is because I want to compare if two DLLs are equal or not.. when versioning is not applied.. – Rosen Petrov Jul 04 '19 at 20:33
  • I guess you can use https://github.com/icsharpcode/ILSpy/tree/master/ICSharpCode.Decompiler.Console as inspiration ? (my bet is that it uses the decompiler) – Vagaus Jul 05 '19 at 15:48

1 Answers1

5

With ILSpy, you can select an assembly node in the tree view, and then use File > Save Code to save the result to disk. ILSpy will use the currently selected language to do so, so it can both disassemble and decompile. When decompiling to C#, the save dialog will have options for saving a C# project (.csproj) with separate source code files per class; or a single C# file (.cs) for the whole assembly.


To decompile programmatically, use the ICSharpCode.Decompiler library (available on NuGet). E.g. decompile whole assembly to a string:

var decompiler = new CSharpDecompiler(assemblyFileName, new DecompilerSettings());
string code = decompiler.DecompileWholeModuleAsString();

See the ICSharpCode.Decompiler.Console project for slightly more advanced usage of the decompiler API. The part with resolver.AddSearchDirectory(path); in that console project may be relevant, because the decompiler needs to find the referenced assemblies.


The ICSharpCode.Decompiler library also has a disassembler API (which is a bit more low-level):

string code;
using (var peFileStream = new FileStream(sourceFileName, FileMode.Open, FileAccess.Read))
using (var peFile = new PEFile(sourceFileName, peFileStream))
using (var writer = new StringWriter()) {
    var output = new PlainTextOutput(writer);
    ReflectionDisassembler rd = new ReflectionDisassembler(output, CancellationToken.None);
    rd.DetectControlStructure = false;
    rd.WriteAssemblyReferences(peFile.Metadata);
    if (metadata.IsAssembly)
        rd.WriteAssemblyHeader(peFile);
    output.WriteLine();
    rd.WriteModuleHeader(peFile);
    output.WriteLine();
    rd.WriteModuleContents(peFile);

    code = writer.ToString();
}
Daniel
  • 15,944
  • 2
  • 54
  • 60