Коммит
4fe44884b6
|
@ -233,7 +233,7 @@
|
|||
</Border>
|
||||
<StackPanel Orientation="Horizontal"
|
||||
Background="Transparent"
|
||||
ToolTip.Tip="{Binding ToolTip, FallbackValue=null}">
|
||||
ToolTip.Tip="{Binding ToolTip}">
|
||||
<ContentPresenter Name="icon"
|
||||
Width="16"
|
||||
Height="16"
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp2.1</TargetFramework>
|
||||
|
||||
<TieredCompilations>true</TieredCompilations>
|
||||
<TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>
|
||||
<PreserveCompilationContext>true</PreserveCompilationContext>
|
||||
<RuntimeIdentifiers>win7-x64;ubuntu.14.04-x64;debian.8-x64;osx.10.12-x64</RuntimeIdentifiers>
|
||||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
||||
|
||||
<GenerateAssemblyInfo>False</GenerateAssemblyInfo>
|
||||
|
||||
<EnableDefaultItems>false</EnableDefaultItems>
|
||||
|
||||
<RootNamespace>AvaloniaILSpy</RootNamespace>
|
||||
|
||||
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
|
||||
|
||||
<StartupObject>AvaloniaILSpy.NetCore.Program</StartupObject>
|
||||
|
||||
<SignAssembly>false</SignAssembly>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)' == 'Debug'">
|
||||
<DebugType>full</DebugType>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<CheckForOverflowUnderflow>True</CheckForOverflowUnderflow>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<CodeAnalysisRuleSet>..\ICSharpCode.Decompiler\ICSharpCode.Decompiler.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="Program.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\AvaloniaILSpy\AvaloniaILSpy.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -1,17 +1,13 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Avalonia;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Reflection;
|
||||
using Avalonia;
|
||||
using Avalonia.Logging.Serilog;
|
||||
|
||||
namespace AvaloniaILSpy
|
||||
namespace AvaloniaILSpy.NetCore
|
||||
{
|
||||
class Program
|
||||
static class Program
|
||||
{
|
||||
|
||||
static void Main(string[] args)
|
||||
{
|
||||
Directory.SetCurrentDirectory(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location));
|
||||
|
@ -19,13 +15,14 @@ namespace AvaloniaILSpy
|
|||
BuildAvaloniaApp().Start<MainWindow>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This method is needed for IDE previewer infrastructure
|
||||
/// </summary>
|
||||
public static AppBuilder BuildAvaloniaApp()
|
||||
=> AppBuilder.Configure<App>()
|
||||
=> AppBuilder.Configure<App>()
|
||||
#if DEBUG
|
||||
.LogToDebug()
|
||||
#endif
|
||||
.UsePlatformDetect();
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -10,11 +10,15 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "doc", "doc", "{F45DB999-7E7
|
|||
doc\IntPtr.txt = doc\IntPtr.txt
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AvaloniaILSpy.Controls", "AvaloniaILSpy.Controls\AvaloniaILSpy.Controls.csproj", "{0A3DA152-0729-4540-973C-11583009520F}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AvaloniaILSpy.Controls", "AvaloniaILSpy.Controls\AvaloniaILSpy.Controls.csproj", "{0A3DA152-0729-4540-973C-11583009520F}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AvaloniaILSpy", "AvaloniaILSpy\AvaloniaILSpy.csproj", "{7BB39313-8FC6-40A4-A06F-FD2A10817256}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AvaloniaILSpy", "AvaloniaILSpy\AvaloniaILSpy.csproj", "{7BB39313-8FC6-40A4-A06F-FD2A10817256}"
|
||||
EndProject
|
||||
Project("{9344BDBB-3E7F-41FC-A0DD-8665D75EE146}") = "AvaloniaEdit", "AvaloniaEdit\src\AvaloniaEdit\AvaloniaEdit.csproj", "{CC3151F6-C080-4E17-9F50-58C3FED64F28}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AvaloniaEdit", "AvaloniaEdit\src\AvaloniaEdit\AvaloniaEdit.csproj", "{CC3151F6-C080-4E17-9F50-58C3FED64F28}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestPlugin", "TestPlugin\TestPlugin.csproj", "{5C561A81-4427-418A-B773-3840D2B32C4D}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AvaloniaILSpy.NetCore", "AvaloniaILSpy.NetCore\AvaloniaILSpy.NetCore.csproj", "{3AAA340D-7BED-4B26-BDD3-992D8B6D7779}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
|
@ -34,6 +38,14 @@ Global
|
|||
{CC3151F6-C080-4E17-9F50-58C3FED64F28}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{CC3151F6-C080-4E17-9F50-58C3FED64F28}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{CC3151F6-C080-4E17-9F50-58C3FED64F28}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{5C561A81-4427-418A-B773-3840D2B32C4D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{5C561A81-4427-418A-B773-3840D2B32C4D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{5C561A81-4427-418A-B773-3840D2B32C4D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{5C561A81-4427-418A-B773-3840D2B32C4D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{3AAA340D-7BED-4B26-BDD3-992D8B6D7779}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{3AAA340D-7BED-4B26-BDD3-992D8B6D7779}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{3AAA340D-7BED-4B26-BDD3-992D8B6D7779}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{3AAA340D-7BED-4B26-BDD3-992D8B6D7779}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
|
@ -2,26 +2,9 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp2.1</TargetFramework>
|
||||
|
||||
<TieredCompilations>true</TieredCompilations>
|
||||
<TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>
|
||||
<PreserveCompilationContext>true</PreserveCompilationContext>
|
||||
<RuntimeIdentifiers>win7-x64;ubuntu.14.04-x64;debian.8-x64;osx.10.12-x64</RuntimeIdentifiers>
|
||||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
||||
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<GenerateAssemblyInfo>False</GenerateAssemblyInfo>
|
||||
|
||||
<EnableDefaultItems>false</EnableDefaultItems>
|
||||
|
||||
<RootNamespace>AvaloniaILSpy</RootNamespace>
|
||||
|
||||
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
|
||||
|
||||
<ApplicationIcon>Images\ILSpy-Large.ico</ApplicationIcon>
|
||||
<StartupObject>AvaloniaILSpy.Program</StartupObject>
|
||||
|
||||
<SignAssembly>false</SignAssembly>
|
||||
</PropertyGroup>
|
||||
|
||||
|
|
|
@ -103,16 +103,15 @@ namespace AvaloniaILSpy
|
|||
|
||||
public static IBitmap LoadImage(object part, string icon)
|
||||
{
|
||||
String uri;
|
||||
var assembly = part.GetType().Assembly;
|
||||
IBitmap image;
|
||||
var assembly = part.GetType().Assembly;
|
||||
if (assembly == typeof(Images).Assembly) {
|
||||
uri = (icon);
|
||||
image = new Bitmap(icon);
|
||||
} else {
|
||||
var name = assembly.GetName();
|
||||
uri = (name.Name + ";component/" + icon);
|
||||
}
|
||||
IBitmap image = new Bitmap(uri);
|
||||
//image.Freeze();
|
||||
var embededResourceStream = assembly.GetManifestResourceStream(icon);
|
||||
image = new Bitmap(embededResourceStream);
|
||||
}
|
||||
return image;
|
||||
}
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@ namespace AvaloniaILSpy
|
|||
/// <summary>
|
||||
/// The main window of the application.
|
||||
/// </summary>
|
||||
partial class MainWindow : Window, IRoutedCommandBindable
|
||||
public partial class MainWindow : Window, IRoutedCommandBindable
|
||||
{
|
||||
readonly NavigationHistory<NavigationState> history = new NavigationHistory<NavigationState>();
|
||||
ILSpySettings spySettings;
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
|
||||
|
||||
using System.ComponentModel.Composition;
|
||||
using Avalonia;
|
||||
using Avalonia.Media;
|
||||
|
||||
using AvaloniaEdit.Highlighting;
|
||||
using AvaloniaILSpy;
|
||||
|
||||
namespace TestPlugin
|
||||
{
|
||||
[Export(typeof(IAboutPageAddition))]
|
||||
public class AboutPageAddition : IAboutPageAddition
|
||||
{
|
||||
public void Write(ISmartTextOutput textOutput)
|
||||
{
|
||||
textOutput.WriteLine();
|
||||
textOutput.Write("This is a test.");
|
||||
textOutput.WriteLine();
|
||||
textOutput.WriteLine();
|
||||
textOutput.BeginSpan(new HighlightingColor {
|
||||
Background = new SimpleHighlightingBrush(Colors.Black),
|
||||
FontStyle = FontStyle.Italic,
|
||||
Foreground = new SimpleHighlightingBrush(Colors.Aquamarine)
|
||||
});
|
||||
textOutput.Write("DO NOT PRESS THIS BUTTON --> ");
|
||||
textOutput.AddButton(null, "Test!", (sender, args) => MessageBox.Show("Naughty Naughty!", "Naughty!", MessageBoxButton.OK, MessageBoxImage.Exclamation));
|
||||
textOutput.Write(" <--");
|
||||
textOutput.WriteLine();
|
||||
textOutput.EndSpan();
|
||||
textOutput.WriteLine();
|
||||
}
|
||||
}
|
||||
}
|
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 1.1 KiB |
|
@ -0,0 +1,42 @@
|
|||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Avalonia.Controls;
|
||||
using AvaloniaILSpy;
|
||||
using AvaloniaILSpy.TreeNodes;
|
||||
using Mono.Cecil;
|
||||
|
||||
namespace TestPlugin
|
||||
{
|
||||
[ExportContextMenuEntryAttribute(Header = "_Save Assembly")]
|
||||
public class SaveAssembly : IContextMenuEntry
|
||||
{
|
||||
public bool IsVisible(TextViewContext context)
|
||||
{
|
||||
return context.SelectedTreeNodes != null && context.SelectedTreeNodes.All(n => n is AssemblyTreeNode);
|
||||
}
|
||||
|
||||
public bool IsEnabled(TextViewContext context)
|
||||
{
|
||||
return context.SelectedTreeNodes != null && context.SelectedTreeNodes.Length == 1;
|
||||
}
|
||||
|
||||
public async void Execute(TextViewContext context)
|
||||
{
|
||||
if (context.SelectedTreeNodes == null)
|
||||
return;
|
||||
AssemblyTreeNode node = (AssemblyTreeNode)context.SelectedTreeNodes[0];
|
||||
AssemblyDefinition asm = node.LoadedAssembly.GetAssemblyDefinitionOrNull();
|
||||
if (asm != null) {
|
||||
SaveFileDialog dlg = new SaveFileDialog();
|
||||
dlg.InitialFileName = node.LoadedAssembly.FileName;
|
||||
dlg.Filters = new List<FileDialogFilter> { new FileDialogFilter { Name = "Assembly", Extensions = { "dll", "exe" } } };
|
||||
var filename = await dlg.ShowAsync(MainWindow.Instance);
|
||||
if (filename != null) {
|
||||
asm.MainModule.Write(filename);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
|
||||
|
||||
using System.ComponentModel.Composition;
|
||||
using Avalonia.Controls;
|
||||
using ICSharpCode.Decompiler;
|
||||
using AvaloniaILSpy;
|
||||
using Mono.Cecil;
|
||||
|
||||
namespace TestPlugin
|
||||
{
|
||||
/// <summary>
|
||||
/// Adds a new language to the decompiler.
|
||||
/// </summary>
|
||||
[Export(typeof(Language))]
|
||||
public class CustomLanguage : Language
|
||||
{
|
||||
public override string Name {
|
||||
get {
|
||||
return "Custom";
|
||||
}
|
||||
}
|
||||
|
||||
public override string FileExtension {
|
||||
get {
|
||||
// used in 'Save As' dialog
|
||||
return ".txt";
|
||||
}
|
||||
}
|
||||
|
||||
// There are several methods available to override; in this sample, we deal with methods only
|
||||
|
||||
public override void DecompileMethod(MethodDefinition method, ITextOutput output, DecompilationOptions options)
|
||||
{
|
||||
if (method.Body != null) {
|
||||
output.WriteLine("Size of method: {0} bytes", method.Body.CodeSize);
|
||||
|
||||
ISmartTextOutput smartOutput = output as ISmartTextOutput;
|
||||
if (smartOutput != null) {
|
||||
// when writing to the text view (but not when writing to a file), we can even add UI elements such as buttons:
|
||||
smartOutput.AddButton(null, "Click me!", (sender, e) => (sender as Button).Content = "I was clicked!");
|
||||
smartOutput.WriteLine();
|
||||
}
|
||||
|
||||
// ICSharpCode.Decompiler.CSharp.CSharpDecompiler can be used to decompile to C#.
|
||||
/*
|
||||
ModuleDefinition module = LoadModule(assemblyFileName);
|
||||
var typeSystem = new DecompilerTypeSystem(module);
|
||||
CSharpDecompiler decompiler = new CSharpDecompiler(typeSystem, new DecompilerSettings());
|
||||
|
||||
decompiler.AstTransforms.Add(new EscapeInvalidIdentifiers());
|
||||
SyntaxTree syntaxTree = decompiler.DecompileWholeModuleAsSingleFile();
|
||||
var visitor = new CSharpOutputVisitor(output, FormattingOptionsFactory.CreateSharpDevelop());
|
||||
syntaxTree.AcceptVisitor(visitor);
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
<UserControl
|
||||
xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||
<StackPanel>
|
||||
<CheckBox IsChecked="{Binding UselessOption1}">Useless option 1</CheckBox>
|
||||
<Slider Minimum="0" Maximum="100" Value="{Binding UselessOption2}"/>
|
||||
</StackPanel>
|
||||
</UserControl>
|
|
@ -0,0 +1,94 @@
|
|||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
|
||||
|
||||
using System.ComponentModel;
|
||||
using Avalonia.Controls;
|
||||
using System.Xml.Linq;
|
||||
using AvaloniaILSpy;
|
||||
using AvaloniaILSpy.Options;
|
||||
using System;
|
||||
using Avalonia.Markup.Xaml;
|
||||
|
||||
namespace TestPlugin
|
||||
{
|
||||
[ExportOptionPage(Title = "TestPlugin", Order = 0)]
|
||||
partial class CustomOptionPage : UserControl, IOptionPage
|
||||
{
|
||||
static readonly XNamespace ns = "http://www.ilspy.net/testplugin";
|
||||
|
||||
public CustomOptionPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
}
|
||||
|
||||
public void Load(ILSpySettings settings)
|
||||
{
|
||||
// For loading options, use ILSpySetting's indexer.
|
||||
// If the specified section does exist, the indexer will return a new empty element.
|
||||
XElement e = settings[ns + "CustomOptions"];
|
||||
// Now load the options from the XML document:
|
||||
Options s = new Options();
|
||||
s.UselessOption1 = (bool?)e.Attribute("useless1") ?? s.UselessOption1;
|
||||
s.UselessOption2 = (double?)e.Attribute("useless2") ?? s.UselessOption2;
|
||||
this.DataContext = s;
|
||||
}
|
||||
|
||||
public void Save(XElement root)
|
||||
{
|
||||
Options s = (Options)this.DataContext;
|
||||
// Save the options back into XML:
|
||||
XElement section = new XElement(ns + "CustomOptions");
|
||||
section.SetAttributeValue("useless1", s.UselessOption1);
|
||||
section.SetAttributeValue("useless2", s.UselessOption2);
|
||||
|
||||
// Replace the existing section in the settings file, or add a new section,
|
||||
// if required.
|
||||
XElement existingElement = root.Element(ns + "CustomOptions");
|
||||
if (existingElement != null)
|
||||
existingElement.ReplaceWith(section);
|
||||
else
|
||||
root.Add(section);
|
||||
}
|
||||
}
|
||||
|
||||
class Options : INotifyPropertyChanged
|
||||
{
|
||||
bool uselessOption1;
|
||||
|
||||
public bool UselessOption1 {
|
||||
get { return uselessOption1; }
|
||||
set {
|
||||
if (uselessOption1 != value) {
|
||||
uselessOption1 = value;
|
||||
OnPropertyChanged("UselessOption1");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
double uselessOption2;
|
||||
|
||||
public double UselessOption2 {
|
||||
get { return uselessOption2; }
|
||||
set {
|
||||
if (uselessOption2 != value) {
|
||||
uselessOption2 = value;
|
||||
OnPropertyChanged("UselessOption2");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
protected virtual void OnPropertyChanged(string propertyName)
|
||||
{
|
||||
if (PropertyChanged != null) {
|
||||
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
|
||||
|
||||
using AvaloniaILSpy;
|
||||
|
||||
namespace TestPlugin
|
||||
{
|
||||
// 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)
|
||||
[ExportMainMenuCommand(Menu = "_File", MenuIcon = "TestPlugin.Clear.png", Header = "_Clear List", MenuCategory = "Open", MenuOrder = 1.5)]
|
||||
// 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)
|
||||
[ExportToolbarCommand(ToolTip = "Clears the current assembly list", ToolbarIcon = "TestPlugin.Clear.png", ToolbarCategory = "Open", ToolbarOrder = 1.5)]
|
||||
public class UnloadAllAssembliesCommand : SimpleCommand
|
||||
{
|
||||
public override void Execute(object parameter)
|
||||
{
|
||||
foreach (var loadedAssembly in MainWindow.Instance.CurrentAssemblyList.GetAssemblies()) {
|
||||
loadedAssembly.AssemblyList.Unload(loadedAssembly);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
#region Using directives
|
||||
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
#endregion
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("TestPlugin")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("TestPlugin")]
|
||||
[assembly: AssemblyCopyright("Copyright 2011")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// This sets the default COM visibility of types in the assembly to invisible.
|
||||
// If you need to expose a type to COM, use [ComVisible(true)] on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The assembly version has following format :
|
||||
//
|
||||
// Major.Minor.Build.Revision
|
||||
//
|
||||
// You can specify all the values or you can use the default the Revision and
|
||||
// Build Numbers by using the '*' as shown below:
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"profiles": {
|
||||
"TestPlugin": {
|
||||
"commandName": "Executable",
|
||||
"executablePath": "$(OutDir)ILSpy.exe",
|
||||
"commandLineArgs": "/separate"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
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.ComponentModel.Composition.
|
||||
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
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<AssemblyName>Test.Plugin</AssemblyName>
|
||||
|
||||
<GenerateAssemblyInfo>False</GenerateAssemblyInfo>
|
||||
|
||||
<EnableDefaultItems>False</EnableDefaultItems>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)' == 'Debug'">
|
||||
<DebugType>full</DebugType>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<CheckForOverflowUnderflow>True</CheckForOverflowUnderflow>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="*.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Update="**\*.xaml.cs">
|
||||
<DependentUpon>%(Filename)</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<EmbeddedResource Include="**\*.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Clear.png" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="Readme.txt" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\AvaloniaILSpy\AvaloniaILSpy.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -11,12 +11,12 @@ var zipRootDir = artifactsDir.Combine("zips");
|
|||
var fileZipSuffix = ".zip";
|
||||
|
||||
var netCoreAppsRoot= ".";
|
||||
var netCoreApp = "AvaloniaILSpy";
|
||||
var netCoreApp = "AvaloniaILSpy.NetCore";
|
||||
|
||||
var buildDirs =
|
||||
GetDirectories($"{netCoreAppsRoot}/**/bin/**") +
|
||||
GetDirectories($"{netCoreAppsRoot}/**/obj/**") +
|
||||
GetDirectories($"{netCoreAppsRoot}/artifacts/**/zips/**");
|
||||
GetDirectories($"{netCoreAppsRoot}/artifacts/**");
|
||||
|
||||
var netCoreProject = new {
|
||||
Path = $"{netCoreAppsRoot}/{netCoreApp}",
|
||||
|
|
Загрузка…
Ссылка в новой задаче