【问题标题】:Assembly file renaming and Assembly.LoadFile程序集文件重命名和 Assembly.LoadFile
【发布时间】:2011-04-15 16:09:22
【问题描述】:

所以情况如下:

我有一个名为 Lib1.dll 的程序集。由于某种原因(与问题无关),我不得不将程序集文件名重命名为 Lib1New.dll,现在在尝试使用 Assembly.LoadFile 加载重命名的程序集时,我注意到 CLR 也尝试加载 Lib1.dll。

如果在搜索路径中找到 Lib1.dll,它将被加载到地址空间中。无论是否找到 Lib1.dll,该应用程序都可以正常工作。 (问题是如果找到 Lib1.dll 文件会被锁定,其他进程无法删除)。

我不明白为什么 LoadFile 会搜索并加载 Lib1.dll。 LoadFile应该是在指定位置加载程序集文件的内容,为什么要搜索文件。

LoadFile 的 MSDN 文档:

使用 LoadFile 方法加载和检查具有相同标识但位于不同路径的程序集。 LoadFile 不会将文件加载到 LoadFrom 上下文中,也不会像 LoadFrom 方法那样使用加载路径解析依赖关系。 LoadFile 在这种有限的场景中很有用,因为 LoadFrom 不能用于加载具有相同身份但不同路径的程序集;它只会加载第一个这样的程序集。

【问题讨论】:

    标签: c# file-io clr .net-assembly


    【解决方案1】:

    我建议您尝试简化您的问题,因为我只是尝试重现您的情况并且没有遇到任何问题。我创建了一个 Lib.dll 程序集,对其进行编译,创建了一个使用 LoadFile 加载它的控制台应用程序,然后将 Lib.dll 和控制台对它的引用重命名为“LibNew.dll”。然后我重新编译了 lib.dll 并运行了控制台应用程序。那时我无法删除 LibNew.dll,但我可以删除 Lib.dll。

    我怀疑您的 Lib.dll 可能会在启动时从其自己的程序集中加载一些信息,并且在内部使用另一个 Load 函数来执行此操作,最终找到原始 Lib.dll。但是如果你有一个非常简单的 DLL,它就不会做额外的负载。我的 DLL 有一个函数,我可以调用它,但我仍然看到上面报告的结果。这是我的代码:

    控制台应用程序:

    class Program
    {
        static void Main(string[] args)
        {
            System.Reflection.Assembly assy = System.Reflection.Assembly.LoadFile(args[0]);
            Type class1 = assy.GetType("Lib.Class1");
    
            System.Reflection.MethodInfo myMethod = class1.GetMethod("MyMethod");
            Console.WriteLine(myMethod.Invoke(null, new object[] {"This is a string"}).ToString());
    
            Console.ReadLine();
        }
    }
    

    库:

    namespace Lib
    {
    public class Class1
    {
        public static string MyMethod(string param)
        {
            return "Fixed: [" + param.Replace(" ", "-") + "]";
        }
    }
    }
    

    仅监控 LoadImage 调用,我发现它没有尝试加载 Lib.dll:

    但是,在监视所有事件时,我发现它确实 探测了应用程序目录中的 Lib.dll。

    也许如果您将 DLL 放在另一个目录中,您可以强制执行您想要的行为?不过,考虑到文档,这是一种奇怪的行为。

    【讨论】:

    • 感谢 BlueMonkMN,这有点道理。如果库是动态加载自身,则可以加载原始库,但我附在帖子中的进程监控日志是使用以下 Lib1 using System 生成的;命名空间 Lib1 { public class Class1 { public void SayHello() { Console.WriteLine("Class1::SayHello"); } } } 你可以运行进程监视器并检查控制台应用程序是否正在尝试加载这两个 dll。
    • 看起来没有找到它,因为我在应用程序目录以外的目录中拥有 DLL。
    【解决方案2】:

    LoadFile 使用 Windows 文件搜索而不是 .NET 的程序集解析。但它仍在搜索文件。

    类似于调用new FileStream(),您可以在其中传递文件名,如果它是相对路径,它将在PATH等中查找它。

    【讨论】:

    • LoadFile 不适用于相对路径,它需要程序集的绝对路径,所以我认为上述答案与这个问题无关。还是谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-09
    • 2010-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多