Browse Source
git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@3248 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61shortcuts
29 changed files with 1990 additions and 1 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,28 @@
@@ -0,0 +1,28 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Christian Hornung" email="chhornung@googlemail.com"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using System.Reflection; |
||||
|
||||
// Information about this assembly is defined by the following
|
||||
// attributes.
|
||||
//
|
||||
// change them to the information which is associated with the assembly
|
||||
// you compile.
|
||||
|
||||
[assembly: AssemblyTitle("Reflector AddIn")] |
||||
[assembly: AssemblyDescription("Reflector AddIn for SharpDevelop")] |
||||
|
||||
#if DEBUG
|
||||
[assembly: AssemblyConfiguration("Debug")] |
||||
#else
|
||||
[assembly: AssemblyConfiguration("Release")] |
||||
#endif
|
||||
|
||||
[assembly: AssemblyTrademark("")] |
||||
[assembly: AssemblyCulture("")] |
||||
|
||||
[assembly: System.CLSCompliant(true)] |
@ -0,0 +1,33 @@
@@ -0,0 +1,33 @@
|
||||
<AddIn name = "ReflectorAddIn" |
||||
author = "Christian Hornung" |
||||
copyright = "prj:///doc/copyright.txt" |
||||
description = "Can open Lutz Roeder's .NET Reflector on a selected class or member."> |
||||
|
||||
<Manifest> |
||||
<Identity name="ReflectorAddIn" version="@ReflectorAddIn.dll" /> |
||||
</Manifest> |
||||
|
||||
<Runtime> |
||||
<Import assembly = "ReflectorAddIn.dll"/> |
||||
<Import assembly = ":ICSharpCode.SharpDevelop"/> |
||||
</Runtime> |
||||
|
||||
<!-- Text editor context menu --> |
||||
|
||||
<Path name = "/SharpDevelop/ViewContent/DefaultTextEditor/ClassMemberContextMenu"> |
||||
<MenuItem id="Reflector" type="Item" label="${res:ReflectorAddIn.OpenReflectorCommand}" class="ReflectorAddIn.TextEditorContextMenuCommand"/> |
||||
</Path> |
||||
|
||||
<Path name = "/SharpDevelop/ViewContent/DefaultTextEditor/ClassBookmarkContextMenu"> |
||||
<MenuItem id="Reflector" type="Item" label="${res:ReflectorAddIn.OpenReflectorCommand}" class="ReflectorAddIn.TextEditorContextMenuCommand"/> |
||||
</Path> |
||||
|
||||
<Path name = "/SharpDevelop/Pads/ClassBrowser/MemberContextMenu"> |
||||
<MenuItem id="Reflector" type="Item" label="${res:ReflectorAddIn.OpenReflectorCommand}" class="ReflectorAddIn.TextEditorContextMenuCommand"/> |
||||
</Path> |
||||
|
||||
<Path name = "/SharpDevelop/Pads/ClassBrowser/ClassContextMenu"> |
||||
<MenuItem id="Reflector" type="Item" label="${res:ReflectorAddIn.OpenReflectorCommand}" class="ReflectorAddIn.TextEditorContextMenuCommand"/> |
||||
</Path> |
||||
|
||||
</AddIn> |
@ -0,0 +1,97 @@
@@ -0,0 +1,97 @@
|
||||
<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
||||
<PropertyGroup> |
||||
<ProjectGuid>{8AA421C8-D7AF-4957-9F43-5135328ACB24}</ProjectGuid> |
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> |
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> |
||||
<OutputType>Library</OutputType> |
||||
<RootNamespace>ReflectorAddIn</RootNamespace> |
||||
<AssemblyName>ReflectorAddIn</AssemblyName> |
||||
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion> |
||||
<AppDesignerFolder>Properties</AppDesignerFolder> |
||||
<OutputPath>..\..\..\..\..\..\AddIns\AddIns\Misc\ReflectorAddIn\</OutputPath> |
||||
<AllowUnsafeBlocks>False</AllowUnsafeBlocks> |
||||
<NoStdLib>False</NoStdLib> |
||||
<WarningLevel>4</WarningLevel> |
||||
<TreatWarningsAsErrors>false</TreatWarningsAsErrors> |
||||
</PropertyGroup> |
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' "> |
||||
<DebugSymbols>true</DebugSymbols> |
||||
<DebugType>Full</DebugType> |
||||
<Optimize>False</Optimize> |
||||
<CheckForOverflowUnderflow>True</CheckForOverflowUnderflow> |
||||
<DefineConstants>DEBUG;TRACE</DefineConstants> |
||||
</PropertyGroup> |
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Release' "> |
||||
<DebugSymbols>False</DebugSymbols> |
||||
<DebugType>None</DebugType> |
||||
<Optimize>True</Optimize> |
||||
<CheckForOverflowUnderflow>False</CheckForOverflowUnderflow> |
||||
<DefineConstants>TRACE</DefineConstants> |
||||
</PropertyGroup> |
||||
<PropertyGroup Condition=" '$(Platform)' == 'AnyCPU' "> |
||||
<RegisterForComInterop>False</RegisterForComInterop> |
||||
<GenerateSerializationAssemblies>Auto</GenerateSerializationAssemblies> |
||||
<BaseAddress>4194304</BaseAddress> |
||||
<PlatformTarget>AnyCPU</PlatformTarget> |
||||
<FileAlignment>4096</FileAlignment> |
||||
</PropertyGroup> |
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.Targets" /> |
||||
<ItemGroup> |
||||
<Reference Include="Reflector.IpcServer"> |
||||
<HintPath>..\RequiredLibraries\Reflector.IpcServer.dll</HintPath> |
||||
</Reference> |
||||
<Reference Include="System" /> |
||||
<Reference Include="System.Core"> |
||||
<RequiredTargetFramework>3.5</RequiredTargetFramework> |
||||
</Reference> |
||||
<Reference Include="System.Drawing" /> |
||||
<Reference Include="System.Runtime.Remoting" /> |
||||
<Reference Include="System.Windows.Forms" /> |
||||
</ItemGroup> |
||||
<ItemGroup> |
||||
<Compile Include="..\..\..\..\..\Main\GlobalAssemblyInfo.cs"> |
||||
<Link>Properties\GlobalAssemblyInfo.cs</Link> |
||||
</Compile> |
||||
<Compile Include="Properties\AssemblyInfo.cs" /> |
||||
<Compile Include="Src\ReflectorController.cs" /> |
||||
<Compile Include="Src\ReflectorSetupHelper.cs" /> |
||||
<Compile Include="Src\SetReflectorPathDialog.cs" /> |
||||
<Compile Include="Src\SetReflectorPathDialog.Designer.cs"> |
||||
<DependentUpon>SetReflectorPathDialog.cs</DependentUpon> |
||||
</Compile> |
||||
<Compile Include="Src\TextEditorContextMenuCommand.cs" /> |
||||
<None Include="..\RequiredLibraries\Reflector.IpcServer.AddIn.dll"> |
||||
<Link>Reflector.IpcServer.AddIn.dll</Link> |
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory> |
||||
</None> |
||||
<None Include="ReflectorAddIn.addin"> |
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory> |
||||
</None> |
||||
<EmbeddedResource Include="Src\SetReflectorPathDialog.resx"> |
||||
<DependentUpon>SetReflectorPathDialog.cs</DependentUpon> |
||||
</EmbeddedResource> |
||||
</ItemGroup> |
||||
<ItemGroup> |
||||
<Folder Include="Src" /> |
||||
<ProjectReference Include="..\..\..\..\..\Libraries\ICSharpCode.TextEditor\Project\ICSharpCode.TextEditor.csproj"> |
||||
<Project>{2D18BE89-D210-49EB-A9DD-2246FBB3DF6D}</Project> |
||||
<Name>ICSharpCode.TextEditor</Name> |
||||
<Private>False</Private> |
||||
</ProjectReference> |
||||
<ProjectReference Include="..\..\..\..\..\Main\Base\Project\ICSharpCode.SharpDevelop.csproj"> |
||||
<Project>{2748AD25-9C63-4E12-877B-4DCE96FBED54}</Project> |
||||
<Name>ICSharpCode.SharpDevelop</Name> |
||||
<Private>False</Private> |
||||
</ProjectReference> |
||||
<ProjectReference Include="..\..\..\..\..\Main\Core\Project\ICSharpCode.Core.csproj"> |
||||
<Project>{35CEF10F-2D4C-45F2-9DD1-161E0FEC583C}</Project> |
||||
<Name>ICSharpCode.Core</Name> |
||||
<Private>False</Private> |
||||
</ProjectReference> |
||||
<ProjectReference Include="..\..\..\..\..\Main\ICSharpCode.SharpDevelop.Dom\Project\ICSharpCode.SharpDevelop.Dom.csproj"> |
||||
<Project>{924EE450-603D-49C1-A8E5-4AFAA31CE6F3}</Project> |
||||
<Name>ICSharpCode.SharpDevelop.Dom</Name> |
||||
<Private>False</Private> |
||||
</ProjectReference> |
||||
</ItemGroup> |
||||
</Project> |
@ -0,0 +1,179 @@
@@ -0,0 +1,179 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Christian Hornung" email="chhornung@googlemail.com"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Diagnostics; |
||||
using System.IO; |
||||
using System.Runtime.Remoting; |
||||
using System.Runtime.Remoting.Channels; |
||||
using System.Runtime.Remoting.Channels.Ipc; |
||||
using System.Text; |
||||
|
||||
using ICSharpCode.Core; |
||||
|
||||
using Reflector.IpcServer; |
||||
|
||||
namespace ReflectorAddIn |
||||
{ |
||||
/// <summary>
|
||||
/// Controls Lutz Roeders's .NET Reflector.
|
||||
/// </summary>
|
||||
public static class ReflectorController |
||||
{ |
||||
#region Connecting
|
||||
|
||||
public static IReflectorService SafeConnect(System.Windows.Forms.IWin32Window owner) |
||||
{ |
||||
try { |
||||
return Connect(owner); |
||||
} catch (RemotingException ex) { |
||||
ShowRemotingError(ex); |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
public static void ShowRemotingError(Exception ex) |
||||
{ |
||||
MessageService.ShowError(String.Concat(ResourceService.GetString("ReflectorAddIn.ReflectorRemotingFailed"), Environment.NewLine, UnwindExceptionMessages(ex))); |
||||
} |
||||
|
||||
static string UnwindExceptionMessages(Exception ex) |
||||
{ |
||||
StringBuilder sb = new StringBuilder(); |
||||
do { |
||||
if (sb.Length > 0) sb.AppendLine(); |
||||
sb.Append(ex.Message); |
||||
} while ((ex = ex.InnerException) != null); |
||||
return sb.ToString(); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Ensures that an instance of Reflector is running and connects to it.
|
||||
/// </summary>
|
||||
/// <returns>The <see cref="IReflectorService"/> that can be used to control the running instance of Reflector.</returns>
|
||||
public static IReflectorService Connect(System.Windows.Forms.IWin32Window owner) |
||||
{ |
||||
IReflectorService service = null; |
||||
try { |
||||
service = TryConnect(); |
||||
} catch (RemotingException) { |
||||
} |
||||
if (service != null) return service; |
||||
|
||||
// Get Reflector path and set it up
|
||||
string reflectorExeFullPath = ReflectorSetupHelper.GetReflectorExeFullPathInteractive(owner); |
||||
if (reflectorExeFullPath == null) return null; |
||||
if (!ReflectorSetupHelper.SetupReflector(reflectorExeFullPath)) return null; |
||||
|
||||
// start Reflector
|
||||
ProcessStartInfo psi = new ProcessStartInfo(reflectorExeFullPath); |
||||
psi.WorkingDirectory = Path.GetDirectoryName(psi.FileName); |
||||
using(Process p = Process.Start(psi)) { |
||||
p.WaitForInputIdle(7500); |
||||
} |
||||
|
||||
Exception lastException = null; |
||||
DateTime start = DateTime.UtcNow; |
||||
do { |
||||
try { |
||||
service = TryConnect(); |
||||
if (service != null) return service; |
||||
} catch (RemotingException ex) { |
||||
lastException = ex; |
||||
} |
||||
System.Threading.Thread.Sleep(250); |
||||
} while ((DateTime.UtcNow - start).TotalSeconds <= 10); |
||||
|
||||
if (lastException != null) { |
||||
throw lastException; |
||||
} |
||||
|
||||
return null; |
||||
} |
||||
|
||||
static IReflectorService TryConnect() |
||||
{ |
||||
EnsureRemotingInitialized(); |
||||
IReflectorService service = RemotingServices.Connect(typeof(IReflectorService), "ipc://ReflectorService/ReflectorService.rem") as IReflectorService; |
||||
if (service == null || !service.CheckIsThere()) { |
||||
throw new RemotingException("Error connecting to Reflector."); |
||||
} |
||||
return service; |
||||
} |
||||
|
||||
public static void Disconnect(IReflectorService service) |
||||
{ |
||||
try { |
||||
RemotingServices.Disconnect((MarshalByRefObject)service); |
||||
} catch (RemotingException) { |
||||
} |
||||
} |
||||
|
||||
#endregion
|
||||
|
||||
// ********************************************************************************************************************************
|
||||
|
||||
#region Remoting initialization
|
||||
|
||||
static IpcClientChannel channel; |
||||
|
||||
static void EnsureRemotingInitialized() |
||||
{ |
||||
if (channel == null) { |
||||
|
||||
bool success = false; |
||||
|
||||
try { |
||||
|
||||
Dictionary<string, object> props = new Dictionary<string, object>(); |
||||
props.Add("name", "Reflector IPC client"); |
||||
props.Add("secure", true); |
||||
props.Add("connectionTimeout", 2000); |
||||
|
||||
channel = new IpcClientChannel(props, null); |
||||
ChannelServices.RegisterChannel(channel, true); |
||||
|
||||
success = true; |
||||
|
||||
} finally { |
||||
if (!success && channel != null) { |
||||
try { |
||||
ChannelServices.UnregisterChannel(channel); |
||||
} catch (RemotingException) { |
||||
} |
||||
channel = null; |
||||
} |
||||
} |
||||
|
||||
} |
||||
} |
||||
|
||||
#endregion
|
||||
|
||||
// ********************************************************************************************************************************
|
||||
|
||||
public static void TryGoTo(CodeElementInfo element, System.Windows.Forms.IWin32Window owner) |
||||
{ |
||||
IReflectorService s = null; |
||||
try { |
||||
|
||||
s = SafeConnect(owner); |
||||
if (s == null) return; |
||||
|
||||
s.GoTo(element); |
||||
|
||||
} catch (System.Runtime.Remoting.RemotingException ex) { |
||||
ShowRemotingError(ex); |
||||
} finally { |
||||
if (s != null) { |
||||
Disconnect(s); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,126 @@
@@ -0,0 +1,126 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Christian Hornung" email="chhornung@googlemail.com"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.IO; |
||||
using System.Text.RegularExpressions; |
||||
using System.Windows.Forms; |
||||
|
||||
using ICSharpCode.Core; |
||||
|
||||
namespace ReflectorAddIn |
||||
{ |
||||
internal static class ReflectorSetupHelper |
||||
{ |
||||
internal const string ReflectorExePathPropertyName = "ReflectorAddIn.ReflectorExePath"; |
||||
|
||||
/// <summary>
|
||||
/// Gets the full path of Reflector.exe, asking the user for it if it
|
||||
/// has not been set.
|
||||
/// </summary>
|
||||
/// <param name="owner">The owner for the path selection dialog, if it is needed.</param>
|
||||
/// <returns>The full path of Reflector.exe, or <c>null</c> if the path was unknown and the user cancelled the path selection dialog.</returns>
|
||||
internal static string GetReflectorExeFullPathInteractive(IWin32Window owner) { |
||||
string path = PropertyService.Get(ReflectorExePathPropertyName); |
||||
string askReason = null; |
||||
|
||||
if (String.IsNullOrEmpty(path)) { |
||||
askReason = ResourceService.GetString("ReflectorAddIn.ReflectorPathNotSet"); |
||||
} else if (!File.Exists(path)) { |
||||
askReason = ResourceService.GetString("ReflectorAddIn.ReflectorDoesNotExist"); |
||||
} |
||||
|
||||
if (askReason != null) { |
||||
using(SetReflectorPathDialog dialog = new SetReflectorPathDialog(path, askReason)) { |
||||
|
||||
if (dialog.ShowDialog(owner) != DialogResult.OK || !File.Exists(dialog.SelectedFile)) { |
||||
return null; |
||||
} |
||||
|
||||
path = dialog.SelectedFile; |
||||
PropertyService.Set(ReflectorExePathPropertyName, path); |
||||
|
||||
} |
||||
} |
||||
|
||||
return path; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Sets up Reflector at the given full path to Reflector.exe so that
|
||||
/// it loads the IpcServer AddIn.
|
||||
/// </summary>
|
||||
internal static bool SetupReflector(string path) { |
||||
|
||||
const string IpcServerDllName = "Reflector.IpcServer.dll"; |
||||
const string IpcServerAddInDllName = "Reflector.IpcServer.AddIn.dll"; |
||||
const string ReflectorConfigName = "Reflector.cfg"; |
||||
|
||||
try { |
||||
|
||||
// Copy the DLLs
|
||||
string targetPath = Path.GetDirectoryName(path); |
||||
string sourcePath = Path.GetDirectoryName(new Uri(typeof(ReflectorSetupHelper).Assembly.CodeBase, UriKind.Absolute).LocalPath); |
||||
|
||||
string ipcServerDllTargetPath = Path.Combine(targetPath, IpcServerDllName); |
||||
string ipcServerAddInDllTargetPath = Path.Combine(targetPath, IpcServerAddInDllName); |
||||
|
||||
File.Copy(Path.Combine(sourcePath, IpcServerDllName), ipcServerDllTargetPath, true); |
||||
File.Copy(Path.Combine(sourcePath, IpcServerAddInDllName), ipcServerAddInDllTargetPath, true); |
||||
|
||||
// Adjust the configuration
|
||||
string cfgFileName = Path.Combine(targetPath, ReflectorConfigName); |
||||
string cfgContent; |
||||
if (File.Exists(cfgFileName)) { |
||||
cfgContent = File.ReadAllText(cfgFileName); |
||||
} else { |
||||
cfgContent = Environment.NewLine; |
||||
} |
||||
|
||||
int insertionIndex = -1; |
||||
bool ipcServerAddInFound = false; |
||||
Match m = Regex.Match(cfgContent, @"\[AddInManager\](?:\s*""(?<1>[^""]*)"")*\s*(?:\[|\z)", RegexOptions.CultureInvariant | RegexOptions.IgnoreCase | RegexOptions.Singleline); |
||||
if (m != null && m.Success) { |
||||
|
||||
foreach (Capture c in m.Groups[1].Captures) { |
||||
if (String.Equals(c.Value, ipcServerAddInDllTargetPath, StringComparison.InvariantCultureIgnoreCase)) { |
||||
ipcServerAddInFound = true; |
||||
} |
||||
insertionIndex = c.Index + c.Length + 1; |
||||
} |
||||
|
||||
} else { |
||||
|
||||
cfgContent += Environment.NewLine + "[AddInManager]" + Environment.NewLine; |
||||
insertionIndex = cfgContent.Length - Environment.NewLine.Length; |
||||
|
||||
} |
||||
|
||||
if (!ipcServerAddInFound) { |
||||
if (insertionIndex == -1) { |
||||
MessageService.ShowError("Cannot configure Reflector because the configuration file could not be parsed."); |
||||
} else { |
||||
cfgContent = cfgContent.Insert(insertionIndex, Environment.NewLine + "\"" + ipcServerAddInDllTargetPath + "\""); |
||||
File.Copy(cfgFileName, Path.ChangeExtension(cfgFileName, ".cfg.bak"), true); |
||||
File.WriteAllText(cfgFileName, cfgContent, System.Text.Encoding.Default); |
||||
} |
||||
} |
||||
|
||||
return true; |
||||
|
||||
|
||||
} catch (IOException ex) { |
||||
MessageService.ShowWarning(ResourceService.GetString("ReflectorAddIn.ErrorReflectorSetup") + Environment.NewLine + ex.Message); |
||||
} catch (UnauthorizedAccessException ex) { |
||||
MessageService.ShowWarning(ResourceService.GetString("ReflectorAddIn.ErrorReflectorSetup") + Environment.NewLine + ex.Message); |
||||
} |
||||
|
||||
return false; |
||||
|
||||
} |
||||
} |
||||
} |
@ -0,0 +1,166 @@
@@ -0,0 +1,166 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Christian Hornung" email="chhornung@googlemail.com"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
namespace ReflectorAddIn |
||||
{ |
||||
partial class SetReflectorPathDialog |
||||
{ |
||||
/// <summary>
|
||||
/// Designer variable used to keep track of non-visual components.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null; |
||||
|
||||
/// <summary>
|
||||
/// Disposes resources used by the form.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing) |
||||
{ |
||||
if (disposing) { |
||||
if (components != null) { |
||||
components.Dispose(); |
||||
} |
||||
} |
||||
base.Dispose(disposing); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// This method is required for Windows Forms designer support.
|
||||
/// Do not change the method contents inside the source code editor. The Forms designer might
|
||||
/// not be able to load this method if it was changed manually.
|
||||
/// </summary>
|
||||
private void InitializeComponent() |
||||
{ |
||||
System.Windows.Forms.Button pshOK; |
||||
System.Windows.Forms.Button pshCancel; |
||||
System.Windows.Forms.Label txtReflectorExplanation; |
||||
System.Windows.Forms.LinkLabel linkReflector; |
||||
System.Windows.Forms.GroupBox grpPath; |
||||
System.Windows.Forms.Button pshBrowse; |
||||
this.slePath = new System.Windows.Forms.TextBox(); |
||||
this.txtReason = new System.Windows.Forms.Label(); |
||||
pshOK = new System.Windows.Forms.Button(); |
||||
pshCancel = new System.Windows.Forms.Button(); |
||||
txtReflectorExplanation = new System.Windows.Forms.Label(); |
||||
linkReflector = new System.Windows.Forms.LinkLabel(); |
||||
grpPath = new System.Windows.Forms.GroupBox(); |
||||
pshBrowse = new System.Windows.Forms.Button(); |
||||
grpPath.SuspendLayout(); |
||||
this.SuspendLayout(); |
||||
//
|
||||
// pshOK
|
||||
//
|
||||
pshOK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); |
||||
pshOK.DialogResult = System.Windows.Forms.DialogResult.OK; |
||||
pshOK.Location = new System.Drawing.Point(272, 187); |
||||
pshOK.Name = "pshOK"; |
||||
pshOK.Size = new System.Drawing.Size(75, 23); |
||||
pshOK.TabIndex = 0; |
||||
pshOK.Text = "${res:Global.OKButtonText}"; |
||||
pshOK.UseVisualStyleBackColor = true; |
||||
//
|
||||
// pshCancel
|
||||
//
|
||||
pshCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); |
||||
pshCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; |
||||
pshCancel.Location = new System.Drawing.Point(353, 187); |
||||
pshCancel.Name = "pshCancel"; |
||||
pshCancel.Size = new System.Drawing.Size(75, 23); |
||||
pshCancel.TabIndex = 1; |
||||
pshCancel.Text = "${res:Global.CancelButtonText}"; |
||||
pshCancel.UseVisualStyleBackColor = true; |
||||
//
|
||||
// txtReflectorExplanation
|
||||
//
|
||||
txtReflectorExplanation.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) |
||||
| System.Windows.Forms.AnchorStyles.Right))); |
||||
txtReflectorExplanation.Location = new System.Drawing.Point(12, 45); |
||||
txtReflectorExplanation.Name = "txtReflectorExplanation"; |
||||
txtReflectorExplanation.Size = new System.Drawing.Size(416, 46); |
||||
txtReflectorExplanation.TabIndex = 3; |
||||
txtReflectorExplanation.Text = "${res:ReflectorAddIn.SetReflectorPathDialog.ReflectorInfo}"; |
||||
//
|
||||
// linkReflector
|
||||
//
|
||||
linkReflector.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) |
||||
| System.Windows.Forms.AnchorStyles.Right))); |
||||
linkReflector.Location = new System.Drawing.Point(12, 91); |
||||
linkReflector.Name = "linkReflector"; |
||||
linkReflector.Size = new System.Drawing.Size(416, 23); |
||||
linkReflector.TabIndex = 4; |
||||
linkReflector.TabStop = true; |
||||
linkReflector.Text = "http://www.aisto.com/roeder/dotnet/"; |
||||
linkReflector.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.LinkReflectorLinkClicked); |
||||
//
|
||||
// grpPath
|
||||
//
|
||||
grpPath.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) |
||||
| System.Windows.Forms.AnchorStyles.Right))); |
||||
grpPath.Controls.Add(pshBrowse); |
||||
grpPath.Controls.Add(this.slePath); |
||||
grpPath.Location = new System.Drawing.Point(12, 127); |
||||
grpPath.Name = "grpPath"; |
||||
grpPath.Size = new System.Drawing.Size(416, 51); |
||||
grpPath.TabIndex = 5; |
||||
grpPath.TabStop = false; |
||||
grpPath.Text = "${res:ReflectorAddIn.SetReflectorPathDialog.PathToReflectorExe}"; |
||||
//
|
||||
// pshBrowse
|
||||
//
|
||||
pshBrowse.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); |
||||
pshBrowse.Location = new System.Drawing.Point(303, 17); |
||||
pshBrowse.Name = "pshBrowse"; |
||||
pshBrowse.Size = new System.Drawing.Size(107, 23); |
||||
pshBrowse.TabIndex = 1; |
||||
pshBrowse.Text = "${res:Global.BrowseButtonText}"; |
||||
pshBrowse.UseVisualStyleBackColor = true; |
||||
pshBrowse.Click += new System.EventHandler(this.PshBrowseClick); |
||||
//
|
||||
// slePath
|
||||
//
|
||||
this.slePath.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) |
||||
| System.Windows.Forms.AnchorStyles.Right))); |
||||
this.slePath.Location = new System.Drawing.Point(6, 19); |
||||
this.slePath.Name = "slePath"; |
||||
this.slePath.Size = new System.Drawing.Size(291, 20); |
||||
this.slePath.TabIndex = 0; |
||||
//
|
||||
// txtReason
|
||||
//
|
||||
this.txtReason.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) |
||||
| System.Windows.Forms.AnchorStyles.Right))); |
||||
this.txtReason.Location = new System.Drawing.Point(12, 9); |
||||
this.txtReason.Name = "txtReason"; |
||||
this.txtReason.Size = new System.Drawing.Size(416, 36); |
||||
this.txtReason.TabIndex = 2; |
||||
//
|
||||
// SetReflectorPathDialog
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); |
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; |
||||
this.ClientSize = new System.Drawing.Size(440, 222); |
||||
this.Controls.Add(grpPath); |
||||
this.Controls.Add(linkReflector); |
||||
this.Controls.Add(txtReflectorExplanation); |
||||
this.Controls.Add(this.txtReason); |
||||
this.Controls.Add(pshCancel); |
||||
this.Controls.Add(pshOK); |
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; |
||||
this.MaximizeBox = false; |
||||
this.MinimizeBox = false; |
||||
this.Name = "SetReflectorPathDialog"; |
||||
this.ShowIcon = false; |
||||
this.ShowInTaskbar = false; |
||||
this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide; |
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; |
||||
grpPath.ResumeLayout(false); |
||||
grpPath.PerformLayout(); |
||||
this.ResumeLayout(false); |
||||
} |
||||
private System.Windows.Forms.TextBox slePath; |
||||
private System.Windows.Forms.Label txtReason; |
||||
} |
||||
} |
@ -0,0 +1,79 @@
@@ -0,0 +1,79 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Christian Hornung" email="chhornung@googlemail.com"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Drawing; |
||||
using System.Windows.Forms; |
||||
|
||||
using ICSharpCode.Core; |
||||
|
||||
namespace ReflectorAddIn |
||||
{ |
||||
/// <summary>
|
||||
/// Asks the user for the path to Reflector.exe.
|
||||
/// </summary>
|
||||
internal partial class SetReflectorPathDialog : Form |
||||
{ |
||||
public SetReflectorPathDialog(string oldPath, string reason) |
||||
{ |
||||
//
|
||||
// The InitializeComponent() call is required for Windows Forms designer support.
|
||||
//
|
||||
InitializeComponent(); |
||||
|
||||
this.Text = ResourceService.GetString("ReflectorAddIn.SetReflectorPathDialogTitle"); |
||||
|
||||
Translate(this); |
||||
|
||||
this.txtReason.Text = reason; |
||||
if (!String.IsNullOrEmpty(oldPath)) { |
||||
this.slePath.Text = oldPath; |
||||
} |
||||
} |
||||
|
||||
private static void Translate(Control container) { |
||||
container.Text = StringParser.Parse(container.Text); |
||||
foreach (Control c in container.Controls) { |
||||
Translate(c); |
||||
} |
||||
} |
||||
|
||||
void LinkReflectorLinkClicked(object sender, LinkLabelLinkClickedEventArgs e) |
||||
{ |
||||
try { |
||||
using(System.Diagnostics.Process.Start("http://www.aisto.com/roeder/dotnet/")) { |
||||
} |
||||
} catch (Exception ex) { |
||||
MessageService.ShowError(ex.Message); |
||||
} |
||||
} |
||||
|
||||
void PshBrowseClick(object sender, EventArgs e) |
||||
{ |
||||
using(OpenFileDialog dialog = new OpenFileDialog()) { |
||||
|
||||
dialog.Title = this.Text; |
||||
dialog.DefaultExt = "exe"; |
||||
dialog.RestoreDirectory = true; |
||||
dialog.Filter = "Reflector.exe|Reflector.exe"; |
||||
|
||||
if (!String.IsNullOrEmpty(this.slePath.Text)) { |
||||
dialog.FileName = this.slePath.Text; |
||||
} |
||||
|
||||
if (dialog.ShowDialog(this) == DialogResult.OK) { |
||||
this.slePath.Text = dialog.FileName; |
||||
} |
||||
|
||||
} |
||||
} |
||||
|
||||
public string SelectedFile { |
||||
get { return this.slePath.Text; } |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,138 @@
@@ -0,0 +1,138 @@
|
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<root> |
||||
<!-- |
||||
Microsoft ResX Schema |
||||
|
||||
Version 2.0 |
||||
|
||||
The primary goals of this format is to allow a simple XML format |
||||
that is mostly human readable. The generation and parsing of the |
||||
various data types are done through the TypeConverter classes |
||||
associated with the data types. |
||||
|
||||
Example: |
||||
|
||||
... ado.net/XML headers & schema ... |
||||
<resheader name="resmimetype">text/microsoft-resx</resheader> |
||||
<resheader name="version">2.0</resheader> |
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> |
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> |
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> |
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> |
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> |
||||
<value>[base64 mime encoded serialized .NET Framework object]</value> |
||||
</data> |
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> |
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> |
||||
<comment>This is a comment</comment> |
||||
</data> |
||||
|
||||
There are any number of "resheader" rows that contain simple |
||||
name/value pairs. |
||||
|
||||
Each data row contains a name, and value. The row also contains a |
||||
type or mimetype. Type corresponds to a .NET class that support |
||||
text/value conversion through the TypeConverter architecture. |
||||
Classes that don't support this are serialized and stored with the |
||||
mimetype set. |
||||
|
||||
The mimetype is used for serialized objects, and tells the |
||||
ResXResourceReader how to depersist the object. This is currently not |
||||
extensible. For a given mimetype the value must be set accordingly: |
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format |
||||
that the ResXResourceWriter will generate, however the reader can |
||||
read any of the formats listed below. |
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64 |
||||
value : The object must be serialized with |
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter |
||||
: and then encoded with base64 encoding. |
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64 |
||||
value : The object must be serialized with |
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter |
||||
: and then encoded with base64 encoding. |
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64 |
||||
value : The object must be serialized into a byte array |
||||
: using a System.ComponentModel.TypeConverter |
||||
: and then encoded with base64 encoding. |
||||
--> |
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> |
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> |
||||
<xsd:element name="root" msdata:IsDataSet="true"> |
||||
<xsd:complexType> |
||||
<xsd:choice maxOccurs="unbounded"> |
||||
<xsd:element name="metadata"> |
||||
<xsd:complexType> |
||||
<xsd:sequence> |
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" /> |
||||
</xsd:sequence> |
||||
<xsd:attribute name="name" use="required" type="xsd:string" /> |
||||
<xsd:attribute name="type" type="xsd:string" /> |
||||
<xsd:attribute name="mimetype" type="xsd:string" /> |
||||
<xsd:attribute ref="xml:space" /> |
||||
</xsd:complexType> |
||||
</xsd:element> |
||||
<xsd:element name="assembly"> |
||||
<xsd:complexType> |
||||
<xsd:attribute name="alias" type="xsd:string" /> |
||||
<xsd:attribute name="name" type="xsd:string" /> |
||||
</xsd:complexType> |
||||
</xsd:element> |
||||
<xsd:element name="data"> |
||||
<xsd:complexType> |
||||
<xsd:sequence> |
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> |
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> |
||||
</xsd:sequence> |
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> |
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> |
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> |
||||
<xsd:attribute ref="xml:space" /> |
||||
</xsd:complexType> |
||||
</xsd:element> |
||||
<xsd:element name="resheader"> |
||||
<xsd:complexType> |
||||
<xsd:sequence> |
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> |
||||
</xsd:sequence> |
||||
<xsd:attribute name="name" type="xsd:string" use="required" /> |
||||
</xsd:complexType> |
||||
</xsd:element> |
||||
</xsd:choice> |
||||
</xsd:complexType> |
||||
</xsd:element> |
||||
</xsd:schema> |
||||
<resheader name="resmimetype"> |
||||
<value>text/microsoft-resx</value> |
||||
</resheader> |
||||
<resheader name="version"> |
||||
<value>2.0</value> |
||||
</resheader> |
||||
<resheader name="reader"> |
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> |
||||
</resheader> |
||||
<resheader name="writer"> |
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> |
||||
</resheader> |
||||
<metadata name="pshOK.GenerateMember" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> |
||||
<value>False</value> |
||||
</metadata> |
||||
<metadata name="pshCancel.GenerateMember" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> |
||||
<value>False</value> |
||||
</metadata> |
||||
<metadata name="txtReflectorExplanation.GenerateMember" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> |
||||
<value>False</value> |
||||
</metadata> |
||||
<metadata name="linkReflector.GenerateMember" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> |
||||
<value>False</value> |
||||
</metadata> |
||||
<metadata name="grpPath.GenerateMember" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> |
||||
<value>False</value> |
||||
</metadata> |
||||
<metadata name="pshBrowse.GenerateMember" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> |
||||
<value>False</value> |
||||
</metadata> |
||||
</root> |
@ -0,0 +1,198 @@
@@ -0,0 +1,198 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Christian Hornung" email="chhornung@googlemail.com"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Windows.Forms; |
||||
|
||||
using ICSharpCode.Core; |
||||
using ICSharpCode.SharpDevelop.Bookmarks; |
||||
using ICSharpCode.SharpDevelop.Dom; |
||||
using ICSharpCode.SharpDevelop.Gui; |
||||
using ICSharpCode.SharpDevelop.Gui.ClassBrowser; |
||||
using ICSharpCode.SharpDevelop.Project; |
||||
using Reflector.IpcServer; |
||||
|
||||
namespace ReflectorAddIn |
||||
{ |
||||
/// <summary>
|
||||
/// Implements a menu command to position .NET Reflector on a class
|
||||
/// or class member.
|
||||
/// </summary>
|
||||
public sealed class TextEditorContextMenuCommand : AbstractMenuCommand |
||||
{ |
||||
public override void Run() |
||||
{ |
||||
IClass c; |
||||
IMember m; |
||||
|
||||
MemberNode mn = this.Owner as MemberNode; |
||||
if (mn != null) { |
||||
m = mn.Member; |
||||
c = m.DeclaringType; |
||||
} else { |
||||
ClassNode cn = this.Owner as ClassNode; |
||||
if (cn != null) { |
||||
c = cn.Class; |
||||
m = null; |
||||
} else { |
||||
ClassMemberBookmark cmbm = this.Owner as ClassMemberBookmark; |
||||
if (cmbm != null) { |
||||
m = cmbm.Member; |
||||
c = m.DeclaringType; |
||||
} else { |
||||
ClassBookmark cbm = this.Owner as ClassBookmark; |
||||
if (cbm != null) { |
||||
c = cbm.Class; |
||||
m = null; |
||||
} else { |
||||
MessageService.ShowWarning("Reflector AddIn: Could not determine the class for the selected element. Owner: " + ((this.Owner == null) ? "<null>" : this.Owner.ToString())); |
||||
return; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
if (c == null) { |
||||
MessageService.ShowWarning("Reflector AddIn: Could not determine the class for the selected element (known owner). Owner: " + this.Owner.ToString()); |
||||
return; |
||||
} |
||||
|
||||
|
||||
CodeElementInfo element = new CodeElementInfo(); |
||||
|
||||
// Try to find the assembly which contains the resolved type
|
||||
IProjectContent pc = c.ProjectContent; |
||||
ReflectionProjectContent rpc = pc as ReflectionProjectContent; |
||||
if (rpc != null) { |
||||
element.AssemblyLocation = rpc.AssemblyLocation; |
||||
} else { |
||||
IProject project = pc.Project as IProject; |
||||
if (project != null) { |
||||
element.AssemblyLocation = project.OutputAssemblyFullPath; |
||||
} |
||||
} |
||||
|
||||
if (String.IsNullOrEmpty(element.AssemblyLocation)) { |
||||
MessageService.ShowWarning("Reflector AddIn: Could not determine the assembly location for " + c.ToString() + "."); |
||||
return; |
||||
} |
||||
|
||||
|
||||
SetNamespaceAndTypeNames(element.Type, c); |
||||
|
||||
if (m != null) { |
||||
element.MemberName = m.Name; |
||||
element.MemberReturnType = ConvertType(m.ReturnType); |
||||
|
||||
IMethod method = m as IMethod; |
||||
if (method != null) { |
||||
if (method.IsConstructor) { |
||||
element.MemberType = MemberType.Constructor; |
||||
element.MemberName = method.IsStatic ? ".cctor" : ".ctor"; |
||||
} else { |
||||
element.MemberType = MemberType.Method; |
||||
} |
||||
element.MemberTypeArgumentCount = method.TypeParameters.Count; |
||||
element.MemberParameters = ConvertParameters(method.Parameters); |
||||
} else { |
||||
|
||||
IField field = m as IField; |
||||
if (field != null && !field.IsLocalVariable) { |
||||
element.MemberType = MemberType.Field; |
||||
} else { |
||||
|
||||
IProperty property = m as IProperty; |
||||
if (property != null) { |
||||
element.MemberType = MemberType.Property; |
||||
element.MemberParameters = ConvertParameters(property.Parameters); |
||||
if (property.IsIndexer) { |
||||
// TODO: Support indexers with different names using DefaultMemberAttribute
|
||||
element.MemberName = "Item"; |
||||
} |
||||
} else { |
||||
|
||||
IEvent e = m as IEvent; |
||||
if (e != null) { |
||||
// Currently I consider events to be uniquely identified by name and containing type.
|
||||
element.MemberType = MemberType.Event; |
||||
} |
||||
|
||||
} |
||||
|
||||
} |
||||
|
||||
} |
||||
} |
||||
|
||||
|
||||
try { |
||||
|
||||
LoggingService.Debug("ReflectorAddIn: Trying to go to " + element.ToString()); |
||||
|
||||
Application.DoEvents(); |
||||
Cursor.Current = Cursors.WaitCursor; |
||||
|
||||
ReflectorController.TryGoTo(element, WorkbenchSingleton.MainForm); |
||||
|
||||
} finally { |
||||
Cursor.Current = Cursors.Default; |
||||
} |
||||
} |
||||
|
||||
static void SetNamespaceAndTypeNames(CodeTypeInfo t, IClass c) |
||||
{ |
||||
Stack<IClass> outerClasses = new Stack<IClass>(); |
||||
do { |
||||
outerClasses.Push(c); |
||||
} while ((c = c.DeclaringType) != null); |
||||
|
||||
t.Namespace = outerClasses.Peek().Namespace; |
||||
|
||||
List<string> types = new List<string>(); |
||||
List<int> typeArgumentCount = new List<int>(); |
||||
while (outerClasses.Count > 0) { |
||||
c = outerClasses.Pop(); |
||||
types.Add(c.Name); |
||||
typeArgumentCount.Add(c.TypeParameters.Count); |
||||
} |
||||
t.TypeNames = types.ToArray(); |
||||
t.TypeArgumentCount = typeArgumentCount.ToArray(); |
||||
} |
||||
|
||||
static CodeTypeInfo ConvertType(IReturnType rt) |
||||
{ |
||||
if (rt == null) return null; |
||||
|
||||
if (rt.IsArrayReturnType) { |
||||
ArrayReturnType art = rt.CastToArrayReturnType(); |
||||
CodeTypeInfo cti = new CodeTypeInfo(); |
||||
cti.ArrayElementType = ConvertType(art.ArrayElementType); |
||||
cti.ArrayDimensions = art.ArrayDimensions; |
||||
return cti; |
||||
} |
||||
|
||||
IClass c = rt.GetUnderlyingClass(); |
||||
if (c != null) { |
||||
CodeTypeInfo cti = new CodeTypeInfo(); |
||||
SetNamespaceAndTypeNames(cti, c); |
||||
return cti; |
||||
} |
||||
|
||||
return null; |
||||
} |
||||
|
||||
static CodeTypeInfo[] ConvertParameters(IList<IParameter> parameters) |
||||
{ |
||||
CodeTypeInfo[] cti = new CodeTypeInfo[parameters.Count]; |
||||
for (int i = 0; i < parameters.Count; ++i) { |
||||
cti[i] = ConvertType(parameters[i].ReturnType); |
||||
} |
||||
return cti; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,13 @@
@@ -0,0 +1,13 @@
|
||||
This directory contains the "glue code" needed for interacting with .NET Reflector. |
||||
|
||||
Reflector.IpcServer.AddIn: |
||||
AddIn for Reflector which provides the ReflectorService via .NET remoting IPC channel. |
||||
This addin directly references Reflector.exe. |
||||
|
||||
Reflector.IpcServer: |
||||
Contains the Reflector-independent common code that is shared between |
||||
Reflector.IpcServer.AddIn and the Reflector addin for SharpDevelop. |
||||
|
||||
|
||||
Note that the distribution does not include Reflector.exe. |
||||
If you want to build those libraries, you must place a copy of Reflector.exe in the src\RequiredLibraries directory. |
@ -0,0 +1,40 @@
@@ -0,0 +1,40 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Christian Hornung" email="chhornung@googlemail.com"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Reflection; |
||||
using System.Runtime.InteropServices; |
||||
|
||||
// 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("Reflector.IpcServer.AddIn")] |
||||
[assembly: AssemblyDescription("IPC server AddIn for Lutz Roeder's .NET Reflector")] |
||||
#if DEBUG
|
||||
[assembly: AssemblyConfiguration("Debug")] |
||||
#else
|
||||
[assembly: AssemblyConfiguration("Release")] |
||||
#endif
|
||||
[assembly: AssemblyCompany("Christian Hornung")] |
||||
[assembly: AssemblyProduct("Reflector.IpcServer")] |
||||
[assembly: AssemblyCopyright("Christian Hornung 2008")] |
||||
[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)] |
||||
|
||||
[assembly: CLSCompliant(true)] |
||||
|
||||
// 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("5.0.0.8")] |
@ -0,0 +1,63 @@
@@ -0,0 +1,63 @@
|
||||
<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
||||
<PropertyGroup> |
||||
<ProjectGuid>{D27CA9CB-5740-4818-889D-74C16A6FFD5F}</ProjectGuid> |
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> |
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> |
||||
<OutputType>Library</OutputType> |
||||
<RootNamespace>Reflector.IpcServer.AddIn</RootNamespace> |
||||
<AssemblyName>Reflector.IpcServer.AddIn</AssemblyName> |
||||
<TargetFrameworkVersion>v2.0</TargetFrameworkVersion> |
||||
<AppDesignerFolder>Properties</AppDesignerFolder> |
||||
<AllowUnsafeBlocks>False</AllowUnsafeBlocks> |
||||
<NoStdLib>False</NoStdLib> |
||||
<WarningLevel>4</WarningLevel> |
||||
<TreatWarningsAsErrors>false</TreatWarningsAsErrors> |
||||
</PropertyGroup> |
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' "> |
||||
<DebugSymbols>true</DebugSymbols> |
||||
<DebugType>Full</DebugType> |
||||
<Optimize>False</Optimize> |
||||
<CheckForOverflowUnderflow>True</CheckForOverflowUnderflow> |
||||
<DefineConstants>DEBUG;TRACE</DefineConstants> |
||||
<OutputPath>..\..\bin\Debug\</OutputPath> |
||||
</PropertyGroup> |
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Release' "> |
||||
<DebugSymbols>false</DebugSymbols> |
||||
<DebugType>None</DebugType> |
||||
<Optimize>True</Optimize> |
||||
<CheckForOverflowUnderflow>False</CheckForOverflowUnderflow> |
||||
<DefineConstants>TRACE</DefineConstants> |
||||
<OutputPath>..\..\..\ReflectorAddIn\RequiredLibraries\</OutputPath> |
||||
</PropertyGroup> |
||||
<PropertyGroup Condition=" '$(Platform)' == 'AnyCPU' "> |
||||
<RegisterForComInterop>False</RegisterForComInterop> |
||||
<GenerateSerializationAssemblies>Auto</GenerateSerializationAssemblies> |
||||
<BaseAddress>4194304</BaseAddress> |
||||
<PlatformTarget>AnyCPU</PlatformTarget> |
||||
<FileAlignment>4096</FileAlignment> |
||||
</PropertyGroup> |
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.Targets" /> |
||||
<ItemGroup> |
||||
<Reference Include="Reflector"> |
||||
<HintPath>..\RequiredLibraries\Reflector.exe</HintPath> |
||||
<Private>False</Private> |
||||
</Reference> |
||||
<Reference Include="System" /> |
||||
<Reference Include="System.Runtime.Remoting" /> |
||||
<Reference Include="System.Windows.Forms" /> |
||||
</ItemGroup> |
||||
<ItemGroup> |
||||
<Compile Include="Properties\AssemblyInfo.cs" /> |
||||
<Compile Include="src\CodeElementFinder.cs" /> |
||||
<Compile Include="src\ReflectorService.cs" /> |
||||
<Compile Include="src\ServiceLoader.cs" /> |
||||
</ItemGroup> |
||||
<ItemGroup> |
||||
<Folder Include="src" /> |
||||
<ProjectReference Include="..\Reflector.IpcServer\Reflector.IpcServer.csproj"> |
||||
<Project>{75B91F9E-C91D-4A12-8BDE-092B831D11DD}</Project> |
||||
<Name>Reflector.IpcServer</Name> |
||||
<Private>True</Private> |
||||
</ProjectReference> |
||||
</ItemGroup> |
||||
</Project> |
@ -0,0 +1,231 @@
@@ -0,0 +1,231 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Christian Hornung" email="chhornung@googlemail.com"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Text; |
||||
|
||||
using Reflector.CodeModel; |
||||
|
||||
namespace Reflector.IpcServer.AddIn |
||||
{ |
||||
/// <summary>
|
||||
/// Finds a code element in Reflector's DOM.
|
||||
/// </summary>
|
||||
internal sealed class CodeElementFinder |
||||
{ |
||||
readonly CodeElementInfo element; |
||||
|
||||
internal CodeElementFinder(CodeElementInfo element) |
||||
{ |
||||
this.element = element; |
||||
} |
||||
|
||||
delegate object Finder<T>(T item); |
||||
|
||||
static object Find<T>(System.Collections.ICollection collection, Finder<T> finder) |
||||
where T : class |
||||
{ |
||||
foreach (T item in collection) { |
||||
object result = finder(item); |
||||
if (result != null) return result; |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
// ********************************************************************************************************************************
|
||||
|
||||
internal object Find(IAssembly asm) |
||||
{ |
||||
return Find<IModule>(asm.Modules, Find) ?? asm; |
||||
} |
||||
|
||||
object Find(IModule mod) |
||||
{ |
||||
return Find<ITypeDeclaration>(mod.Types, Find); |
||||
} |
||||
|
||||
object Find(ITypeDeclaration typeDecl) |
||||
{ |
||||
if (element.Type == null || |
||||
element.Type.Namespace == null || |
||||
element.Type.TypeNames == null || |
||||
element.Type.TypeArgumentCount == null) { |
||||
return null; |
||||
} |
||||
|
||||
// If this is an outermost type declaration, check the namespace.
|
||||
if (!(typeDecl.Owner is ITypeDeclaration)) { |
||||
if (!String.Equals(typeDecl.Namespace, element.Type.Namespace, StringComparison.InvariantCulture)) { |
||||
return null; |
||||
} |
||||
} |
||||
|
||||
// Check the current type
|
||||
if (!Is(typeDecl, element.Type)) { |
||||
// Look in nested types
|
||||
return Find<ITypeDeclaration>(typeDecl.NestedTypes, Find); |
||||
} |
||||
|
||||
// This is the correct type.
|
||||
// Look for members.
|
||||
|
||||
object result = null; |
||||
|
||||
switch(element.MemberType) { |
||||
case MemberType.Event: |
||||
result = Find<IEventDeclaration>(typeDecl.Events, Find); |
||||
break; |
||||
|
||||
case MemberType.Field: |
||||
result = Find<IFieldDeclaration>(typeDecl.Fields, Find); |
||||
break; |
||||
|
||||
case MemberType.Method: |
||||
case MemberType.Constructor: |
||||
result = Find<IMethodDeclaration>(typeDecl.Methods, Find); |
||||
break; |
||||
|
||||
case MemberType.Property: |
||||
result = Find<IPropertyDeclaration>(typeDecl.Properties, Find); |
||||
break; |
||||
} |
||||
|
||||
return result ?? typeDecl; |
||||
} |
||||
|
||||
#region Type checking
|
||||
|
||||
/// <summary>
|
||||
/// Tests whether the specified type declaration is the same type
|
||||
/// as the CodeTypeInfo parameter describes
|
||||
/// (except for the namespace, which is tested before).
|
||||
/// </summary>
|
||||
static bool Is(ITypeDeclaration t, CodeTypeInfo cti) |
||||
{ |
||||
if (t == null || cti == null) return false; |
||||
|
||||
int index = cti.TypeNames.Length - 1; |
||||
do { |
||||
if (index < 0 || |
||||
!String.Equals(t.Name, cti.TypeNames[index], StringComparison.InvariantCulture) || |
||||
t.GenericArguments.Count != cti.TypeArgumentCount[index]) { |
||||
return false; |
||||
} |
||||
--index; |
||||
} while ((t = t.Owner as ITypeDeclaration) != null); |
||||
return index == -1; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Tests whether the specified type is the same type
|
||||
/// as the CodeTypeInfo parameter describes.
|
||||
/// </summary>
|
||||
static bool Is(IType t, CodeTypeInfo cti) |
||||
{ |
||||
ITypeReference r = t as ITypeReference; |
||||
if (r != null) return Is(r, cti); |
||||
|
||||
IArrayType a = t as IArrayType; |
||||
if (a != null && cti != null) { |
||||
return Is(a.ElementType, cti.ArrayElementType) && |
||||
(a.Dimensions.Count == cti.ArrayDimensions || (a.Dimensions.Count == 0 && cti.ArrayDimensions == 1)); |
||||
} |
||||
|
||||
IReferenceType rt = t as IReferenceType; |
||||
if (rt != null) { |
||||
return Is(rt.ElementType, cti); |
||||
} |
||||
|
||||
IGenericArgument ga = t as IGenericArgument; |
||||
if (ga != null) { |
||||
return true; |
||||
} |
||||
|
||||
return false; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Tests whether the specified type is the same type
|
||||
/// as the CodeTypeInfo parameter describes.
|
||||
/// </summary>
|
||||
static bool Is(ITypeReference r, CodeTypeInfo cti) |
||||
{ |
||||
if (r == null || cti == null) return false; |
||||
|
||||
int index = cti.TypeNames.Length - 1; |
||||
do { |
||||
if (index < 0 || |
||||
!String.Equals(r.Name, cti.TypeNames[index], StringComparison.InvariantCulture) || |
||||
r.GenericArguments.Count != cti.TypeArgumentCount[index]) { |
||||
return false; |
||||
} |
||||
--index; |
||||
|
||||
ITypeReference next = r.Owner as ITypeReference; |
||||
if (next == null) { |
||||
if (!String.Equals(r.Namespace, cti.Namespace, StringComparison.InvariantCulture)) { |
||||
return false; |
||||
} |
||||
break; |
||||
} else { |
||||
r = next; |
||||
} |
||||
} while (true); |
||||
return index == -1; |
||||
} |
||||
|
||||
static bool CheckParameters(CodeTypeInfo[] cti, IParameterDeclarationCollection pdc) |
||||
{ |
||||
if (cti == null || cti.Length != pdc.Count) return false; |
||||
for (int i = 0; i < cti.Length; ++i) { |
||||
if (cti[i] != null && !Is(pdc[i].ParameterType, cti[i])) return false; |
||||
} |
||||
return true; |
||||
} |
||||
|
||||
#endregion
|
||||
|
||||
object Find(IEventDeclaration eventDecl) |
||||
{ |
||||
if (String.Equals(element.MemberName, eventDecl.Name, StringComparison.InvariantCulture)) { |
||||
return eventDecl; |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
object Find(IFieldDeclaration fieldDecl) |
||||
{ |
||||
if (String.Equals(element.MemberName, fieldDecl.Name, StringComparison.InvariantCulture) && |
||||
(element.MemberReturnType == null || Is(fieldDecl.FieldType, element.MemberReturnType))) { |
||||
return fieldDecl; |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
object Find(IMethodDeclaration methodDecl) |
||||
{ |
||||
if (String.Equals(element.MemberName, methodDecl.Name, StringComparison.InvariantCulture) && |
||||
element.MemberTypeArgumentCount == methodDecl.GenericArguments.Count && |
||||
(element.MemberType == MemberType.Constructor || (element.MemberReturnType == null || Is(methodDecl.ReturnType.Type, element.MemberReturnType))) && |
||||
CheckParameters(element.MemberParameters, methodDecl.Parameters)) { |
||||
return methodDecl; |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
object Find(IPropertyDeclaration propertyDecl) |
||||
{ |
||||
if (String.Equals(element.MemberName, propertyDecl.Name, StringComparison.InvariantCulture) && |
||||
(element.MemberReturnType == null || Is(propertyDecl.PropertyType, element.MemberReturnType)) && |
||||
CheckParameters(element.MemberParameters, propertyDecl.Parameters)) { |
||||
return propertyDecl; |
||||
} |
||||
return null; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,118 @@
@@ -0,0 +1,118 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Christian Hornung" email="chhornung@googlemail.com"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Windows.Forms; |
||||
|
||||
using Reflector.CodeModel; |
||||
|
||||
namespace Reflector.IpcServer.AddIn |
||||
{ |
||||
/// <summary>
|
||||
/// Provides the ability to remote-control Reflector.
|
||||
/// </summary>
|
||||
public sealed class ReflectorService : MarshalByRefObject, IReflectorService |
||||
{ |
||||
readonly IServiceProvider serviceProvider; |
||||
readonly Dictionary<string, DateTime> assemblyLastWriteTimes = new Dictionary<string, DateTime>(StringComparer.InvariantCultureIgnoreCase); |
||||
|
||||
public ReflectorService(IServiceProvider serviceProvider) |
||||
{ |
||||
if (serviceProvider == null) throw new ArgumentNullException("serviceProvider"); |
||||
this.serviceProvider = serviceProvider; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Used to test the remoting connection without doing any action.
|
||||
/// </summary>
|
||||
/// <returns><c>true</c>.</returns>
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")] |
||||
public bool CheckIsThere() |
||||
{ |
||||
return true; |
||||
} |
||||
|
||||
// ********************************************************************************************************************************
|
||||
|
||||
T GetService<T>() |
||||
{ |
||||
return (T)serviceProvider.GetService(typeof(T)); |
||||
} |
||||
|
||||
IAssemblyBrowser AssemblyBrowser { |
||||
get { return GetService<IAssemblyBrowser>(); } |
||||
} |
||||
|
||||
IAssemblyManager AssemblyManager { |
||||
get { return GetService<IAssemblyManager>(); } |
||||
} |
||||
|
||||
IWindowManager WindowManager { |
||||
get { return GetService<IWindowManager>(); } |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Positions the assembly browser of Reflector on the element
|
||||
/// that best matches the parameters contained in the <paramref name="element"/> parameter
|
||||
/// and brings the Reflector window to front if at least the specified assembly was found.
|
||||
/// </summary>
|
||||
/// <param name="element">A <see cref="CodeElementInfo"/> object that describes the element to go to.</param>
|
||||
/// <exception cref="ArgumentNullException">The <paramref name="element"/> parameter is <c>null</c>.</exception>
|
||||
public void GoTo(CodeElementInfo element) |
||||
{ |
||||
if (element == null) throw new ArgumentNullException("element"); |
||||
WindowManager.Content.BeginInvoke(new Action<CodeElementInfo>(GoToInternal), |
||||
new object[] { element }); |
||||
} |
||||
|
||||
void GoToInternal(CodeElementInfo element) |
||||
{ |
||||
if (element == null) throw new ArgumentNullException("element"); |
||||
|
||||
IAssembly asm = AssemblyManager.LoadFile(element.AssemblyLocation); |
||||
if (asm == null) return; |
||||
|
||||
// Force reload of the assembly if it has changed since start of Service
|
||||
DateTime tNew = GetLastWriteTimeSafe(element.AssemblyLocation); |
||||
DateTime tOld; |
||||
if (this.assemblyLastWriteTimes.TryGetValue(element.AssemblyLocation, out tOld)) { |
||||
if (!tNew.Equals(tOld)) { |
||||
AssemblyManager.Unload(asm); |
||||
asm = AssemblyManager.LoadFile(element.AssemblyLocation); |
||||
if (asm == null) return; |
||||
} |
||||
} |
||||
|
||||
this.assemblyLastWriteTimes[element.AssemblyLocation] = tNew; |
||||
|
||||
|
||||
AssemblyBrowser.ActiveItem = (new CodeElementFinder(element)).Find(asm); |
||||
|
||||
WindowManager.Activate(); |
||||
Form topForm = WindowManager.Content.FindForm(); |
||||
if (topForm != null) { |
||||
// Force the Reflector window to the top
|
||||
topForm.TopMost = true; |
||||
topForm.TopMost = false; |
||||
} |
||||
} |
||||
|
||||
static DateTime GetLastWriteTimeSafe(string path) |
||||
{ |
||||
try { |
||||
return System.IO.File.GetLastWriteTimeUtc(path); |
||||
} catch (UnauthorizedAccessException) { |
||||
return DateTime.UtcNow; |
||||
} catch (System.IO.IOException) { |
||||
return DateTime.UtcNow; |
||||
} catch (NotSupportedException) { |
||||
return DateTime.UtcNow; |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,97 @@
@@ -0,0 +1,97 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Christian Hornung" email="chhornung@googlemail.com"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Runtime.Remoting; |
||||
using System.Runtime.Remoting.Channels; |
||||
using System.Runtime.Remoting.Channels.Ipc; |
||||
|
||||
namespace Reflector.IpcServer.AddIn |
||||
{ |
||||
/// <summary>
|
||||
/// Initializes our remoting service when the AddIn is loaded in Reflector.
|
||||
/// </summary>
|
||||
public sealed class ServiceLoader : IPackage |
||||
{ |
||||
public ServiceLoader() |
||||
{ |
||||
} |
||||
|
||||
ReflectorService serviceInstance; |
||||
IpcServerChannel channel; |
||||
|
||||
public void Load(IServiceProvider serviceProvider) |
||||
{ |
||||
try { |
||||
TryLoad(serviceProvider); |
||||
} catch (RemotingException ex) { |
||||
((IWindowManager)serviceProvider.GetService(typeof(IWindowManager))).ShowMessage(String.Concat("ReflectorAddIn: Failed to initialize remoting service.", Environment.NewLine, Environment.NewLine, "Exception:", Environment.NewLine, ex.ToString())); |
||||
} |
||||
} |
||||
|
||||
void TryLoad(IServiceProvider serviceProvider) |
||||
{ |
||||
const int tryCount = 20; |
||||
const int waitTimeMS = 500; |
||||
|
||||
for (int i = 0; i < tryCount; ++i) { |
||||
bool success = false; |
||||
|
||||
try { |
||||
|
||||
serviceInstance = new ReflectorService(serviceProvider); |
||||
|
||||
Dictionary<string, object> props = new Dictionary<string, object>(); |
||||
props.Add("name", "Reflector IPC server"); |
||||
props.Add("secure", true); |
||||
props.Add("portName", "ReflectorService"); |
||||
// The following line is needed to fix an "access denied" error
|
||||
// when Reflector is restarted within a certain amount of time
|
||||
props.Add("exclusiveAddressUse", false); |
||||
|
||||
channel = new IpcServerChannel(props, null); |
||||
ChannelServices.RegisterChannel(channel, true); |
||||
|
||||
RemotingServices.Marshal(serviceInstance, "ReflectorService.rem"); |
||||
|
||||
success = true; |
||||
return; |
||||
|
||||
} catch (RemotingException) { |
||||
if (!((i + 1) < tryCount)) { |
||||
throw; |
||||
} |
||||
} finally { |
||||
if (!success) { |
||||
Unload(); |
||||
} |
||||
} |
||||
|
||||
System.Threading.Thread.Sleep(waitTimeMS); |
||||
} |
||||
} |
||||
|
||||
public void Unload() |
||||
{ |
||||
if (serviceInstance != null) { |
||||
try { |
||||
RemotingServices.Disconnect(serviceInstance); |
||||
} catch (RemotingException) { |
||||
} |
||||
serviceInstance = null; |
||||
} |
||||
if (channel != null) { |
||||
try { |
||||
ChannelServices.UnregisterChannel(channel); |
||||
} catch (RemotingException) { |
||||
} |
||||
channel = null; |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,20 @@
@@ -0,0 +1,20 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 10.00 |
||||
# Visual Studio 2008 |
||||
# SharpDevelop 3.0.0.3217 |
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Reflector.IpcServer", "Reflector.IpcServer\Reflector.IpcServer.csproj", "{75B91F9E-C91D-4A12-8BDE-092B831D11DD}" |
||||
EndProject |
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Reflector.IpcServer.AddIn", "Reflector.IpcServer.AddIn\Reflector.IpcServer.AddIn.csproj", "{D27CA9CB-5740-4818-889D-74C16A6FFD5F}" |
||||
EndProject |
||||
Global |
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution |
||||
Debug|Any CPU = Debug|Any CPU |
||||
Release|Any CPU = Release|Any CPU |
||||
EndGlobalSection |
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution |
||||
{75B91F9E-C91D-4A12-8BDE-092B831D11DD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
||||
{75B91F9E-C91D-4A12-8BDE-092B831D11DD}.Release|Any CPU.ActiveCfg = Release|Any CPU |
||||
{D27CA9CB-5740-4818-889D-74C16A6FFD5F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
||||
{D27CA9CB-5740-4818-889D-74C16A6FFD5F}.Release|Any CPU.ActiveCfg = Release|Any CPU |
||||
EndGlobalSection |
||||
EndGlobal |
@ -0,0 +1,40 @@
@@ -0,0 +1,40 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Christian Hornung" email="chhornung@googlemail.com"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Reflection; |
||||
using System.Runtime.InteropServices; |
||||
|
||||
// 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("Reflector.IpcServer")] |
||||
[assembly: AssemblyDescription("IPC server module for Lutz Roeder's .NET Reflector")] |
||||
#if DEBUG
|
||||
[assembly: AssemblyConfiguration("Debug")] |
||||
#else
|
||||
[assembly: AssemblyConfiguration("Release")] |
||||
#endif
|
||||
[assembly: AssemblyCompany("Christian Hornung")] |
||||
[assembly: AssemblyProduct("Reflector.IpcServer")] |
||||
[assembly: AssemblyCopyright("Christian Hornung 2008")] |
||||
[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)] |
||||
|
||||
[assembly: CLSCompliant(true)] |
||||
|
||||
// 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("5.0.0.3")] |
@ -0,0 +1,52 @@
@@ -0,0 +1,52 @@
|
||||
<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
||||
<PropertyGroup> |
||||
<ProjectGuid>{75B91F9E-C91D-4A12-8BDE-092B831D11DD}</ProjectGuid> |
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> |
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> |
||||
<OutputType>Library</OutputType> |
||||
<RootNamespace>Reflector.IpcServer</RootNamespace> |
||||
<AssemblyName>Reflector.IpcServer</AssemblyName> |
||||
<TargetFrameworkVersion>v2.0</TargetFrameworkVersion> |
||||
<AppDesignerFolder>Properties</AppDesignerFolder> |
||||
<AllowUnsafeBlocks>False</AllowUnsafeBlocks> |
||||
<NoStdLib>False</NoStdLib> |
||||
<WarningLevel>4</WarningLevel> |
||||
<TreatWarningsAsErrors>false</TreatWarningsAsErrors> |
||||
</PropertyGroup> |
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' "> |
||||
<DebugSymbols>true</DebugSymbols> |
||||
<DebugType>Full</DebugType> |
||||
<Optimize>False</Optimize> |
||||
<CheckForOverflowUnderflow>True</CheckForOverflowUnderflow> |
||||
<DefineConstants>DEBUG;TRACE</DefineConstants> |
||||
<OutputPath>..\..\bin\Debug\</OutputPath> |
||||
</PropertyGroup> |
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Release' "> |
||||
<DebugSymbols>false</DebugSymbols> |
||||
<DebugType>None</DebugType> |
||||
<Optimize>True</Optimize> |
||||
<CheckForOverflowUnderflow>False</CheckForOverflowUnderflow> |
||||
<DefineConstants>TRACE</DefineConstants> |
||||
<OutputPath>..\..\..\ReflectorAddIn\RequiredLibraries\</OutputPath> |
||||
</PropertyGroup> |
||||
<PropertyGroup Condition=" '$(Platform)' == 'AnyCPU' "> |
||||
<RegisterForComInterop>False</RegisterForComInterop> |
||||
<GenerateSerializationAssemblies>Auto</GenerateSerializationAssemblies> |
||||
<BaseAddress>4194304</BaseAddress> |
||||
<PlatformTarget>AnyCPU</PlatformTarget> |
||||
<FileAlignment>4096</FileAlignment> |
||||
</PropertyGroup> |
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.Targets" /> |
||||
<ItemGroup> |
||||
<Reference Include="System" /> |
||||
</ItemGroup> |
||||
<ItemGroup> |
||||
<Compile Include="Properties\AssemblyInfo.cs" /> |
||||
<Compile Include="src\CodeElementInfo.cs" /> |
||||
<Compile Include="src\CodeTypeInfo.cs" /> |
||||
<Compile Include="src\IReflectorService.cs" /> |
||||
</ItemGroup> |
||||
<ItemGroup> |
||||
<Folder Include="src" /> |
||||
</ItemGroup> |
||||
</Project> |
@ -0,0 +1,125 @@
@@ -0,0 +1,125 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Christian Hornung" email="chhornung@googlemail.com"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Text; |
||||
|
||||
namespace Reflector.IpcServer |
||||
{ |
||||
/// <summary>
|
||||
/// Describes a code element.
|
||||
/// </summary>
|
||||
[Serializable] |
||||
public sealed class CodeElementInfo |
||||
{ |
||||
string assemblyLocation; |
||||
readonly CodeTypeInfo type = new CodeTypeInfo(); |
||||
MemberType memberType; |
||||
string memberName; |
||||
int memberTypeArgumentCount; |
||||
CodeTypeInfo memberReturnType; |
||||
CodeTypeInfo[] memberParameters; |
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the full path and file name of the assembly.
|
||||
/// </summary>
|
||||
public string AssemblyLocation { |
||||
get { return assemblyLocation; } |
||||
set { assemblyLocation = value; } |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the object describing the type.
|
||||
/// </summary>
|
||||
public CodeTypeInfo Type { |
||||
get { return type; } |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the kind of member.
|
||||
/// </summary>
|
||||
public MemberType MemberType { |
||||
get { return memberType; } |
||||
set { memberType = value; } |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the member name.
|
||||
/// </summary>
|
||||
public string MemberName { |
||||
get { return memberName; } |
||||
set { memberName = value; } |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the type argument count of the member.
|
||||
/// </summary>
|
||||
public int MemberTypeArgumentCount { |
||||
get { return memberTypeArgumentCount; } |
||||
set { memberTypeArgumentCount = value; } |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the member return type information.
|
||||
/// </summary>
|
||||
public CodeTypeInfo MemberReturnType { |
||||
get { return memberReturnType; } |
||||
set { memberReturnType = value; } |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the member parameters type information.
|
||||
/// </summary>
|
||||
public CodeTypeInfo[] MemberParameters { |
||||
get { return memberParameters; } |
||||
set { memberParameters = value; } |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="CodeElementInfo"/> class.
|
||||
/// </summary>
|
||||
public CodeElementInfo() |
||||
{ |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Returns a string representation of the current object.
|
||||
/// </summary>
|
||||
/// <returns>A string representation of the current object.</returns>
|
||||
public override string ToString() |
||||
{ |
||||
return string.Format(System.Globalization.CultureInfo.InvariantCulture, |
||||
"[CodeElementInfo AssemblyLocation={0} Type={1} MemberType={2} MemberName={3} MemberTypeArgumentCount={4} MemberReturnType={5} MemberParameters={6}]", |
||||
AssemblyLocation, |
||||
Type == null ? "<null>" : Type.ToString(), |
||||
MemberType, |
||||
MemberName ?? "<null>", |
||||
MemberTypeArgumentCount, |
||||
MemberReturnType == null ? "<null>" : MemberReturnType.ToString(), |
||||
MemberParameters == null ? "<null>" : String.Join(", ", Array.ConvertAll<CodeTypeInfo, string>(MemberParameters, TypeInfoToString))); |
||||
} |
||||
|
||||
static string TypeInfoToString(CodeTypeInfo cti) |
||||
{ |
||||
if (cti == null) return "<null>"; |
||||
return cti.ToString(); |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Specifies a kind of class member.
|
||||
/// </summary>
|
||||
public enum MemberType |
||||
{ |
||||
None = 0, |
||||
Method, |
||||
Constructor, |
||||
Field, |
||||
Property, |
||||
Event |
||||
} |
||||
} |
@ -0,0 +1,93 @@
@@ -0,0 +1,93 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Christian Hornung" email="chhornung@googlemail.com"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
|
||||
namespace Reflector.IpcServer |
||||
{ |
||||
/// <summary>
|
||||
/// Describes a type.
|
||||
/// </summary>
|
||||
[Serializable] |
||||
public sealed class CodeTypeInfo |
||||
{ |
||||
string @namespace; |
||||
string[] typeNames = new string[0]; |
||||
int[] typeArgumentCount = new int[0]; |
||||
CodeTypeInfo arrayElementType; |
||||
int arrayDimensions; |
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the namespace.
|
||||
/// </summary>
|
||||
public string Namespace { |
||||
get { return @namespace; } |
||||
set { @namespace = value; } |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the type names (without namespace).
|
||||
/// The order must be from the outermost type name to the innermost type name.
|
||||
/// </summary>
|
||||
public string[] TypeNames { |
||||
get { return typeNames; } |
||||
set { typeNames = value; } |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the type argument counts for the types as specified in the <see cref="TypeNames"/> property..
|
||||
/// The order must be from the outermost type to the innermost type.
|
||||
/// </summary>
|
||||
public int[] TypeArgumentCount { |
||||
get { return typeArgumentCount; } |
||||
set { typeArgumentCount = value; } |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the array element type.
|
||||
/// </summary>
|
||||
public CodeTypeInfo ArrayElementType { |
||||
get { return arrayElementType; } |
||||
set { arrayElementType = value; } |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the number of array dimensions of the type.
|
||||
/// </summary>
|
||||
public int ArrayDimensions { |
||||
get { return arrayDimensions; } |
||||
set { arrayDimensions = value; } |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="CodeTypeInfo"/> class.
|
||||
/// </summary>
|
||||
public CodeTypeInfo() |
||||
{ |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Returns a string representation of the current object.
|
||||
/// </summary>
|
||||
/// <returns>A string representation of the current object.</returns>
|
||||
public override string ToString() |
||||
{ |
||||
return string.Format(System.Globalization.CultureInfo.InvariantCulture, |
||||
"[CodeTypeInfo: Namespace={0} TypeNames={1} TypeArgumentCount={2} ArrayElementType={3} ArrayDimensions={4}]", |
||||
Namespace, |
||||
String.Join("+", TypeNames), |
||||
String.Join("+", Array.ConvertAll<int, string>(TypeArgumentCount, IntToString)), |
||||
ArrayElementType == null ? "<null>" : ArrayElementType.ToString(), |
||||
ArrayDimensions); |
||||
} |
||||
|
||||
static string IntToString(int i) |
||||
{ |
||||
return i.ToString(System.Globalization.CultureInfo.InvariantCulture); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,32 @@
@@ -0,0 +1,32 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Christian Hornung" email="chhornung@googlemail.com"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
|
||||
namespace Reflector.IpcServer |
||||
{ |
||||
/// <summary>
|
||||
/// Provides the ability to remote-control Reflector.
|
||||
/// </summary>
|
||||
public interface IReflectorService |
||||
{ |
||||
/// <summary>
|
||||
/// Used to test the remoting connection without doing any action.
|
||||
/// </summary>
|
||||
/// <returns><c>true</c>.</returns>
|
||||
bool CheckIsThere(); |
||||
|
||||
/// <summary>
|
||||
/// Positions the assembly browser of Reflector on the element
|
||||
/// that best matches the parameters contained in the <paramref name="element"/> parameter
|
||||
/// and brings the Reflector window to front if at least the specified assembly was found.
|
||||
/// </summary>
|
||||
/// <param name="element">A <see cref="CodeElementInfo"/> object that describes the element to go to.</param>
|
||||
/// <exception cref="ArgumentNullException">The <paramref name="element"/> parameter is <c>null</c>.</exception>
|
||||
void GoTo(CodeElementInfo element); |
||||
} |
||||
} |
Binary file not shown.
Loading…
Reference in new issue