【问题标题】:How to get all the referenced assemblies using reflection ? (.net4)如何使用反射获取所有引用的程序集? (.net4)
【发布时间】:2021-07-05 11:25:15
【问题描述】:

我编写了一段代码,它为我提供了一个程序集(在 .net5 中)的引用程序集,它运行良好,例如,如果我使用 File.WriteAllText 方法,程序集“System.IO” .FileSystem”(这是通过使用 Assembly.GetReferencedAssemblies 方法)。

但现在我需要让这段代码在 .NET4(用于 Unity 引擎)上工作。但我发现 myAssembly.GetReferencedAssemblies 的输出与 .NET5 中的不同。

它现在只给我:myAssembly.dll 和 mscorlib.dll

而且我无法像以前一样向我提供所有引用的程序集(例如 System 或 System.IO ...)

这是一个简单的例子:

    using System.IO;

    public class Plugin {

         static Plugin() {

             // Just use the File class to keep the System.IO assembly reference
             File.WriteAllText("test", string.Empty);

         }

    }

    public static void Test() {

        string myPluginPath = "myAssembly.dll";

        // Load the assembly
        Assembly assembly = Assembly.LoadFrom(myPluginPath);

        // Get all the referenced assemblies
        foreach (AssemblyName name in assembly.GetReferencedAssemblies()) {

            Console.WriteLine(name.Name);

            // Different outputs:
            //
            // .NET 5
            // - System.IO.FileSystem
            // - ....
            // .NET 4
            // - mscorlib
            // - Plugin

        }

    }

知道如何让 myAssembly.GetReferencedAssemblies 在 .net4 上工作吗?谢谢!

【问题讨论】:

  • 请向我们提供minimal reproducible example,向我们展示您在 .NET 4 和 .NET 5 中看到的输出。
  • 我添加了一个简单的例子

标签: c# reflection .net-assembly


【解决方案1】:

知道如何让myAssembly.GetReferencedAssemblies 在.net4 上工作吗?

System.IO.File 驻留在 .NET Framework 中的 mscorlib.dll 中,因此两个版本都可以正常工作。为什么需要实际的程序集名称?您不能跨平台依赖它们。

另一方面,如果您需要它来解析程序集限定类型名称,那么您可以使用旧程序集标识来实现,因此 Type.GetType("System.IO.File, mscorlib, Version=4.0.0.0") 也适用于 .NET 5。

这是因为即使在较新的平台上也有一个 mscorlib.dll,它只包含一组 [assembly:TypeForwardedTo(...)] 属性,用于提供到新位置的重定向。

但它不会反过来工作,所以不要指望你可以从 .NET Framework 4.0 中的 System.IO.FileSystem.dll 解析类型 File


评论后更新:

在 .NET Framework 中,handling potentially harmful plugins 的最佳方法是为它们创建单独的 AppDomains,但具有受限的权限。 Here 是我的单元测试中创建此类沙箱域的示例,here 是示例用法。 AppDomains 甚至可以连同它们引用的程序集一起卸载。

坏消息是这在 .NET 5 中不起作用,因为从 .NET Core 开始,您无法再创建 AppDomains(如果您已经有了 .NET 5 的解决方案,这不是什么大问题)。但为了完整起见:从 .NET Core 3.0 开始,AssemblyLoadContext 类型是用于处理插件的 recommended way。虽然它不会像AppDomain 那样创建受限环境,但您可以使用AssemblyDependencyResolver 来控制插件的程序集加载请求。

【讨论】:

  • 我实际上是在用 Unity 做一个“插件”或“修改”系统。基本上我想让用户创建自定义.dll,然后将它们加载到游戏中。但我需要防止用户创建可能损害其他玩家计算机的 dll(通过不允许使用某些命名空间的 dll,如 System.IO 或互操作服务(对于 DllImport 属性))。也许还有另一种解决方案来分析程序集以检查它们是否有不安全的程序集?
  • 非常感谢!这正是我想要的!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-08-24
  • 2011-01-15
  • 1970-01-01
  • 1970-01-01
  • 2023-04-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多