Recovering Lost Source Code
Sometimes the source code is gone. The repository was deleted, the developer left, the backup failed. If you still have the compiled .dll or .exe, mcilspy can reconstruct C# source that is often close to the original.
The Recovery Workflow
Section titled “The Recovery Workflow”-
Assess the assembly
Start with
get_assembly_infoto check the target framework and whether debug information exists:"Get assembly info for LegacyApp.dll"If
has_debug_infois true, a PDB file may be alongside the assembly. This significantly improves output quality. -
Generate a project structure
Use
decompile_assemblywithcreate_projectto produce a.csprojfile and organized source files:"Decompile LegacyApp.dll into a project structure at ./recovered-source"The
create_projectflag tells ILSpy to generate a buildable project rather than a single concatenated output. Combined withnested_directories, source files are organized into namespace-based folder hierarchies. -
Enable PDB generation
Set
generate_pdbto produce a portable PDB file alongside the decompiled source. This lets you attach a debugger to the decompiled code:"Decompile LegacyApp.dll to ./recovered with create_project, generate_pdb, and nested_directories enabled" -
Recover original variable names
If the assembly ships with its original PDB (or an embedded portable PDB), enable
use_pdb_variable_namesto replace ILSpy’s generated names (num,text,flag) with the originals:"Decompile with use_pdb_variable_names enabled"Without this flag, local variables get generic names based on their types. With it, you get
connectionTimeoutinstead ofnum2. -
Build and fix
The decompiled project usually needs minor adjustments before it compiles. Common issues include missing NuGet package references, unresolved
externmethods, and resource files that need regenerating. But the structural recovery is typically complete.
Choosing a Language Version
Section titled “Choosing a Language Version”ILSpy decompiles using modern C# syntax by default (Latest). If the original code targeted an older framework, you may want to match the language version for authenticity:
| Original Framework | Suggested Version |
|---|---|
| .NET Framework 2.0-3.5 | CSharp3 |
| .NET Framework 4.0 | CSharp4 |
| .NET Framework 4.5 | CSharp5 |
| .NET Framework 4.6+ | CSharp6 or CSharp7 |
| .NET Core 3.x | CSharp8_0 |
| .NET 5-6 | CSharp9_0 or CSharp10_0 |
| .NET 7-8 | CSharp11_0 or CSharp12_0 |
Pass the version via the language_version parameter on decompile_assembly.
Cleaning Up the Output
Section titled “Cleaning Up the Output”ILSpy produces clean output, but two optional flags can tighten it further:
remove_dead_codestrips unreachable code paths that the compiler left in the IL. This is common with debug builds.remove_dead_storesremoves variable assignments whose values are never read.
Both flags are safe for source recovery — they remove only provably unreachable code.
Single-Type Recovery
Section titled “Single-Type Recovery”If you only need one class, skip the project generation and decompile just that type:
"Decompile the MyApp.Data.CustomerRepository class from LegacyApp.dll"This returns the C# source for that single type, which you can paste directly into a new project.