Files
ILSpy/TestPlugin
Siegfried Pammer 667f6ad5f8 Add pwsh dev scripts, repo-wide lock files, and CI NuGet caching
Replace the Windows-only .bat helpers (clean / debugbuild / releasebuild /
restore / updatedeps and BuildTools/format) with cross-platform pwsh
scripts at the repo root: restore.ps1, build.ps1 (-Configuration), clean.ps1,
updatedeps.ps1 and BuildTools/format.ps1, alongside the existing publish.ps1.

Enable a packages.lock.json for every project by hoisting
RestorePackagesWithLockFile into the root Directory.Build.props (the four
core libraries set it individually before) and commit the generated locks,
so restores are repeatable and CI can cache packages off them.

Cache the NuGet packages folder in the three setup-dotnet workflows
(build-ilspy, build-frontends, codeql-analysis), keyed on the lock files
per the setup-dotnet caching guidance.

Scope the Debug "Verify package contents" check to the *.filelist outputs
it actually generates. A project's packages.lock.json is keyed only by
(framework, RID), with no host-OS axis, so a lock produced on Linux
legitimately differs from one produced on Windows whenever an OS-conditional
PackageReference applies (Debug+Windows pulls Microsoft.DiaSymReader*). The
Windows restore then rewrites those locks; that churn must not fail a step
whose job is to police the VSIX/MSI file lists.

Also drop the dead ILSpy.BamlDecompiler publish line from
publishlocaldev.ps1, mirroring the earlier publish.ps1 fix.

Assisted-by: Claude:claude-opus-4-8:Claude Code
2026-06-09 00:58:19 +02:00
..
2011-04-13 11:26:10 +02:00
2025-08-28 20:56:19 -04:00

ILSpy uses MEF (Managed Extensibility Framework) for plugins.
Plugins must be placed in the same directory as ILSpy.exe, and must be called "*.Plugin.dll".

To write a plugin, you need to add a reference to ILSpy.exe and to System.Composition.AttributedModel.
Depending on what your plugin is doing, you might also need references to the other libraries shipping with ILSpy.

Plugins work by exporting types for certain extension points.
Here is a list of extension points:

Adding another language:

	[Export(typeof(Language))]
	public class CustomLanguage : Language
	
	This adds an additional language to the combobox in the toolbar.
	The language has to implement its own decompiler (all the way from IL), but it can also re-use
	the ICSharpCode.Decompiler library to decompile to C#, and then translate the C# code to the target language.

---

Adding an entry to the main menu:

	[ExportMainMenuCommand(Menu = "_File", MenuIcon = "Clear.png", Header = "_Clear List", MenuCategory = "Open", MenuOrder = 1.5)]
	public class UnloadAllAssembliesCommand : SimpleCommand
	
	Menu: menu into which the item is added
	MenuIcon: optional, icon to use for the menu item. Must be embedded as "Resource" (WPF-style resource) in the same assembly as the command type.
	Header: text on the menu item
	MenuCategory: optional, used for grouping related menu items together. A separator is added between different groups.
	MenuOrder: controls the order in which the items appear (items are sorted by this value)

	The command class must implement WPF's ICommand interface.

---

Adding an entry to the tool bar:

	[ExportToolbarCommand(ToolTip = "Clears the current assembly list", ToolbarIcon = "Clear.png", ToolbarCategory = "Open", ToolbarOrder = 1.5)]
	public class UnloadAllAssembliesCommand : SimpleCommand

	ToolTip: the tool tip
	ToolbarIcon: The icon. Must be embedded as "Resource" (WPF-style resource) in the same assembly as the command type.
	ToolbarCategory: optional, used for grouping related toolbar items together. A separator is added between different groups.
	ToolbarOrder: controls the order in which the items appear (items are sorted by this value)

	The command class must implement WPF's ICommand interface.

---

Adding an entry to the context menu:

	[ExportContextMenuEntry(Header = "_Save Assembly")]
	public class SaveAssembly : IContextMenuEntry
	
	Icon: optional, icon to use for the menu item. Must be embedded as "Resource" (WPF-style resource) in the same assembly as the command type.
	Header: text on the menu item
	Category: optional, used for grouping related menu items together. A separator is added between different groups.
	Order: controls the order in which the items appear (items are sorted by this value)
	
	Context menu entries must implement IContextMenuEntry, which defines 3 methods:
	bool IsVisible, bool IsEnabled, and void Execute.

---

Adding an option page:

	[ExportOptionPage("TestPlugin")]
	partial class CustomOptionPage : UserControl, IOptionPage