Browse Source

Properly resolve local assemblies.

pull/19/head
Eusebiu Marcu 14 years ago committed by Daniel Grunwald
parent
commit
5dab783842
  1. 1
      src/AddIns/DisplayBindings/ILSpyAddIn/ILSpyAddIn.csproj
  2. 216
      src/AddIns/DisplayBindings/ILSpyAddIn/LaunchILSpy/Fusion.cs
  3. 32
      src/AddIns/DisplayBindings/ILSpyAddIn/LaunchILSpy/ILSpyAssemblyResolver.cs
  4. 2
      src/AddIns/DisplayBindings/ILSpyAddIn/ViewContent/DecompiledViewContent.cs

1
src/AddIns/DisplayBindings/ILSpyAddIn/ILSpyAddIn.csproj

@ -64,7 +64,6 @@ @@ -64,7 +64,6 @@
<Link>Properties\GlobalAssemblyInfo.cs</Link>
</Compile>
<Compile Include="DebuggerDecompilerService.cs" />
<Compile Include="LaunchILSpy\Fusion.cs" />
<Compile Include="LaunchILSpy\ILSpyAssemblyResolver.cs" />
<Compile Include="NavigateToDecompiledEntityService.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />

216
src/AddIns/DisplayBindings/ILSpyAddIn/LaunchILSpy/Fusion.cs

@ -1,216 +0,0 @@ @@ -1,216 +0,0 @@
// 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)
using System;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using System.Text;
namespace ICSharpCode.ILSpyAddIn.LaunchILSpy
{
// .NET Fusion COM interfaces
[ComImport(), Guid("E707DCDE-D1CD-11D2-BAB9-00C04F8ECEAE"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IAssemblyCache
{
[PreserveSig()]
int UninstallAssembly(uint dwFlags,
[MarshalAs(UnmanagedType.LPWStr)] string pszAssemblyName,
IntPtr pvReserved,
out uint pulDisposition);
[PreserveSig()]
int QueryAssemblyInfo(uint dwFlags,
[MarshalAs(UnmanagedType.LPWStr)] string pszAssemblyName,
IntPtr pAsmInfo);
[PreserveSig()]
int CreateAssemblyCacheItem(uint dwFlags,
IntPtr pvReserved,
out IAssemblyCacheItem ppAsmItem,
[MarshalAs(UnmanagedType.LPWStr)] string pszAssemblyName);
[PreserveSig()]
int CreateAssemblyScavenger(out object ppAsmScavenger);
[PreserveSig()]
int InstallAssembly(uint dwFlags,
[MarshalAs(UnmanagedType.LPWStr)] string pszManifestFilePath,
IntPtr pvReserved);
}
[ComImport(), Guid("9E3AAEB4-D1CD-11D2-BAB9-00C04F8ECEAE"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IAssemblyCacheItem
{
void CreateStream([MarshalAs(UnmanagedType.LPWStr)] string pszName,
uint dwFormat,
uint dwFlags,
uint dwMaxSize,
out IStream ppStream);
void IsNameEqual(IAssemblyName pName);
void Commit(uint dwFlags);
void MarkAssemblyVisible(uint dwFlags);
}
[ComImport(), Guid("CD193BC0-B4BC-11D2-9833-00C04FC31D2E"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IAssemblyName
{
[PreserveSig()]
int SetProperty(uint PropertyId, IntPtr pvProperty, uint cbProperty);
[PreserveSig()]
int GetProperty(uint PropertyId, IntPtr pvProperty, ref uint pcbProperty);
[PreserveSig()]
int Finalize();
[PreserveSig()]
int GetDisplayName([Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder szDisplayName,
ref uint pccDisplayName,
uint dwDisplayFlags);
[PreserveSig()]
int BindToObject(object refIID,
object pAsmBindSink,
IApplicationContext pApplicationContext,
[MarshalAs(UnmanagedType.LPWStr)] string szCodeBase,
long llFlags,
int pvReserved,
uint cbReserved,
out int ppv);
[PreserveSig()]
int GetName(ref uint lpcwBuffer,
[Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pwzName);
[PreserveSig()]
int GetVersion(out uint pdwVersionHi, out uint pdwVersionLow);
[PreserveSig()]
int IsEqual(IAssemblyName pName,
uint dwCmpFlags);
[PreserveSig()]
int Clone(out IAssemblyName pName);
}
[ComImport(), Guid("7C23FF90-33AF-11D3-95DA-00A024A85B51"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IApplicationContext
{
void SetContextNameObject(IAssemblyName pName);
void GetContextNameObject(out IAssemblyName ppName);
void Set([MarshalAs(UnmanagedType.LPWStr)] string szName,
int pvValue,
uint cbValue,
uint dwFlags);
void Get([MarshalAs(UnmanagedType.LPWStr)] string szName,
out int pvValue,
ref uint pcbValue,
uint dwFlags);
void GetDynamicDirectory(out int wzDynamicDir,
ref uint pdwSize);
}
[ComImport(), Guid("21B8916C-F28E-11D2-A473-00C04F8EF448"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IAssemblyEnum
{
[PreserveSig()]
int GetNextAssembly(out IApplicationContext ppAppCtx,
out IAssemblyName ppName,
uint dwFlags);
[PreserveSig()]
int Reset();
[PreserveSig()]
int Clone(out IAssemblyEnum ppEnum);
}
[ComImport(), Guid("1D23DF4D-A1E2-4B8B-93D6-6EA3DC285A54"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IHistoryReader
{
[PreserveSig()]
int GetFilePath([Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder wzFilePath,
ref uint pdwSize);
[PreserveSig()]
int GetApplicationName([Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder wzAppName,
ref uint pdwSize);
[PreserveSig()]
int GetEXEModulePath([Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder wzExePath,
ref uint pdwSize);
void GetNumActivations(out uint pdwNumActivations);
void GetActivationDate(uint dwIdx, // One-based!
out long /* FILETIME */ pftDate);
[PreserveSig()]
int GetRunTimeVersion(ref long /* FILETIME */ pftActivationDate,
[Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder wzRunTimeVersion,
ref uint pdwSize);
void GetNumAssemblies(ref long /* FILETIME */ pftActivationDate,
out uint pdwNumAsms);
void GetHistoryAssembly(ref long /* FILETIME */ pftActivationDate,
uint dwIdx, // One-based!
[MarshalAs(UnmanagedType.IUnknown)] out object ppHistAsm);
}
internal static class Fusion
{
[DllImport("fusion.dll", CharSet=CharSet.Auto)]
internal static extern int CreateAssemblyCache(out IAssemblyCache ppAsmCache,
uint dwReserved);
// dwFlags: 1 = Enumerate native image (NGEN) assemblies
// 2 = Enumerate GAC assemblies
// 4 = Enumerate Downloaded assemblies
//
[DllImport("fusion.dll", CharSet=CharSet.Auto)]
internal static extern int CreateAssemblyEnum(out IAssemblyEnum ppEnum,
IApplicationContext pAppCtx,
IAssemblyName pName,
uint dwFlags,
int pvReserved);
[DllImport("fusion.dll", CharSet=CharSet.Auto)]
internal static extern int CreateAssemblyNameObject(out IAssemblyName ppName,
string szAssemblyName,
uint dwFlags,
int pvReserved);
// ?????
[DllImport("fusion.dll")]
internal static extern int CreateApplicationContext(out IApplicationContext ppAppContext,
uint dw);
[DllImport("fusion.dll")]
internal static extern int GetCachePath(uint flags,
[MarshalAs(UnmanagedType.LPWStr)] StringBuilder wzDir,
ref uint pdwSize);
public static string GetGacPath(bool isCLRv4 = false)
{
const uint ASM_CACHE_ROOT = 0x08; // CLR V2.0
const uint ASM_CACHE_ROOT_EX = 0x80; // CLR V4.0
uint flags = isCLRv4 ? ASM_CACHE_ROOT_EX : ASM_CACHE_ROOT;
const int size = 260; // MAX_PATH
StringBuilder b = new StringBuilder(size);
uint tmp = size;
GetCachePath(flags, b, ref tmp);
return b.ToString();
}
}
}

32
src/AddIns/DisplayBindings/ILSpyAddIn/LaunchILSpy/ILSpyAssemblyResolver.cs

@ -8,6 +8,7 @@ using System.Linq; @@ -8,6 +8,7 @@ using System.Linq;
using System.Text;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Dom;
using Mono.Cecil;
namespace ICSharpCode.ILSpyAddIn.LaunchILSpy
@ -16,6 +17,7 @@ namespace ICSharpCode.ILSpyAddIn.LaunchILSpy @@ -16,6 +17,7 @@ namespace ICSharpCode.ILSpyAddIn.LaunchILSpy
{
readonly DirectoryInfo directoryInfo;
readonly IDictionary<string, AssemblyDefinition> cache;
readonly IDictionary<string, AssemblyDefinition> localAssembliesCache;
public ILSpyAssemblyResolver(string decompiledAssemblyFolder)
{
@ -25,6 +27,9 @@ namespace ICSharpCode.ILSpyAddIn.LaunchILSpy @@ -25,6 +27,9 @@ namespace ICSharpCode.ILSpyAddIn.LaunchILSpy
FolderPath = decompiledAssemblyFolder;
this.directoryInfo = new DirectoryInfo(decompiledAssemblyFolder);
this.cache = new Dictionary<string, AssemblyDefinition> ();
this.localAssembliesCache = new Dictionary<string, AssemblyDefinition>();
ReadLocalAssemblies();
}
public string FolderPath {
@ -49,13 +54,9 @@ namespace ICSharpCode.ILSpyAddIn.LaunchILSpy @@ -49,13 +54,9 @@ namespace ICSharpCode.ILSpyAddIn.LaunchILSpy
if (cache.TryGetValue(name.FullName, out assembly))
return assembly;
// serach into assemblyDecompiledFolder
var file = this.directoryInfo.GetFiles()
.Where(f => f != null && f.FullName.Contains(name.Name))
.FirstOrDefault();
if (file != null) {
assembly = AssemblyDefinition.ReadAssembly(file.FullName, parameters);
// search into assemblyDecompiledFolder
if (localAssembliesCache.ContainsKey(name.FullName)) {
assembly = localAssembliesCache[name.FullName];
}
if (assembly == null) {
@ -72,7 +73,7 @@ namespace ICSharpCode.ILSpyAddIn.LaunchILSpy @@ -72,7 +73,7 @@ namespace ICSharpCode.ILSpyAddIn.LaunchILSpy
}
return assembly;
} catch (Exception ex) {
LoggingService.Error("Exception: " + ex.Message);
LoggingService.Error("Exception (ILSpyAssemblyResolver): " + ex.Message);
return null;
}
}
@ -90,6 +91,19 @@ namespace ICSharpCode.ILSpyAddIn.LaunchILSpy @@ -90,6 +91,19 @@ namespace ICSharpCode.ILSpyAddIn.LaunchILSpy
return Resolve(AssemblyNameReference.Parse(fullName), parameters);
}
void ReadLocalAssemblies()
{
// read local assemblies
foreach (var file in this.directoryInfo.GetFiles()) {
try {
var localAssembly = AssemblyDefinition.ReadAssembly(file.FullName);
localAssembliesCache.Add(localAssembly.FullName, localAssembly);
} catch {
// unable to read assembly file
}
}
}
#region FindAssemblyInGac
// This region is based on code from Mono.Cecil:
@ -118,7 +132,7 @@ namespace ICSharpCode.ILSpyAddIn.LaunchILSpy @@ -118,7 +132,7 @@ namespace ICSharpCode.ILSpyAddIn.LaunchILSpy
// 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[] gac_paths = { GacInterop.GacRootPathV2, GacInterop.GacRootPathV4 };
static readonly string[] gacs = { "GAC_MSIL", "GAC_32", "GAC" };
static readonly string[] prefixes = { string.Empty, "v4.0_" };

2
src/AddIns/DisplayBindings/ILSpyAddIn/ViewContent/DecompiledViewContent.cs

@ -146,7 +146,7 @@ namespace ICSharpCode.ILSpyAddIn @@ -146,7 +146,7 @@ namespace ICSharpCode.ILSpyAddIn
AnalyticsMonitorService.TrackException(ex);
StringWriter writer = new StringWriter();
writer.WriteLine("Exception while decompiling " + fullTypeName);
writer.WriteLine(string.Format("Exception while decompiling {0} ({1})", fullTypeName, assemblyFile));
writer.WriteLine();
writer.WriteLine(ex.ToString());
WorkbenchSingleton.SafeThreadAsyncCall(OnDecompilationFinished, writer);

Loading…
Cancel
Save