add assembly reference dialog
Is there a way to use visual studio's "add assembly reference dialog" (or something similar) in my own application? I need it for dynamic code generation and compilation.
This is not simply an OpenFileDialog, since it additionally looks in开发者_JS百科to the GAC and so on, so it will be very complicated to do it on my own, I think.
If this is not possible, how can I get a list of all assemblies from the GAC?
There's an undocumented API which allows you to enumerate assemblies from the GAC.
The best way to get all assemblies from the GAC is to use Fusion
first approch: The following code snippet shows how to achieve your goal:
internal class GacApi
{
[DllImport("fusion.dll")]
internal static extern IntPtr CreateAssemblyCache(
out IAssemblyCache ppAsmCache,
int reserved);
}
[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("e707dcde-d1cd-11d2-bab9-00c04f8eceae")]
internal interface IAssemblyCache
{
int Dummy1();
[PreserveSig()]
IntPtr QueryAssemblyInfo(int flags, [MarshalAs(UnmanagedType.LPWStr)] String assemblyName, ref ASSEMBLY_INFO assemblyInfo); int Dummy2(); int Dummy3(); int Dummy4();
}
[StructLayout(LayoutKind.Sequential)]
internal struct ASSEMBLY_INFO
{
public int cbAssemblyInfo;
public int assemblyFlags;
public long assemblySizeInKB;
[MarshalAs(UnmanagedType.LPWStr)]
public String currentAssemblyPath;
public int cchBuf;
}
class Program
{
static void Main()
{
try
{
Console.WriteLine(QueryAssemblyInfo("System"));
}
catch(System.IO.FileNotFoundException e)
{
Console.WriteLine(e.Message);
}
}
public static String QueryAssemblyInfo(String assemblyName)
{
ASSEMBLY_INFO assembyInfo = new ASSEMBLY_INFO ();
assembyInfo.cchBuf = 512;
assembyInfo.currentAssemblyPath = new String('\0', assembyInfo.cchBuf) ;
IAssemblyCache assemblyCache = null;
IntPtr hr = GacApi.CreateAssemblyCache(out assemblyCache, 0);
if (hr == IntPtr.Zero)
{
hr = assemblyCache.QueryAssemblyInfo(1, assemblyName, ref assembyInfo);
if(hr != IntPtr.Zero)
Marshal.ThrowExceptionForHR(hr.ToInt32());
}
else
Marshal.ThrowExceptionForHR(hr.ToInt32());
return assembyInfo.currentAssemblyPath;
}
}
second approach: The GAC directory (%systemroot%\assembly for default installations) is a standard directory like any other directory and you should be able to loop through the directory, load the assemblies and retrieve type information of all types within the assembly.
Edit: The code for the easiest way:
List<string> dirs = new List<string>() {
"GAC", "GAC_32", "GAC_64", "GAC_MSIL",
"NativeImages_v2.0.50727_32",
"NativeImages_v2.0.50727_64",
"NativeImages_v4.0.50727_32",
"NativeImages_v4.0.50727_64"
};
string baseDir = @"c:\windows\assembly";
int i = 0;
foreach (string dir in dirs)
if (Directory.Exists(Path.Combine(baseDir, dir)))
foreach (string assemblyDir in Directory.GetFiles(Path.Combine(baseDir, dir), "*.dll", SearchOption.AllDirectories))
Console.WriteLine(assemblyDir);
More information about Fusion.dll can be found at:
http://support.microsoft.com/kb/317540
Let me know if you have other questions
s
You dont want your app to be that slow, do you :P
Source is available for CR_QuickAddReference.
精彩评论