添加程序集引用对话框

时间:2009-11-25 15:15:05

标签: c# visual-studio-2008 assemblies code-generation gac

有没有办法在我自己的应用程序中使用visual studio的“添加程序集引用对话框”(或类似的东西)?我需要它来进行动态代码生成和编译。

这不仅仅是一个OpenFileDialog,因为它还会调查GAC等等,所以我认为自己这样做会非常复杂。

如果无法做到这一点,我如何从GAC获取所有程序集的列表?

3 个答案:

答案 0 :(得分:2)

有一个undocumented API,允许您枚举GAC中的程序集。

答案 1 :(得分:2)

从GAC获取所有程序集的最佳方法是使用Fusion

第一个approch :以下代码段显示了如何实现目标:

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;
    }
}

第二种方法:GAC目录(默认安装的%systemroot%\ assembly)是一个标准目录,就像任何其他目录一样,您应该能够遍历目录,加载程序集并检索在程序集中键入所有类型的信息。

编辑:最简单方法的代码:

            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);

有关Fusion.dll的更多信息,请访问:

http://support.microsoft.com/kb/317540

如果您有其他问题,请告诉我

取值

答案 2 :(得分:1)

你不希望你的应用那个慢,你呢:P

来源可用于CR_QuickAddReference