Permalink
Browse files

Properly resolve local assemblies.

  • Loading branch information...
1 parent 6cac9f6 commit 5dab78384259fdacd33847d465ef75e536392f35 @eusebiu eusebiu committed with dgrunwald Aug 19, 2011
@@ -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" />
@@ -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();
- }
- }
-}
@@ -8,6 +8,7 @@
using System.Text;
using ICSharpCode.Core;
+using ICSharpCode.SharpDevelop.Dom;
using Mono.Cecil;
namespace ICSharpCode.ILSpyAddIn.LaunchILSpy
@@ -16,6 +17,7 @@ class ILSpyAssemblyResolver : IAssemblyResolver
{
readonly DirectoryInfo directoryInfo;
readonly IDictionary<string, AssemblyDefinition> cache;
+ readonly IDictionary<string, AssemblyDefinition> localAssembliesCache;
public ILSpyAssemblyResolver(string decompiledAssemblyFolder)
{
@@ -25,6 +27,9 @@ public ILSpyAssemblyResolver(string decompiledAssemblyFolder)
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 @@ public AssemblyDefinition Resolve(AssemblyNameReference name, ReaderParameters p
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 @@ public AssemblyDefinition Resolve(AssemblyNameReference name, ReaderParameters p
}
return assembly;
} catch (Exception ex) {
- LoggingService.Error("Exception: " + ex.Message);
+ LoggingService.Error("Exception (ILSpyAssemblyResolver): " + ex.Message);
return null;
}
}
@@ -90,6 +91,19 @@ public AssemblyDefinition Resolve(string fullName, ReaderParameters parameters)
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 @@ public AssemblyDefinition Resolve(string fullName, ReaderParameters parameters)
// 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_" };
@@ -146,7 +146,7 @@ void DecompilationThread()
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);

0 comments on commit 5dab783

Please sign in to comment.