diff --git a/src/AddIns/DisplayBindings/ILSpyAddIn/ILSpyAddIn.csproj b/src/AddIns/DisplayBindings/ILSpyAddIn/ILSpyAddIn.csproj
index 44512a97fa..8bb7218718 100644
--- a/src/AddIns/DisplayBindings/ILSpyAddIn/ILSpyAddIn.csproj
+++ b/src/AddIns/DisplayBindings/ILSpyAddIn/ILSpyAddIn.csproj
@@ -64,6 +64,8 @@
Properties\GlobalAssemblyInfo.cs
+
+
diff --git a/src/AddIns/DisplayBindings/ILSpyAddIn/LaunchILSpy/Fusion.cs b/src/AddIns/DisplayBindings/ILSpyAddIn/LaunchILSpy/Fusion.cs
new file mode 100644
index 0000000000..b25db8aff6
--- /dev/null
+++ b/src/AddIns/DisplayBindings/ILSpyAddIn/LaunchILSpy/Fusion.cs
@@ -0,0 +1,216 @@
+// 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();
+ }
+ }
+}
diff --git a/src/AddIns/DisplayBindings/ILSpyAddIn/LaunchILSpy/ILSpyAssemblyResolver.cs b/src/AddIns/DisplayBindings/ILSpyAddIn/LaunchILSpy/ILSpyAssemblyResolver.cs
new file mode 100644
index 0000000000..8c4771895a
--- /dev/null
+++ b/src/AddIns/DisplayBindings/ILSpyAddIn/LaunchILSpy/ILSpyAssemblyResolver.cs
@@ -0,0 +1,118 @@
+// 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.IO;
+using System.Linq;
+using System.Text;
+
+using Mono.Cecil;
+
+namespace ICSharpCode.ILSpyAddIn.LaunchILSpy
+{
+ class ILSpyAssemblyResolver : DefaultAssemblyResolver
+ {
+ readonly DirectoryInfo directoryInfo;
+
+ public ILSpyAssemblyResolver(string decompiledAssemblyFolder)
+ {
+ if (string.IsNullOrEmpty(decompiledAssemblyFolder))
+ throw new ArgumentException("Invalid working folder");
+
+ this.directoryInfo = new DirectoryInfo(decompiledAssemblyFolder);
+ }
+
+ public override AssemblyDefinition Resolve(AssemblyNameReference name)
+ {
+ try {
+ // search default
+ var defaultAssembly = base.Resolve(name);
+ if (defaultAssembly != null)
+ return defaultAssembly;
+ } catch (AssemblyResolutionException) {
+ // serach into assemblyDecompiledFolder
+ var file = this.directoryInfo.GetFiles()
+ .Where(f => f != null && f.FullName.Contains(name.Name))
+ .FirstOrDefault();
+ if (file != null)
+ return AssemblyDefinition.ReadAssembly(file.FullName);
+
+ // search using ILSpy's GacInterop.FindAssemblyInNetGac()
+ string fileInGac = FindAssemblyInNetGac(name);
+ if (!string.IsNullOrEmpty(fileInGac))
+ return AssemblyDefinition.ReadAssembly(fileInGac);
+ }
+ return null;
+ }
+
+ #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_" };
+
+ ///
+ /// Gets the file name for an assembly stored in the GAC.
+ ///
+ public static string FindAssemblyInNetGac (AssemblyNameReference reference)
+ {
+ // without public key, it can't be in the GAC
+ if (reference.PublicKeyToken == null)
+ return null;
+
+ 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
+ }
+}
diff --git a/src/AddIns/DisplayBindings/ILSpyAddIn/ViewContent/DecompiledViewContent.cs b/src/AddIns/DisplayBindings/ILSpyAddIn/ViewContent/DecompiledViewContent.cs
index 3237536bc5..b3b38cfc88 100644
--- a/src/AddIns/DisplayBindings/ILSpyAddIn/ViewContent/DecompiledViewContent.cs
+++ b/src/AddIns/DisplayBindings/ILSpyAddIn/ViewContent/DecompiledViewContent.cs
@@ -9,6 +9,7 @@ using System.Threading;
using ICSharpCode.Core;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Ast;
+using ICSharpCode.ILSpyAddIn.LaunchILSpy;
using ICSharpCode.ILSpyAddIn.ViewContent;
using ICSharpCode.NRefactory.CSharp;
using ICSharpCode.NRefactory.Utils;
@@ -151,7 +152,7 @@ namespace ICSharpCode.ILSpyAddIn
ReaderParameters readerParameters = new ReaderParameters();
// Use new assembly resolver instance so that the AssemblyDefinitions can be garbage-collected
// once the code is decompiled.
- readerParameters.AssemblyResolver = new DefaultAssemblyResolver();
+ readerParameters.AssemblyResolver = new ILSpyAssemblyResolver(Path.GetDirectoryName(assemblyFile));
ModuleDefinition module = ModuleDefinition.ReadModule(assemblyFile, readerParameters);
TypeDefinition typeDefinition = module.GetType(fullTypeName);