【问题标题】:How to read properties from DLL before Assembly.LoadFile()如何在 Assembly.LoadFile() 之前从 DLL 中读取属性
【发布时间】:2025-11-30 22:00:01
【问题描述】:

我的程序有一个pluginManager 模块,它可以加载一个DLL 文件并运行DLL 的方法,但是我需要在Assembly.LoadFile() 之前读取DLL 的属性。我该怎么办?

我看过关于Assembly的文档,他们在Assembly.LoadFile()之后读取属性,你知道Assembly没有UnLoad()方法,所以我必须在LoadFile()之前读取属性

    private void ImprotZip(string path)
    {
        /*
        1、create tempDir, uppackage to tempDir
        2、Load Plugin DLL, Load plugin dependent lib DLL
        */
        string tempDirectory = CreateRuntimeDirectory(path);
        string[] dllFiles = Directory.GetFiles(tempDirectory);
        ///Load DlL
        foreach(string dll in dllFiles)
        {
            ImprotDll(dll, false);
        }
        string libPath = string.Format("{0}\\lib\\", tempDirectory);
        if (!Directory.Exists(libPath))
            return;
        string[] dlls = Directory.GetFiles(libPath);
        ///Load plugin dependent lib DLL
        foreach(string dll in dlls)
        {
            try
            {
                //filtering same DLL 
                //if(Dll.properties.AssemblyProduct != "something")
                //continue;
                Assembly.LoadFile(dll);
            }
            catch(Exception e)
            {
                e.Log();
            }
        }
    }

【问题讨论】:

  • 是否可以强制将可查询的元数据放在目标 dll 旁边的单独文件中?
  • 你的意思是我可以为插件 dll 文件创建一个 xml 文档?
  • 您应该发布更多代码,这可能是一种更好的整体方式来做您想做的事情,这听起来可能会从一些设计调整中受益。或在 StackExchange -CodeReview 上发帖。
  • 我想过滤同一个 DLL,如果我加载同一个 DLL 程序会崩溃

标签: c# dll .net-assembly


【解决方案1】:

您可以使用 Assembly.ReflectionOnlyLoad 将程序集加载到仅反射上下文中。

我仍然会为仅反射上下文创建一个应用程序域,这样您就可以在完成后卸载该域。您可以使用AppDomain.CreateDomain 方法创建应用程序域。无论如何,您都应该为插件执行此操作,以便在完成后卸载它们。

【讨论】:

  • 如果我加载相同的 DLL 恐怕程序会崩溃
【解决方案2】:

FileVersionInfo.GetVersionInfo 正是您要找的。​​p>

【讨论】:

    【解决方案3】:

    试试这个代码

    AppDomain.CurrentDomain.AssemblyResolve += (sender, bargs) => {

                    String dllName = new AssemblyName(bargs.Name).Name + ".dll";
                    var assem = Assembly.GetExecutingAssembly();
                    String resourceName = assem.GetManifestResourceNames().FirstOrDefault(rn => rn.EndsWith(dllName));
                    if (resourceName == null) return null; // For null assembly
                    using (var stream = assem.GetManifestResourceStream(resourceName))
                    {
                        Byte[] assemblyData = new Byte[stream.Length];
                        stream.Read(assemblyData, 0, assemblyData.Length);
                        return Assembly.Load(assemblyData);
                    }
                };
    

    【讨论】: