Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Store some more debugger settings #276

Closed
wants to merge 11 commits into from

3 participants

Ronny Klier Eusebiu Marcu Daniel Grunwald
Ronny Klier
  • Make settings of debugged executables persistent (Tripel of assembly, workingdirectory and arguments), initialize with last debugged executable.
  • Make breakpoints persistent. More exactly, store all bookmarks which have an exported implementation of IBookmarkPersistence. This is done per assembly list. The load/save is triggered by debugger plugin because BookmarkManager as part of ILSpy.SharpDevelop.LGPL has no access to ILSpySettings or MainWindow.
  • Sort the entries in breakpoint panel
Eusebiu Marcu eusebiu was assigned
Eusebiu Marcu eusebiu was unassigned by RKlier
Daniel Grunwald dgrunwald closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Aug 29, 2011
  1. Fix: keep current line visible while stepping

    Ronny Klier authored
Commits on Sep 2, 2011
Commits on Sep 17, 2011
  1. Ronny Klier
  2. Ronny Klier
  3. Ronny Klier

    fix merge error

    RKlier authored
Commits on Sep 19, 2011
  1. Ronny Klier

    Sort breakpoints by member name

    RKlier authored
  2. Ronny Klier
Commits on Oct 17, 2011
  1. Merge branch 'master' into Bookmarks

    Ronny Klier authored
  2. Adapt to changes from master

    Ronny Klier authored
Commits on Oct 24, 2011
  1. Ronny Klier
Commits on Apr 14, 2012
  1. Ronny Klier
This page is out of date. Refresh to see the latest.
1  Debugger/ILSpy.Debugger/ILSpy.Debugger.csproj
View
@@ -85,6 +85,7 @@
<Compile Include="Models\TreeModel\StackFrameNode.cs" />
<Compile Include="Models\TreeModel\TreeNode.cs" />
<Compile Include="Models\TreeModel\Utils.cs" />
+ <Compile Include="Services\BreakpointService.cs" />
<Compile Include="Services\Debugger\DebuggerHelper.cs" />
<Compile Include="Services\Debugger\ListHelper.cs" />
<Compile Include="Services\Debugger\TypeResolverExtension.cs" />
160 Debugger/ILSpy.Debugger/Services/BreakpointService.cs
View
@@ -0,0 +1,160 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
+
+#region using
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Collections.Specialized;
+using ICSharpCode.ILSpy.Bookmarks;
+using System.Xml.Linq;
+using ICSharpCode.ILSpy.Debugger.Bookmarks;
+using ICSharpCode.ILSpy.XmlDoc;
+using Mono.Cecil;
+using ICSharpCode.Decompiler.ILAst;
+using ICSharpCode.NRefactory;
+
+#endregion
+
+namespace ICSharpCode.ILSpy.Debugger.Services
+{
+ [ExportBookmarkPersistenceAttribute(SupportedType=typeof(BreakpointBookmark))]
+ public class BreakpointPersistence : IBookmarkPersistence
+ {
+ #region IBookmarkPersistence Members
+
+ public XElement Save(BookmarkBase bookmark)
+ {
+ var b = bookmark as BreakpointBookmark;
+ XElement bElement = new XElement("Bookmark",
+ new XAttribute("functionToken", b.FunctionToken),
+ new XAttribute("isProperty", b.FunctionToken != b.MemberReference.MetadataToken.ToInt32()),
+ new XAttribute("enabled", b.IsEnabled),
+ new XAttribute("ilRange", b.ILRange),
+ new XAttribute("assembly", b.MemberReference.Module.FullyQualifiedName),
+ new XAttribute("type", b.MemberReference.DeclaringType.FullName),
+ new XAttribute("method", b.MemberReference.Name),
+ new XAttribute("line", b.LineNumber)); // line number is just stored as an initial value (it will be adapted if the method is decompiled/shown)
+ return bElement;
+ }
+
+ public BookmarkBase Load(XElement bookmarkNode)
+ {
+ string assembly = (string)bookmarkNode.Attribute("assembly");
+ string type = (string)bookmarkNode.Attribute("type");
+ string method = (string)bookmarkNode.Attribute("method");
+ MemberReference mr = BreakpointService.ResolveMethod(assembly, type + "." + method);
+ if (mr == null)
+ return null;
+ ILRange range;
+ int functionToken;
+ int line;
+ if (!ILRange.TryParse((string)bookmarkNode.Attribute("ilRange"), out range)
+ || !int.TryParse((string)bookmarkNode.Attribute("functionToken"), out functionToken)
+ || !int.TryParse((string)bookmarkNode.Attribute("line"), out line))
+ return null;
+ var breakpoint = new BreakpointBookmark(mr, new TextLocation(line, 0), functionToken, range,
+ BreakpointAction.Break);
+ breakpoint.IsEnabled = (bool)bookmarkNode.Attribute("enabled");
+ return breakpoint;
+ }
+
+ #endregion
+ }
+
+ /// <summary>
+ /// Store and load the bookmarks.
+ /// </summary>
+ /// <remarks>
+ /// This task should be handled by BookmarkManager, but it could not reach IlSpySettings and MainWindow.
+ /// </remarks>
+ static class BreakpointService
+ {
+ static string activeAssemblyListName = null;
+
+ public static void Initialize()
+ {
+ BookmarkManager.PersistenceEntries =
+ App.CompositionContainer.GetExports<IBookmarkPersistence, IBookmarkPersistenceMetadata>();
+ if (MainWindow.Instance.CurrentAssemblyList != null)
+ {
+ activeAssemblyListName = MainWindow.Instance.CurrentAssemblyList.ListName;
+ LoadBookmarks();
+ }
+ MainWindow.Instance.CurrentAssemblyListChanged += OnCurrentAssemblyListChanged;
+ MainWindow.Instance.Closing += delegate
+ {
+ SaveBookmarks();
+ MainWindow.Instance.CurrentAssemblyListChanged -= OnCurrentAssemblyListChanged;
+ };
+
+ }
+
+ public static MemberReference ResolveMethod(string assembly, string fullMethodName)
+ {
+ var foundAssembly = MainWindow.Instance.CurrentAssemblyList.OpenAssembly(assembly);
+ if (null == foundAssembly)
+ return null;
+ if (!foundAssembly.IsLoaded)
+ foundAssembly.WaitUntilLoaded();
+ // Replace is done because XmlDocKeyProvider stores ".ctor" as "#ctor"
+ MemberReference mr =
+ XmlDocKeyProvider.FindMemberByKey(foundAssembly.AssemblyDefinition.MainModule, "M:" + fullMethodName.Replace("..", ".#"));
+ if (mr == null)
+ mr = XmlDocKeyProvider.FindMemberByKey(foundAssembly.AssemblyDefinition.MainModule, "P:" + fullMethodName.Replace("..", ".#"));
+ return mr;
+ }
+
+ static void OnCurrentAssemblyListChanged(object sender, NotifyCollectionChangedEventArgs e)
+ {
+ if (e.Action != NotifyCollectionChangedAction.Reset
+ || activeAssemblyListName == MainWindow.Instance.CurrentAssemblyList.ListName)
+ return;
+ if (activeAssemblyListName != null)
+ SaveBookmarks();
+ BookmarkManager.Clear();
+ activeAssemblyListName = MainWindow.Instance.CurrentAssemblyList.ListName;
+ LoadBookmarks();
+ }
+
+ static void SaveBookmarks()
+ {
+ ILSpySettings.Update(
+ delegate (XElement root) {
+ XElement doc = root.Element("Bookmarks");
+ if (doc == null)
+ {
+ doc = new XElement("Bookmarks");
+ root.Add(doc);
+ }
+ XElement listElement = doc.Elements("List").FirstOrDefault(e => (string)e.Attribute("name") == activeAssemblyListName);
+ if (listElement != null)
+ listElement.ReplaceWith(SaveActiveBookmarks());
+ else
+ doc.Add(SaveActiveBookmarks());
+ });
+ }
+
+ static XElement SaveActiveBookmarks()
+ {
+ XElement list = BookmarkManager.SaveBookmarks();
+ list.SetAttributeValue("name", activeAssemblyListName);
+ return list;
+ }
+
+ static void LoadBookmarks()
+ {
+ ILSpySettings settings = ILSpySettings.Load();
+ XElement doc = settings["Bookmarks"];
+ if (doc == null)
+ {
+ return;
+ }
+ XElement listElement = doc.Elements("List").FirstOrDefault(e => (string)e.Attribute("name") == activeAssemblyListName);
+ if (listElement == null)
+ return;
+ BookmarkManager.LoadBookmarks(listElement);
+ }
+ }
+}
2  Debugger/ILSpy.Debugger/Services/Debugger/WindowsDebugger.cs
View
@@ -91,7 +91,6 @@ protected virtual void OnProcessSelected(ProcessEventArgs e)
public WindowsDebugger()
{
-
}
#region IDebugger Members
@@ -808,6 +807,7 @@ public void JumpToCurrentLine()
DebugInformation.DebugStepInformation = null; // we do not need to step into/out
DebuggerService.RemoveCurrentLineMarker();
DebuggerService.JumpToCurrentLine(memberReference, line, 0, line, 0, ilOffset);
+ MainWindow.Instance.TextView.UnfoldAndScroll(line);
}
else {
StepIntoUnknownFrame(frame);
4 Debugger/ILSpy.Debugger/UI/BreakpointPanel.xaml
View
@@ -1,6 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<UserControl
- x:Class="ICSharpCode.ILSpy.Debugger.UI.BreakpointPanel" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:bm="clr-namespace:ICSharpCode.ILSpy.Bookmarks">
+ x:Class="ICSharpCode.ILSpy.Debugger.UI.BreakpointPanel"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid>
<ListView
Name="view"
121 Debugger/ILSpy.Debugger/UI/BreakpointPanel.xaml.cs
View
@@ -14,69 +14,86 @@
using ICSharpCode.ILSpy;
using ICSharpCode.ILSpy.Bookmarks;
+using ICSharpCode.ILSpy.Controls;
using ICSharpCode.ILSpy.Debugger.Bookmarks;
using ICSharpCode.ILSpy.Options;
+using ICSharpCode.ILSpy.Debugger.Services;
namespace ICSharpCode.ILSpy.Debugger.UI
{
- /// <summary>
- /// Interaction logic for BreakpointPanel.xaml
- /// </summary>
- public partial class BreakpointPanel : UserControl, IPane
+ /// <summary>
+ /// Interaction logic for BreakpointPanel.xaml
+ /// </summary>
+ public partial class BreakpointPanel : UserControl, IPane
+ {
+ static BreakpointPanel s_instance;
+
+ public static BreakpointPanel Instance
{
- static BreakpointPanel s_instance;
-
- public static BreakpointPanel Instance
- {
- get {
- if (null == s_instance)
- {
- App.Current.VerifyAccess();
- s_instance = new BreakpointPanel();
- }
- return s_instance;
+ get {
+ if (null == s_instance)
+ {
+ App.Current.VerifyAccess();
+ s_instance = new BreakpointPanel();
}
+ return s_instance;
}
+ }
- private BreakpointPanel()
- {
- InitializeComponent();
- }
+ private BreakpointPanel()
+ {
+ InitializeComponent();
+ }
- public void Show()
- {
- if (!IsVisible)
- {
- SetItemSource();
-
- MainWindow.Instance.ShowInBottomPane("Breakpoints", this);
-
- BookmarkManager.Added += delegate { SetItemSource(); };
- BookmarkManager.Removed += delegate { SetItemSource(); };
- DebuggerSettings.Instance.PropertyChanged +=
- delegate(object s, PropertyChangedEventArgs e) { if (e.PropertyName == "ShowAllBookmarks") SetItemSource(); };
- }
- }
-
- private void SetItemSource()
- {
- view.ItemsSource = null;
- if (DebuggerSettings.Instance.ShowAllBookmarks)
- view.ItemsSource = BookmarkManager.Bookmarks;
- else
- view.ItemsSource = BookmarkManager.Bookmarks.Where(b => b is BreakpointBookmark);
- }
+ public void Show()
+ {
+ if (!IsVisible)
+ {
+ SetItemSource();
+
+ MainWindow.Instance.ShowInBottomPane("Breakpoints", this);
+
+ BookmarkManager.Added += delegate { SetItemSource(); };
+ BookmarkManager.Removed += delegate { SetItemSource(); };
+ DebuggerSettings.Instance.PropertyChanged +=
+ delegate(object s, PropertyChangedEventArgs e) { if (e.PropertyName == "ShowAllBookmarks") SetItemSource(); };
+ }
+ }
+
+ private void SetItemSource()
+ {
+ view.ItemsSource = null;
+ if (DebuggerSettings.Instance.ShowAllBookmarks)
+ view.ItemsSource = BookmarkManager.Bookmarks;
+ else
+ view.ItemsSource = BookmarkManager.Bookmarks.Where(b => b is BreakpointBookmark);
+ Sort();
+ }
+
+ private void Sort()
+ {
+ // BreakpointPanel doesn't use SortableGridViewColumn to sort since should not happen on a specific column
+ // nor should the column or direction change.
+ // Additional SortableGridViewColumndoes not update order when adding or removing content.
+ ICollectionView dataView =
+ CollectionViewSource.GetDefaultView(view.ItemsSource);
+
+ dataView.SortDescriptions.Clear();
+ SortDescription sd = new SortDescription("MemberReference.FullName", ListSortDirection.Ascending);
+ dataView.SortDescriptions.Add(sd);
+ dataView.Refresh();
+ }
public void Closed()
{
- BookmarkManager.Added -= delegate { SetItemSource(); };
- BookmarkManager.Removed -= delegate { SetItemSource(); };
- DebuggerSettings.Instance.PropertyChanged -=
- delegate(object s, PropertyChangedEventArgs e) { if (e.PropertyName == "ShowAllBookmarks") SetItemSource(); };
+ BookmarkManager.Added -= delegate { SetItemSource(); };
+ BookmarkManager.Removed -= delegate { SetItemSource(); };
+ DebuggerSettings.Instance.PropertyChanged -=
+ delegate(object s, PropertyChangedEventArgs e) { if (e.PropertyName == "ShowAllBookmarks") SetItemSource(); };
}
- void view_MouseDoubleClick(object sender, MouseButtonEventArgs e)
- {
+ void view_MouseDoubleClick(object sender, MouseButtonEventArgs e)
+ {
if (MouseButton.Left != e.ChangedButton)
return;
var selectedItem = view.SelectedItem as BookmarkBase;
@@ -85,7 +102,7 @@ void view_MouseDoubleClick(object sender, MouseButtonEventArgs e)
MainWindow.Instance.JumpToReference(selectedItem.MemberReference);
MainWindow.Instance.TextView.UnfoldAndScroll(selectedItem.LineNumber);
e.Handled = true;
- }
+ }
void view_KeyUp(object sender, KeyEventArgs e)
{
@@ -102,6 +119,12 @@ void view_KeyUp(object sender, KeyEventArgs e)
[ExportMainMenuCommand(Menu="_Debugger", Header="Show _Breakpoints", MenuCategory="View", MenuOrder=8)]
public class BookmarkManagerPanelCommand : SimpleCommand
{
+ public BookmarkManagerPanelCommand()
+ {
+ // (mis)use the fact that loaded on startup
+ BreakpointService.Initialize();
+ }
+
public override void Execute(object parameter)
{
BreakpointPanel.Instance.Show();
7 Debugger/ILSpy.Debugger/UI/CallStackPanel.xaml.cs
View
@@ -226,11 +226,8 @@ void view_MouseDoubleClick(object sender, MouseButtonEventArgs e)
if (null == selectedItem)
return;
- var foundAssembly = MainWindow.Instance.CurrentAssemblyList.OpenAssembly(selectedItem.Frame.MethodInfo.DebugModule.FullPath);
- if (null == foundAssembly || null == foundAssembly.AssemblyDefinition)
- return;
-
- MemberReference mr = XmlDocKeyProvider.FindMemberByKey(foundAssembly.AssemblyDefinition.MainModule, "M:" + selectedItem.Name);
+ MemberReference mr = BreakpointService.ResolveMethod(selectedItem.Frame.MethodInfo.DebugModule.FullPath,
+ selectedItem.Name);
if (mr == null)
return;
MainWindow.Instance.JumpToReference(mr);
122 Debugger/ILSpy.Debugger/UI/ExecuteProcessWindow.xaml
View
@@ -6,105 +6,45 @@
WindowState="Normal"
WindowStyle="ToolWindow"
ShowInTaskbar="False"
- Height="171"
- Width="509">
- <Grid>
- <Grid.RowDefinitions>
- <RowDefinition
- Height="1.4*" />
- <RowDefinition
+ Height="250"
+ Width="600">
+ <Grid>
+ <Grid.RowDefinitions>
+ <RowDefinition
+ Height="1*" />
+ <RowDefinition
Height="Auto" />
- </Grid.RowDefinitions>
- <Grid.ColumnDefinitions>
- <ColumnDefinition
- Width="125" />
- <ColumnDefinition
- Width="1*" />
- <ColumnDefinition
- Width="40" />
- </Grid.ColumnDefinitions>
- <Label
- Content="Executable"
- Grid.Column="0"
- Grid.Row="0"
- HorizontalAlignment="Left"
- VerticalAlignment="Top"
- Margin="19.5,15.5,0,0" />
- <TextBox
- Name="pathTextBox"
- Grid.Column="1"
- Grid.Row="0"
- HorizontalAlignment="Stretch"
- VerticalAlignment="Top"
- Margin="5,15.5,0,0" />
- <Button
- Content="..."
- MinWidth="25"
- Name="pathButton"
- Click="pathButton_Click"
- Grid.Column="2"
- Grid.Row="0"
- HorizontalAlignment="Left"
- VerticalAlignment="Top"
- Margin="5,15.5,0,0" />
- <Label
- Content="Arguments"
- Grid.Column="0"
- Grid.Row="0"
- HorizontalAlignment="Left"
- VerticalAlignment="Top"
- Margin="19.5,46.46,0,0" />
- <TextBox
- Name="argumentsTextBox"
- Grid.Column="1"
- Grid.Row="0"
- HorizontalAlignment="Stretch"
- VerticalAlignment="Top"
- Margin="5,46.46,0,0" />
- <Label
- Content="Working directory"
- Grid.Column="0"
- Grid.Row="0"
- HorizontalAlignment="Left"
- VerticalAlignment="Top"
- Margin="19.5,77.42,0,0" />
- <TextBox
- Name="workingDirectoryTextBox"
- Grid.Column="1"
- Grid.Row="0"
- HorizontalAlignment="Stretch"
- VerticalAlignment="Top"
- Margin="5,77.42,0,0" />
- <Button
- Content="..."
- MinWidth="25"
- Click="workingDirectoryButton_Click"
- Name="workingDirectoryButton"
- Grid.Column="2"
- Grid.Row="0"
- HorizontalAlignment="Left"
- VerticalAlignment="Top"
- Margin="5,77.42,0,0" />
- <StackPanel
- Margin="4"
+ </Grid.RowDefinitions>
+ <StackPanel Grid.Row="0" VerticalAlignment="Top" Margin="12,8">
+ <Label Content="Executable" HorizontalAlignment="Left"/>
+ <DockPanel>
+ <Button DockPanel.Dock="Right" Margin="2" Padding="4,0" Content="..." Name="pathButton" Click="pathButton_Click" MinWidth="25"/>
+ <TextBox Name="pathTextBox"/>
+ </DockPanel>
+ <Label Content="Arguments" HorizontalAlignment="Left"/>
+ <TextBox Name="argumentsTextBox"/>
+ <Label Content="Working directory" HorizontalAlignment="Left"/>
+ <DockPanel>
+ <Button DockPanel.Dock="Right" Margin="2" Padding="4,0" Content="..." Name="workingDirectoryButton" Click="workingDirectoryButton_Click" MinWidth="25"/>
+ <TextBox Name="workingDirectoryTextBox"/>
+ </DockPanel>
+ </StackPanel>
+ <StackPanel Grid.Row="1"
Orientation="Horizontal"
HorizontalAlignment="Right"
- Grid.Row="1"
- Grid.ColumnSpan="3">
+ VerticalAlignment="Bottom"
+ Margin="12,8">
<Button
- Margin="0,0,4,0"
- DockPanel.Dock="Left"
- HorizontalAlignment="Center"
- x:Name="ExecuteButton"
+ Margin="2"
IsDefault="True"
+ x:Name="ExecuteButton"
Click="ExecuteButton_Click"
- Content="Execute" />
+ Content="Execute"/>
<Button
- DockPanel.Dock="Right"
+ Margin="2"
IsCancel="True"
x:Name="CancelButton"
- Content="Cancel"
- Click="CancelButton_Click" />
+ Content="Cancel"/>
</StackPanel>
- </Grid>
+ </Grid>
</Window>
209 Debugger/ILSpy.Debugger/UI/ExecuteProcessWindow.xaml.cs
View
@@ -7,78 +7,145 @@
using System.Text;
using System.Windows;
using System.Windows.Forms;
+using System.Linq;
+using System.Xml.Linq;
namespace ICSharpCode.ILSpy.Debugger.UI
{
- /// <summary>
- /// Interaction logic for ExecuteProcessWindow.xaml
- /// </summary>
- public partial class ExecuteProcessWindow : Window
- {
- public ExecuteProcessWindow()
- {
- InitializeComponent();
- }
-
- public string SelectedExecutable {
- get {
- return pathTextBox.Text;
- }
- set {
- pathTextBox.Text = value;
- workingDirectoryTextBox.Text = Path.GetDirectoryName(value);
- }
- }
-
- public string WorkingDirectory {
- get {
- return workingDirectoryTextBox.Text;
- }
- set {
- workingDirectoryTextBox.Text = value;
- }
- }
-
- public string Arguments {
- get {
- return argumentsTextBox.Text;
- }
- }
-
- void pathButton_Click(object sender, RoutedEventArgs e)
- {
- OpenFileDialog dialog = new OpenFileDialog() {
- Filter = ".NET Executable (*.exe) | *.exe",
- InitialDirectory = workingDirectoryTextBox.Text,
- RestoreDirectory = true,
- DefaultExt = "exe"
- };
-
- if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) {
- SelectedExecutable = dialog.FileName;
- }
- }
-
- void ExecuteButton_Click(object sender, RoutedEventArgs e)
- {
- if (string.IsNullOrEmpty(SelectedExecutable))
- return;
- this.DialogResult = true;
- }
-
- void CancelButton_Click(object sender, RoutedEventArgs e)
- {
- this.Close();
- }
-
- void workingDirectoryButton_Click(object sender, RoutedEventArgs e)
- {
- FolderBrowserDialog dialog = new FolderBrowserDialog() {
- SelectedPath = workingDirectoryTextBox.Text
- };
- if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) {
- workingDirectoryTextBox.Text = dialog.SelectedPath;
- }
- }
- }
+ /// <summary>
+ /// Interaction logic for ExecuteProcessWindow.xaml
+ /// </summary>
+ public partial class ExecuteProcessWindow : Window
+ {
+ public ExecuteProcessWindow()
+ {
+ InitializeComponent();
+ InitFromExecutable();
+ }
+
+ public string SelectedExecutable
+ {
+ get
+ {
+ return pathTextBox.Text;
+ }
+ set
+ {
+ pathTextBox.Text = value;
+ // just in case we have no stored working directory
+ workingDirectoryTextBox.Text = Path.GetDirectoryName(value);
+ InitFromExecutable(value);
+ }
+ }
+
+ public string WorkingDirectory
+ {
+ get
+ {
+ return workingDirectoryTextBox.Text;
+ }
+ set
+ {
+ workingDirectoryTextBox.Text = value;
+ }
+ }
+
+ public string Arguments
+ {
+ get
+ {
+ return argumentsTextBox.Text;
+ }
+ private set
+ {
+ argumentsTextBox.Text = value;
+ }
+ }
+
+ void InitFromExecutable(string file = null)
+ {
+ var settings = ILSpySettings.Load();
+ var debuggerSettings = settings["DebuggerSettings"];
+ var executables = debuggerSettings.Element("Executables");
+ if (null == executables)
+ return;
+ if (null == file)
+ file = (string)executables.Attribute("last");
+ var lastAssembly = executables.Elements("Assembly").FirstOrDefault(a => (string)a.Attribute("name") == file);
+ if (null == lastAssembly)
+ return;
+ pathTextBox.Text = (string)lastAssembly.Attribute("name");
+ workingDirectoryTextBox.Text = (string)lastAssembly.Attribute("workingDirectory");
+ argumentsTextBox.Text = (string)lastAssembly.Attribute("arguments");
+ }
+
+ void pathButton_Click(object sender, RoutedEventArgs e)
+ {
+ OpenFileDialog dialog = new OpenFileDialog()
+ {
+ Filter = ".NET Executable (*.exe) | *.exe",
+ InitialDirectory = workingDirectoryTextBox.Text,
+ RestoreDirectory = true,
+ DefaultExt = "exe"
+ };
+
+ if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
+ {
+ SelectedExecutable = dialog.FileName;
+ }
+ }
+
+ void ExecuteButton_Click(object sender, RoutedEventArgs e)
+ {
+ if (string.IsNullOrEmpty(SelectedExecutable))
+ return;
+ // update settings
+ ILSpySettings.Update(
+ delegate(XElement root)
+ {
+ XElement debuggerSettings = root.Element("DebuggerSettings");
+ if (debuggerSettings == null)
+ {
+ debuggerSettings = new XElement("DebuggerSettings");
+ root.Add(debuggerSettings);
+ }
+ XElement executables = debuggerSettings.Element("Executables");
+ if (executables == null)
+ {
+ executables = new XElement("Executables");
+ debuggerSettings.Add(executables);
+ }
+ executables.SetAttributeValue("last", SelectedExecutable);
+ XElement assembly = new XElement("Assembly");
+ assembly.SetAttributeValue("name", SelectedExecutable);
+ assembly.SetAttributeValue("workingDirectory", WorkingDirectory);
+ assembly.SetAttributeValue("arguments", Arguments);
+
+ XElement listElement = executables.Elements("Assembly").FirstOrDefault(a => (string)a.Attribute("name") == SelectedExecutable);
+ if (listElement != null)
+ listElement.ReplaceWith(assembly);
+ else
+ executables.Add(assembly);
+
+ });
+ this.DialogResult = true;
+ }
+
+ void CancelButton_Click(object sender, RoutedEventArgs e)
+ {
+ this.Close();
+ }
+
+ void workingDirectoryButton_Click(object sender, RoutedEventArgs e)
+ {
+ FolderBrowserDialog dialog = new FolderBrowserDialog()
+ {
+ SelectedPath = workingDirectoryTextBox.Text
+ };
+ if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
+ {
+ workingDirectoryTextBox.Text = dialog.SelectedPath;
+ }
+ }
+ }
}
17 ICSharpCode.Decompiler/ILAst/ILAstTypes.cs
View
@@ -29,6 +29,7 @@
using Mono.Cecil.Cil;
using Mono.CSharp;
using Cecil = Mono.Cecil;
+using System.Globalization;
namespace ICSharpCode.Decompiler.ILAst
{
@@ -230,7 +231,21 @@ public override string ToString()
{
return string.Format("{0}-{1}", From.ToString("X"), To.ToString("X"));
}
-
+
+ public static bool TryParse(string value, out ILRange result)
+ {
+ result = null;
+ string[] p = value.Split('-');
+ if (p == null || p.Length != 2)
+ return false;
+ ILRange ilr = new ILRange();
+ if (!int.TryParse(p[0], NumberStyles.HexNumber, CultureInfo.InvariantCulture, out ilr.From)
+ || !int.TryParse(p[1], NumberStyles.HexNumber, CultureInfo.InvariantCulture, out ilr.To))
+ return false;
+ result = ilr;
+ return true;
+ }
+
public static List<ILRange> OrderAndJoint(IEnumerable<ILRange> input)
{
if (input == null)
64 ILSpy.SharpDevelop.LGPL/Bookmarks/BookmarkManager.cs
View
@@ -8,9 +8,38 @@
using ICSharpCode.NRefactory.CSharp;
using Mono.Cecil;
using Mono.CSharp;
+using System.ComponentModel.Composition;
+using System.Xml.Linq;
+using System.Linq;
namespace ICSharpCode.ILSpy.Bookmarks
{
+ /// <summary>
+ /// Bookmark specializations may provide an exported implementation of this interface to support save and load for these bookmarks.
+ /// </summary>
+ public interface IBookmarkPersistence
+ {
+ XElement Save(BookmarkBase bookmark);
+ BookmarkBase Load(XElement bookmarkNode);
+ }
+
+ public interface IBookmarkPersistenceMetadata
+ {
+ Type SupportedType { get; }
+ }
+
+ [MetadataAttribute]
+ [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
+ public class ExportBookmarkPersistenceAttribute : ExportAttribute, IBookmarkPersistenceMetadata
+ {
+ public ExportBookmarkPersistenceAttribute()
+ : base(typeof(IBookmarkPersistence))
+ {
+ }
+
+ public Type SupportedType { get; set; }
+ }
+
/// <summary>
/// Static class that maintains the list of bookmarks and breakpoints.
/// </summary>
@@ -113,5 +142,38 @@ static void OnAdded(BookmarkEventArgs e)
public static event BookmarkEventHandler Removed;
public static event BookmarkEventHandler Added;
- }
+
+ #region persistence
+ [ImportMany(typeof(IBookmarkPersistence))]
+ public static IEnumerable<Lazy<IBookmarkPersistence, IBookmarkPersistenceMetadata>> PersistenceEntries { get; set; }
+
+ public static XElement SaveBookmarks()
+ {
+ XElement list = new XElement("List");
+ foreach (var b in BookmarkManager.Bookmarks)
+ {
+ var persistenceHandler = PersistenceEntries.FirstOrDefault(e => e.Metadata.SupportedType == b.GetType());
+ if (null == persistenceHandler)
+ continue;
+ var bookmarkNode = persistenceHandler.Value.Save(b);
+ bookmarkNode.SetAttributeValue("bookmarkType", b.GetType().Name);
+ list.Add(bookmarkNode);
+ }
+ return list;
+ }
+
+ public static void LoadBookmarks(XElement bookmarkList)
+ {
+ foreach (var bookmarkNode in bookmarkList.Elements("Bookmark"))
+ {
+ var persistenceHandler =
+ PersistenceEntries.FirstOrDefault(e => e.Metadata.SupportedType.Name == (string)bookmarkNode.Attribute("bookmarkType"));
+ if (null == persistenceHandler)
+ continue;
+ BookmarkBase newMark = persistenceHandler.Value.Load(bookmarkNode);
+ AddMark(newMark);
+ }
+ }
+ #endregion
+ }
}
8 ILSpy.SharpDevelop.LGPL/ILSpy.SharpDevelop.LGPL.csproj
View
@@ -48,6 +48,7 @@
<RequiredTargetFramework>3.0</RequiredTargetFramework>
</Reference>
<Reference Include="System" />
+ <Reference Include="System.ComponentModel.Composition" />
<Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
@@ -86,12 +87,7 @@
<Compile Include="Services\IDebugger.cs" />
<Compile Include="Services\ParserService.cs" />
</ItemGroup>
- <ItemGroup>
- <Folder Include="AvalonEdit" />
- <Folder Include="Bookmarks" />
- <Folder Include="Models" />
- <Folder Include="Services" />
- </ItemGroup>
+ <ItemGroup />
<ItemGroup>
<ProjectReference Include="..\AvalonEdit\ICSharpCode.AvalonEdit\ICSharpCode.AvalonEdit.csproj">
<Project>{6C55B776-26D4-4DB3-A6AB-87E783B2F3D1}</Project>
62 ILSpy.sln
View
@@ -1,15 +1,14 @@

Microsoft Visual Studio Solution File, Format Version 11.00
+# SharpDevelop 4.1.0.7638-alpha
# Visual Studio 2010
# SharpDevelop 4.2.0.8200-alpha
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "doc", "doc", "{F45DB999-7E72-4000-B5AD-3A7B485A0896}"
- ProjectSection(SolutionItems) = postProject
+ ProjectSection(SolutionItems) = preProject
doc\Command Line.txt = doc\Command Line.txt
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Debugger", "Debugger", "{89C4A682-2706-44A3-ADDC-BC273164C37E}"
- ProjectSection(SolutionItems) = postProject
- EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ILSpy.Debugger", "Debugger\ILSpy.Debugger\ILSpy.Debugger.csproj", "{6D3D0F0D-348D-456A-A6ED-E9BD5EFABB6A}"
EndProject
@@ -51,6 +50,18 @@ Global
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {1D18D788-F7EE-4585-A23B-34DC8EC63CB8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {1D18D788-F7EE-4585-A23B-34DC8EC63CB8}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {1D18D788-F7EE-4585-A23B-34DC8EC63CB8}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {1D18D788-F7EE-4585-A23B-34DC8EC63CB8}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {1D18D788-F7EE-4585-A23B-34DC8EC63CB8}.Release|Any CPU.Build.0 = Release|Any CPU
+ {1D18D788-F7EE-4585-A23B-34DC8EC63CB8}.Release|x86.ActiveCfg = Release|Any CPU
+ {6D3D0F0D-348D-456A-A6ED-E9BD5EFABB6A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {6D3D0F0D-348D-456A-A6ED-E9BD5EFABB6A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {6D3D0F0D-348D-456A-A6ED-E9BD5EFABB6A}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {6D3D0F0D-348D-456A-A6ED-E9BD5EFABB6A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {6D3D0F0D-348D-456A-A6ED-E9BD5EFABB6A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {6D3D0F0D-348D-456A-A6ED-E9BD5EFABB6A}.Release|x86.ActiveCfg = Release|Any CPU
{1E85EFF9-E370-4683-83E4-8A3D063FF791}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1E85EFF9-E370-4683-83E4-8A3D063FF791}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1E85EFF9-E370-4683-83E4-8A3D063FF791}.Debug|x86.ActiveCfg = Debug|x86
@@ -107,46 +118,46 @@ Global
{FEC0DA52-C4A6-4710-BE36-B484A20C5E22}.Release|Any CPU.Build.0 = Release|Any CPU
{FEC0DA52-C4A6-4710-BE36-B484A20C5E22}.Release|x86.ActiveCfg = Release|x86
{FEC0DA52-C4A6-4710-BE36-B484A20C5E22}.Release|x86.Build.0 = Release|x86
- {F32EBCC8-0E53-4421-867E-05B3D6E10C70}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F32EBCC8-0E53-4421-867E-05B3D6E10C70}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {F32EBCC8-0E53-4421-867E-05B3D6E10C70}.Debug|x86.Build.0 = Debug|Any CPU
+ {F32EBCC8-0E53-4421-867E-05B3D6E10C70}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F32EBCC8-0E53-4421-867E-05B3D6E10C70}.Debug|x86.ActiveCfg = Debug|Any CPU
- {F32EBCC8-0E53-4421-867E-05B3D6E10C70}.Release|Any CPU.Build.0 = Release|Any CPU
+ {F32EBCC8-0E53-4421-867E-05B3D6E10C70}.Debug|x86.Build.0 = Debug|Any CPU
{F32EBCC8-0E53-4421-867E-05B3D6E10C70}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {F32EBCC8-0E53-4421-867E-05B3D6E10C70}.Release|x86.Build.0 = Release|Any CPU
+ {F32EBCC8-0E53-4421-867E-05B3D6E10C70}.Release|Any CPU.Build.0 = Release|Any CPU
{F32EBCC8-0E53-4421-867E-05B3D6E10C70}.Release|x86.ActiveCfg = Release|Any CPU
- {63E6915C-7EA4-4D76-AB28-0D7191EEA626}.Debug|Any CPU.Build.0 = net_4_0_Debug|Any CPU
+ {F32EBCC8-0E53-4421-867E-05B3D6E10C70}.Release|x86.Build.0 = Release|Any CPU
{63E6915C-7EA4-4D76-AB28-0D7191EEA626}.Debug|Any CPU.ActiveCfg = net_4_0_Debug|Any CPU
- {63E6915C-7EA4-4D76-AB28-0D7191EEA626}.Debug|x86.Build.0 = net_4_0_Debug|Any CPU
+ {63E6915C-7EA4-4D76-AB28-0D7191EEA626}.Debug|Any CPU.Build.0 = net_4_0_Debug|Any CPU
{63E6915C-7EA4-4D76-AB28-0D7191EEA626}.Debug|x86.ActiveCfg = net_4_0_Debug|Any CPU
- {63E6915C-7EA4-4D76-AB28-0D7191EEA626}.Release|Any CPU.Build.0 = net_4_0_Release|Any CPU
+ {63E6915C-7EA4-4D76-AB28-0D7191EEA626}.Debug|x86.Build.0 = net_4_0_Debug|Any CPU
{63E6915C-7EA4-4D76-AB28-0D7191EEA626}.Release|Any CPU.ActiveCfg = net_4_0_Release|Any CPU
+ {63E6915C-7EA4-4D76-AB28-0D7191EEA626}.Release|Any CPU.Build.0 = net_4_0_Release|Any CPU
{63E6915C-7EA4-4D76-AB28-0D7191EEA626}.Release|x86.Build.0 = net_4_0_Release|Any CPU
{63E6915C-7EA4-4D76-AB28-0D7191EEA626}.Release|x86.ActiveCfg = net_4_0_Release|Any CPU
- {7B82B671-419F-45F4-B778-D9286F996EFA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7B82B671-419F-45F4-B778-D9286F996EFA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {7B82B671-419F-45F4-B778-D9286F996EFA}.Debug|x86.Build.0 = Debug|Any CPU
+ {7B82B671-419F-45F4-B778-D9286F996EFA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7B82B671-419F-45F4-B778-D9286F996EFA}.Debug|x86.ActiveCfg = Debug|Any CPU
- {7B82B671-419F-45F4-B778-D9286F996EFA}.Release|Any CPU.Build.0 = Release|Any CPU
+ {7B82B671-419F-45F4-B778-D9286F996EFA}.Debug|x86.Build.0 = Debug|Any CPU
{7B82B671-419F-45F4-B778-D9286F996EFA}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {7B82B671-419F-45F4-B778-D9286F996EFA}.Release|x86.Build.0 = Release|Any CPU
+ {7B82B671-419F-45F4-B778-D9286F996EFA}.Release|Any CPU.Build.0 = Release|Any CPU
{7B82B671-419F-45F4-B778-D9286F996EFA}.Release|x86.ActiveCfg = Release|Any CPU
- {A6BAD2BA-76BA-461C-8B6D-418607591247}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7B82B671-419F-45F4-B778-D9286F996EFA}.Release|x86.Build.0 = Release|Any CPU
{A6BAD2BA-76BA-461C-8B6D-418607591247}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {A6BAD2BA-76BA-461C-8B6D-418607591247}.Debug|x86.Build.0 = Debug|x86
+ {A6BAD2BA-76BA-461C-8B6D-418607591247}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A6BAD2BA-76BA-461C-8B6D-418607591247}.Debug|x86.ActiveCfg = Debug|x86
- {A6BAD2BA-76BA-461C-8B6D-418607591247}.Release|Any CPU.Build.0 = Release|Any CPU
+ {A6BAD2BA-76BA-461C-8B6D-418607591247}.Debug|x86.Build.0 = Debug|x86
{A6BAD2BA-76BA-461C-8B6D-418607591247}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {A6BAD2BA-76BA-461C-8B6D-418607591247}.Release|x86.Build.0 = Release|x86
+ {A6BAD2BA-76BA-461C-8B6D-418607591247}.Release|Any CPU.Build.0 = Release|Any CPU
{A6BAD2BA-76BA-461C-8B6D-418607591247}.Release|x86.ActiveCfg = Release|x86
- {1169E6D1-1899-43D4-A500-07CE4235B388}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {1169E6D1-1899-43D4-A500-07CE4235B388}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {1169E6D1-1899-43D4-A500-07CE4235B388}.Debug|x86.Build.0 = Debug|x86
+ {A6BAD2BA-76BA-461C-8B6D-418607591247}.Release|x86.Build.0 = Release|x86
+ {1169E6D1-1899-43D4-A500-07CE4235B388}.Debug|Any CPU.ActiveCfg = Debug|x86
+ {1169E6D1-1899-43D4-A500-07CE4235B388}.Debug|Any CPU.Build.0 = Debug|x86
{1169E6D1-1899-43D4-A500-07CE4235B388}.Debug|x86.ActiveCfg = Debug|x86
- {1169E6D1-1899-43D4-A500-07CE4235B388}.Release|Any CPU.Build.0 = Release|Any CPU
- {1169E6D1-1899-43D4-A500-07CE4235B388}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {1169E6D1-1899-43D4-A500-07CE4235B388}.Release|x86.Build.0 = Release|x86
+ {1169E6D1-1899-43D4-A500-07CE4235B388}.Debug|x86.Build.0 = Debug|x86
+ {1169E6D1-1899-43D4-A500-07CE4235B388}.Release|Any CPU.ActiveCfg = Release|x86
+ {1169E6D1-1899-43D4-A500-07CE4235B388}.Release|Any CPU.Build.0 = Release|x86
{1169E6D1-1899-43D4-A500-07CE4235B388}.Release|x86.ActiveCfg = Release|x86
+ {1169E6D1-1899-43D4-A500-07CE4235B388}.Release|x86.Build.0 = Release|x86
{6D3D0F0D-348D-456A-A6ED-E9BD5EFABB6A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6D3D0F0D-348D-456A-A6ED-E9BD5EFABB6A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6D3D0F0D-348D-456A-A6ED-E9BD5EFABB6A}.Release|Any CPU.Build.0 = Release|Any CPU
@@ -163,6 +174,7 @@ Global
{704F66F1-5C7F-4326-A7AA-C604A3896D4E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{704F66F1-5C7F-4326-A7AA-C604A3896D4E}.Release|x86.Build.0 = Release|x86
{704F66F1-5C7F-4326-A7AA-C604A3896D4E}.Release|x86.ActiveCfg = Release|x86
+ {704F66F1-5C7F-4326-A7AA-C604A3896D4E}.Release|x86.Build.0 = Release|x86
{53DCA265-3C3C-42F9-B647-F72BA678122B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{53DCA265-3C3C-42F9-B647-F72BA678122B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{53DCA265-3C3C-42F9-B647-F72BA678122B}.Debug|x86.Build.0 = Debug|Any CPU
@@ -176,7 +188,7 @@ Global
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
- {6D3D0F0D-348D-456A-A6ED-E9BD5EFABB6A} = {89C4A682-2706-44A3-ADDC-BC273164C37E}
{1D18D788-F7EE-4585-A23B-34DC8EC63CB8} = {89C4A682-2706-44A3-ADDC-BC273164C37E}
+ {6D3D0F0D-348D-456A-A6ED-E9BD5EFABB6A} = {89C4A682-2706-44A3-ADDC-BC273164C37E}
EndGlobalSection
EndGlobal
3  ILSpy/MainWindow.xaml.cs
View
@@ -420,6 +420,9 @@ void ShowAssemblyList(AssemblyList assemblyList)
this.Title = "ILSpy";
else
this.Title = "ILSpy - " + assemblyList.ListName;
+ // activating another assembly list is a heavy change so trigger event
+ if (CurrentAssemblyListChanged != null)
+ CurrentAssemblyListChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
void assemblyList_Assemblies_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
Something went wrong with that request. Please try again.