【问题标题】:How to get Names of DLLs used by application如何获取应用程序使用的 DLL 的名称
【发布时间】:2010-11-21 06:12:13
【问题描述】:

我正在寻找读取我的应用程序使用的所有程序集 (.dll) 的方法。

在标准 C# 项目中有“References”文件夹,当它展开时,我可以读取所有使用的库。

我的目标是以编程方式读取解决方案中每个项目使用的所有程序集。

最后我想看看我编译的 *.exe 应用程序使用了哪些库。

【问题讨论】:

    标签: c# .net reflection


    【解决方案1】:

    要正确执行此操作,您需要遍历程序集,获取依赖项...如果您的 exe 需要 Dll_A,而 Dll_A 需要 Dll_B(即使 exe 没有引用它),那么您的 exe 也需要 Dll_B .

    您可以通过反射查询这个(在任何程序集上);这需要做一些工作(尤其是防止循环引用,这确实会发生;这是一个从“入口程序集”开始的示例,但这也可以是任何程序集:

        List<string> refs = new List<string>();
        Queue<AssemblyName> pending = new Queue<AssemblyName>();
        pending.Enqueue(Assembly.GetEntryAssembly().GetName());
        while(pending.Count > 0)
        {
            AssemblyName an = pending.Dequeue();
            string s = an.ToString();
            if(refs.Contains(s)) continue; // done already
            refs.Add(s);
            try
            {
                Assembly asm = Assembly.Load(an);
                if(asm != null)
                {
                    foreach(AssemblyName sub in asm.GetReferencedAssemblies())
                    {
                        pending.Enqueue(sub);
                    }
                    foreach (Type type in asm.GetTypes())
                    {
                        foreach (MethodInfo method in type.GetMethods(
                            BindingFlags.Static | BindingFlags.Public |
                                 BindingFlags.NonPublic))
                        {
                            DllImportAttribute attrib = (DllImportAttribute)
                                Attribute.GetCustomAttribute(method,
                                    typeof(DllImportAttribute));
                            if (attrib != null && !refs.Contains(attrib.Value))
                            {
                                refs.Add(attrib.Value);
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Console.Error.WriteLine(ex.Message);
            }
        }
        refs.Sort();
        foreach (string name in refs)
        {
            Console.WriteLine(name);
        }
    

    【讨论】:

    • 这是否也会检测到通过 PInvoke 使用的非托管 dll,还是只提取管理 dll?
    • 仅限托管 dll。您可以使用反射来查找 P/Invoke 方法 - 但反射会略有不同。
    • 我该怎么做?我的反思知识有限,你能指出我正确的方向吗?
    • 您能否使用Assembly 上的扩展方法和yield 更新此内容并返回IEnumerable&lt;Assembly&gt;IEnumerable&lt;AssemblyName&gt;
    • @julealgon 有什么特别的原因吗?我的意思是:如果有人想要,他们可以……在本地做吗?
    【解决方案2】:
    System.Reflection.Assembly []ar=AppDomain.CurrentDomain.GetAssemblies();
    
    foreach (System.Reflection.Assembly a in ar)
    {
     Console.WriteLine("{0}", a.FullName);
    }
    

    【讨论】:

    【解决方案3】:

    我猜你可以使用:

    AssemblyName[] assemblies = this.GetType().Assembly.GetReferencedAssemblies();
    

    【讨论】:

      【解决方案4】:

      如果您有一个Assembly 对象,您可以在其上调用GetReferencedAssemblies() 以获取程序集使用的任何引用。要获取当前运行的项目使用的程序集列表,您可以使用:

      System.Reflection.Assembly.GetExecutingAssembly().GetReferencedAssemblies()
      

      【讨论】:

        【解决方案5】:

        您可以使用AppDomain.GetAssemblies
        但这会给应用程序中显式或隐式使用的所有程序集。

        【讨论】:

        • 据我了解,这将给出已经加载的那些。可能有一些在元数据中被引用,但尚未加载,因为到目前为止执行中还不需要它们。
        • 感谢您的提示!这个 AppDomain.CurrentDomain.GetAssemblies() 也很有意思
        【解决方案6】:

        你看过Assembly.GetReferencedAssemblies吗?

        请注意,您不使用的任何引用最终都不会发送到元数据中,因此您不会在执行时看到它们。

        我之前已经递归地使用GetReferencedAssemblies 来查找命名类型,而无需指定程序集。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-10-22
          • 2012-12-23
          • 2017-12-30
          • 2015-11-02
          • 2015-12-19
          相关资源
          最近更新 更多