开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜