The GUI has the metadata-tables view; the CLI had nothing, so checking
e.g. which MethodSemantics rows reference a Property row required a
hand-written System.Reflection.Metadata script. --dump-table <name>
prints every row of a table (RID, token, resolved names, heap offsets,
coded indexes) as an aligned text table, or as JSON with --json, for
the same 39 Cor tables the GUI shows.
Row enumeration for tables without public SRM row access lives in
MetadataExtensions next to the existing GetMethodSemantics helper, so
the GUI's raw-reading table nodes can be folded onto the shared
readers later. Every table's columns are spelled out explicitly in
ECMA-335 declaration order: reflecting over the SRM row structs would
tie the output (and its column order) to runtime internals, and
deterministic output is the point of the feature. JSON uses
System.Text.Json from the shared framework, so no new package
reference is needed.
Assisted-by: Claude:claude-fable-5:Claude Code
Decompiling one method or property previously required decompiling its
whole type and searching the output, which is wasteful for scripted and
agent-driven use against large assemblies. The new -m|--member option
accepts an XML documentation id string (the syntax of compiler-generated
documentation files and of the UI's --navigateto option) or a metadata
token in 0x06000005 form, resolves it against the main module (with a
bounds check for tokens and distinct error messages for malformed ids,
unknown members, and members of other modules), and prints just that
member through the engine's single-member decompilation path.
The tests seed a new ICSharpCode.ILSpyCmd.Tests project (part of the
XPlat and Desktop solution filters and of the per-project CI test
steps), driving the real Main in-process via InternalsVisibleTo, so
future ilspycmd features have a dedicated home for CLI tests.
Assisted-by: Claude:claude-fable-5:Claude Code
Backfills the standard MIT X11 header on hand-written files that never
got one, attributing each to its first-commit author and year from git
history. Code vendored from dotnet/runtime and Humanizr/Humanizer gets
its origin's license lines and a provenance note instead. Generated
files (Resources.Designer.cs, the version-info template), tool-managed
suppression files, and BAML test-case fixtures intentionally stay
header-less.
Assisted-by: Claude:claude-fable-5:Claude Code
--list-* printed generic types without their `n arity suffix, yet -t only
accepted the exact reflection name, so a name copied straight from the listing
threw "Could not find type definition". The listing now prints the reflection
name, and -t resolves through a ladder of progressively looser, uniqueness-
checked rules: the engine's exact lookup, an arity- and nesting-separator-
insensitive FullName match, a case-insensitive match, a namespace-less simple
name, and a trailing segment path ("Dictionary.KeyCollection"). The input is
parsed with System.Reflection.Metadata.TypeName and reduced to its underlying
definition first, so assembly qualification, generic arguments, and
array/pointer/byref decorations cannot corrupt the comparison key. An ambiguous
name reports its candidates instead of guessing, and a miss prints name
suggestions and returns EX_DATAERR rather than dumping a stack trace.
Assisted-by: Claude:claude-opus-4-8:Claude Code
The portable-PDB writer carried its knobs (no-logo, pdb id, progress,
progress title) as a growing list of optional WritePdb parameters.
Turn the type into a configured instance whose options are properties,
and add EmbedSourceFiles (default true): when a PDB is generated next
to a project export whose .cs are already on disk, embedding the source
again is redundant, so the caller can turn it off. The per-document
checksum/hash is computed either way, so documents still resolve.
Assisted-by: Claude:claude-opus-4-8:Claude Code
stdout is the data channel: --resource may be writing a binary payload to
it. Update-check notices on stdout would tail-append to the binary stream
and corrupt extracted files. Move them to stderr (npm/cargo/pip
convention) so meta-output stays out of the data path.
--list-resources prints every leaf in the assembly's embedded
resources (including individual entries inside .resources containers).
--resource <name> extracts a single leaf. Names ending in .baml are
decompiled to XAML; everything else is emitted as raw bytes. Without
-o, BAML goes to stdout as text and binary leaves go to the binary
stdout stream. Unknown names exit with EX_DATAERR and print the
available leaves to stderr.
--decompile-baml is a modifier for -p that swaps in the new
BamlAwareWholeProjectDecompiler so .baml entries become .xaml Page
items in the generated project. Default -p behaviour is unchanged.
* Support batch PDB generation.
* Use `FileMode.Create` for output PDB files to ensure existing files are fully overwritten/truncated.
* Localize the string `Generating portable PDB...`.
* Refine `GeneratePdbForAssemblies` implementation.
* Replace direct calls to `explorer.exe` with the Shell API to prevent spawning an `explorer.exe` process that doesn't exit automatically on every call.
* Batch calls to `ShellHelper.OpenFolderAndSelectItems` instead of looping `OpenFolderAndSelectItem`.
* Localize the string `Open Explorer`.
* Fix `OpenCmdHere` malfunction when ILSpy is running from a different drive than the OS.
* Refine `GeneratePdbForAssemblies` implementation.
* Replace WinForms `FolderBrowserDialog` with WPF `OpenFolderDialog`.
* Add license header
* Exclude duplicate entries entered by the user within `OpenFolderAndSelectItems`.
* Explicitly declare that `ShellHelper.cs` is a module that allows Pinvoke.
* Use `FileMode.Create` for output PDB files to ensure existing files are fully overwritten/truncated.
* Show original filenames when generating PDBs to improve UX during batch processing.
* added mermaid class diagrammer
contributed from https://github.com/h0lg/netAmermaid - find earlier git history there
* reading from embedded resource instead of file
* swapped out icon to brand diagrammers as an ILSpy product
reusing linked ..\ILSpy\Images\ILSpy.ico from UI project
* added required ilspycmd options and routed call
* adjusted VS Code task to generate model.json required by the JS/CSS/HTML dev loop
* added debug launchSettings
* updated help command output
* using ILSpyX build info in generated diagrammers
removing unused code
* using explicit type where it's not obvious
* outputting in to a folder next to and named after the input assembly + " diagrammer" by default
* renamed diagrammer output to index.html
to support default web server configs in the wild
* improved instructions for creating an off-line diagrammer
* added developer-facing doco for how to edit the HTML/JS/CSS parts
* renamed to remove netAmermaid branding
* updated repo URL and doco link to new Wiki page
* copied over doco
* removed obsolete parts
* moved CLI doco into ILSpyCmd README
* removed end-user facing chapters that go into the Wiki from dev-facing doco
* updated to ilspycmd API and rebranded to ILSpy
* removed doco that's now in https://github.com/icsharpcode/ILSpy/wiki/Diagramming
* added tasks
When disassembling IL add a flag to enable showing sequence points. We
can already specify PDB loading; take advantage of that to provide
debug information for the decompiler.
When the `--il-sequence-points` flag is used the behavior is the same as
with `-il`, but sequence point information is aslo emitted. This leaves
things open to adding an `--il-metadata-tokens` flag too.