Browse Source

Show assembly location in OpenFromGacDialog.

pull/1/head
Daniel Grunwald 14 years ago
parent
commit
a256eedae3
  1. 78
      ILSpy/AssemblyListTreeNode.cs
  2. 12
      ILSpy/AssemblyTreeNode.cs
  3. 107
      ILSpy/GacInterop.cs
  4. 1
      ILSpy/ILSpy.csproj
  5. 4
      ILSpy/MainWindow.xaml.cs
  6. 7
      ILSpy/OpenFromGacDialog.xaml
  7. 85
      ILSpy/OpenFromGacDialog.xaml.cs

78
ILSpy/AssemblyListTreeNode.cs

@ -75,25 +75,18 @@ namespace ICSharpCode.ILSpy @@ -75,25 +75,18 @@ namespace ICSharpCode.ILSpy
return node;
}
var newNode = new AssemblyTreeNode(file, null, this);
var newNode = new AssemblyTreeNode(file, this);
this.Children.Add(newNode);
return newNode;
}
public AssemblyTreeNode OpenGacAssembly(string fullName)
AssemblyTreeNode OpenGacAssembly(string fullName)
{
App.Current.Dispatcher.VerifyAccess();
foreach (AssemblyTreeNode node in this.Children) {
if (fullName.Equals(node.FullName, StringComparison.OrdinalIgnoreCase))
return node;
}
string file = FindAssemblyInNetGac(AssemblyNameReference.Parse(fullName));
string file = GacInterop.FindAssemblyInNetGac(AssemblyNameReference.Parse(fullName));
if (file != null) {
var newNode = new AssemblyTreeNode(file, fullName, this);
this.Children.Add(newNode);
return newNode;
return OpenAssembly(file);
} else {
return null;
}
@ -122,68 +115,5 @@ namespace ICSharpCode.ILSpy @@ -122,68 +115,5 @@ namespace ICSharpCode.ILSpy
var node = OpenGacAssembly(fullName);
return node != null ? node.AssemblyDefinition : null;
}
#region FindAssemblyInGac
// This region is taken from Mono.Cecil:
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2010 Jb Evain
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
static string FindAssemblyInNetGac (AssemblyNameReference reference)
{
string[] gac_paths = { Fusion.GetGacPath(false), Fusion.GetGacPath(true) };
string[] gacs = { "GAC_MSIL", "GAC_32", "GAC" };
string[] prefixes = { string.Empty, "v4.0_" };
for (int i = 0; i < 2; i++) {
for (int j = 0; j < gacs.Length; j++) {
var gac = Path.Combine (gac_paths [i], gacs [j]);
var file = GetAssemblyFile (reference, prefixes [i], gac);
if (File.Exists (file))
return file;
}
}
return null;
}
static string GetAssemblyFile (AssemblyNameReference reference, string prefix, string gac)
{
var gac_folder = new StringBuilder ()
.Append (prefix)
.Append (reference.Version)
.Append ("__");
for (int i = 0; i < reference.PublicKeyToken.Length; i++)
gac_folder.Append (reference.PublicKeyToken [i].ToString ("x2"));
return Path.Combine (
Path.Combine (
Path.Combine (gac, reference.Name), gac_folder.ToString ()),
reference.Name + ".dll");
}
#endregion
}
}

12
ILSpy/AssemblyTreeNode.cs

@ -18,20 +18,18 @@ namespace ICSharpCode.ILSpy @@ -18,20 +18,18 @@ namespace ICSharpCode.ILSpy
{
readonly IAssemblyResolver assemblyResolver;
readonly string fileName;
string fullName;
string shortName;
readonly Task<AssemblyDefinition> assemblyTask;
readonly List<TypeTreeNode> classes = new List<TypeTreeNode>();
readonly Dictionary<string, NamespaceTreeNode> namespaces = new Dictionary<string, NamespaceTreeNode>();
readonly SynchronizationContext syncContext;
public AssemblyTreeNode(string fileName, string fullName, IAssemblyResolver assemblyResolver)
public AssemblyTreeNode(string fileName, IAssemblyResolver assemblyResolver)
{
if (fileName == null)
throw new ArgumentNullException("fileName");
this.fileName = fileName;
this.fullName = fullName;
this.assemblyResolver = assemblyResolver;
this.assemblyTask = Task.Factory.StartNew<AssemblyDefinition>(LoadAssembly); // requires that this.fileName is set
this.shortName = Path.GetFileNameWithoutExtension(fileName);
@ -44,10 +42,6 @@ namespace ICSharpCode.ILSpy @@ -44,10 +42,6 @@ namespace ICSharpCode.ILSpy
get { return fileName; }
}
public string FullName {
get { return fullName ?? assemblyTask.Result.FullName; }
}
public AssemblyDefinition AssemblyDefinition {
get { return assemblyTask.Result; }
}
@ -75,10 +69,6 @@ namespace ICSharpCode.ILSpy @@ -75,10 +69,6 @@ namespace ICSharpCode.ILSpy
shortName = assembly.Name.Name;
RaisePropertyChanged("Text");
}
if (fullName != assembly.FullName) {
fullName = assembly.FullName;
RaisePropertyChanged("FullName");
}
}, null);
return assembly;

107
ILSpy/GacInterop.cs

@ -0,0 +1,107 @@ @@ -0,0 +1,107 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using Mono.Cecil;
namespace ICSharpCode.ILSpy
{
/// <summary>
/// Interop with the .NET GAC.
/// </summary>
public static class GacInterop
{
public static IEnumerable<AssemblyNameReference> GetGacAssemblyFullNames()
{
IApplicationContext applicationContext = null;
IAssemblyEnum assemblyEnum = null;
IAssemblyName assemblyName = null;
Fusion.CreateAssemblyEnum(out assemblyEnum, null, null, 2, 0);
while (assemblyEnum.GetNextAssembly(out applicationContext, out assemblyName, 0) == 0) {
uint nChars = 0;
assemblyName.GetDisplayName(null, ref nChars, 0);
StringBuilder name = new StringBuilder((int)nChars);
assemblyName.GetDisplayName(name, ref nChars, 0);
AssemblyNameReference r = null;
try {
r = AssemblyNameReference.Parse(name.ToString());
} catch (ArgumentException) {
} catch (FormatException) {
} catch (OverflowException) {
}
if (r != null)
yield return r;
}
}
#region FindAssemblyInGac
// This region is based on code from Mono.Cecil:
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2010 Jb Evain
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
static readonly string[] gac_paths = { Fusion.GetGacPath(false), Fusion.GetGacPath(true) };
static readonly string[] gacs = { "GAC_MSIL", "GAC_32", "GAC" };
static readonly string[] prefixes = { string.Empty, "v4.0_" };
public static string FindAssemblyInNetGac (AssemblyNameReference reference)
{
for (int i = 0; i < 2; i++) {
for (int j = 0; j < gacs.Length; j++) {
var gac = Path.Combine (gac_paths [i], gacs [j]);
var file = GetAssemblyFile (reference, prefixes [i], gac);
if (File.Exists (file))
return file;
}
}
return null;
}
static string GetAssemblyFile (AssemblyNameReference reference, string prefix, string gac)
{
var gac_folder = new StringBuilder ()
.Append (prefix)
.Append (reference.Version)
.Append ("__");
for (int i = 0; i < reference.PublicKeyToken.Length; i++)
gac_folder.Append (reference.PublicKeyToken [i].ToString ("x2"));
return Path.Combine (
Path.Combine (
Path.Combine (gac, reference.Name), gac_folder.ToString ()),
reference.Name + ".dll");
}
#endregion
}
}

1
ILSpy/ILSpy.csproj

@ -74,6 +74,7 @@ @@ -74,6 +74,7 @@
<Compile Include="ExtensionMethods.cs" />
<Compile Include="FieldTreeNode.cs" />
<Compile Include="Fusion.cs" />
<Compile Include="GacInterop.cs" />
<Compile Include="Images\Images.cs" />
<Compile Include="MethodTreeNode.cs" />
<Compile Include="ModuleReferenceTreeNode.cs" />

4
ILSpy/MainWindow.xaml.cs

@ -80,8 +80,8 @@ namespace ICSharpCode.ILSpy @@ -80,8 +80,8 @@ namespace ICSharpCode.ILSpy
dlg.Owner = this;
if (dlg.ShowDialog() == true) {
treeView.UnselectAll();
foreach (string fullName in dlg.SelectedFullNames) {
var asm = assemblyList.OpenGacAssembly(fullName);
foreach (string file in dlg.SelectedFileNames) {
var asm = assemblyList.OpenAssembly(file);
if (asm != null)
treeView.SelectedItems.Add(asm);
}

7
ILSpy/OpenFromGacDialog.xaml

@ -8,7 +8,7 @@ @@ -8,7 +8,7 @@
MinWidth="200"
MinHeight="150"
Height="350"
Width="650"
Width="750"
FocusManager.FocusedElement="{Binding ElementName=filterTextBox}">
<Grid
Margin="12,8">
@ -26,8 +26,9 @@ @@ -26,8 +26,9 @@
<GridView>
<local:SortableGridViewColumn x:Name="nameColumn" Width="300" Header="Reference Name" DisplayMemberBinding="{Binding ShortName}" />
<local:SortableGridViewColumn Width="75" Header="Version" DisplayMemberBinding="{Binding Version}" />
<local:SortableGridViewColumn Width="80" Header="Culture" DisplayMemberBinding="{Binding Culture}" />
<local:SortableGridViewColumn Width="120" Header="Public Key Token" DisplayMemberBinding="{Binding PublicKeyToken}" />
<local:SortableGridViewColumn Width="65" Header="Culture" DisplayMemberBinding="{Binding Culture}" />
<local:SortableGridViewColumn Width="115" Header="Public Key Token" DisplayMemberBinding="{Binding PublicKeyToken}" />
<local:SortableGridViewColumn Width="1000" Header="Location" DisplayMemberBinding="{Binding FileName}" />
</GridView>
</ListView.View>
</ListView>

85
ILSpy/OpenFromGacDialog.xaml.cs

@ -15,6 +15,7 @@ using System.Windows.Documents; @@ -15,6 +15,7 @@ using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Threading;
using Mono.Cecil;
namespace ICSharpCode.ILSpy
{
@ -46,63 +47,52 @@ namespace ICSharpCode.ILSpy @@ -46,63 +47,52 @@ namespace ICSharpCode.ILSpy
#region Fetch Gac Contents
sealed class GacEntry : IEquatable<GacEntry>
{
readonly string fullAssemblyName;
readonly string shortName, culture, publicKeyToken;
readonly Version version;
readonly AssemblyNameReference r;
readonly string fileName;
public GacEntry(string fullAssemblyName)
public GacEntry(AssemblyNameReference r, string fileName)
{
this.fullAssemblyName = fullAssemblyName;
string[] components = fullAssemblyName.Split(',');
shortName = components[0];
for (int i = 1; i < components.Length; i++) {
string val = components[i].Trim();
int pos = val.IndexOf('=');
if (pos > 0) {
switch (val.Substring(0, pos)) {
case "Version":
string versionText = val.Substring(pos + 1);
Version.TryParse(versionText, out version);
break;
case "Culture":
culture = val.Substring(pos + 1);
break;
case "PublicKeyToken":
publicKeyToken = val.Substring(pos + 1);
break;
}
}
}
this.r = r;
this.fileName = fileName;
}
public string FullName {
get { return fullAssemblyName; }
get { return r.FullName; }
}
public string ShortName {
get { return shortName; }
get { return r.Name; }
}
public string FileName {
get { return fileName; }
}
public Version Version {
get { return version; }
get { return r.Version; }
}
public string Culture {
get { return culture; }
get { return r.Culture; }
}
public string PublicKeyToken {
get { return publicKeyToken; }
get {
StringBuilder s = new StringBuilder();
foreach (byte b in r.PublicKeyToken)
s.Append(b.ToString("x2"));
return s.ToString();
}
}
public override string ToString()
{
return fullAssemblyName;
return r.FullName;
}
public override int GetHashCode()
{
return fullAssemblyName.GetHashCode();
return r.FullName.GetHashCode();
}
public override bool Equals(object obj)
@ -112,31 +102,18 @@ namespace ICSharpCode.ILSpy @@ -112,31 +102,18 @@ namespace ICSharpCode.ILSpy
public bool Equals(GacEntry o)
{
return o != null && fullAssemblyName == o.fullAssemblyName;
}
}
IEnumerable<GacEntry> GetGacAssemblyFullNames()
{
IApplicationContext applicationContext = null;
IAssemblyEnum assemblyEnum = null;
IAssemblyName assemblyName = null;
Fusion.CreateAssemblyEnum(out assemblyEnum, null, null, 2, 0);
while (!cancelFetchThread && assemblyEnum.GetNextAssembly(out applicationContext, out assemblyName, 0) == 0) {
uint nChars = 0;
assemblyName.GetDisplayName(null, ref nChars, 0);
StringBuilder name = new StringBuilder((int)nChars);
assemblyName.GetDisplayName(name, ref nChars, 0);
yield return new GacEntry(name.ToString());
return o != null && r.FullName == o.r.FullName;
}
}
void FetchGacContents()
{
foreach (var entry in GetGacAssemblyFullNames().Distinct()) {
var entries =
from r in GacInterop.GetGacAssemblyFullNames()
let file = GacInterop.FindAssemblyInNetGac(r)
where file != null
select new GacEntry(r, file);
foreach (var entry in entries.Distinct()) {
Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action<GacEntry>(AddNewEntry), entry);
}
}
@ -171,9 +148,9 @@ namespace ICSharpCode.ILSpy @@ -171,9 +148,9 @@ namespace ICSharpCode.ILSpy
Close();
}
public string[] SelectedFullNames {
public string[] SelectedFileNames {
get {
return listView.SelectedItems.OfType<GacEntry>().Select(e => e.FullName).ToArray();
return listView.SelectedItems.OfType<GacEntry>().Select(e => e.FileName).ToArray();
}
}
}

Loading…
Cancel
Save