Search code examples
c#decompilingcildecompilerilspy

How to use ICSharpCode.Decompiler to decompile a whole assembly to a text file?


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?


Solution

  • 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();
    }