添加装配体参考对话框

发布于 2024-08-12 02:02:55 字数 170 浏览 2 评论 0原文

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

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

如果不可能,我如何从 GAC 获取所有程序集的列表?

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 into 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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

丑疤怪 2024-08-19 02:02:55

有一个未记录的 API,它允许您从 GAC 枚举程序集。

There's an undocumented API which allows you to enumerate assemblies from the GAC.

战皆罪 2024-08-19 02:02:55

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

第一种方法:以下代码片段显示如何实现您的目标:

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

请告诉我

如果您还有其他问题,

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

一梦浮鱼 2024-08-19 02:02:55

您不希望您的应用程序那么慢,对吧:P

源代码可用于 CR_QuickAddReference

You dont want your app to be that slow, do you :P

Source is available for CR_QuickAddReference.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文