汇编文件重命名和Assembly.LoadFile

5

现在的情况是:

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

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

enter image description here

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

LoadFile的MSDN文档:

使用LoadFile方法加载和检查具有相同标识但位于不同路径上的程序集。 LoadFile不会将文件加载到LoadFrom上下文中,并且不会像LoadFrom方法一样使用加载路径来解析依赖项。 LoadFile在此限制场景中非常有用,因为无法使用LoadFrom加载具有相同标识但不同路径的程序集;它只会加载第一个这样的程序集。

2个回答

2
我建议您简化问题,因为我刚刚尝试重现您的情况,并没有遇到任何问题。我创建了一个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: LoadImage调用的Process Monitor跟踪

然而,如果监视所有事件,我会看到它在应用程序目录中探测Lib.dll。 所有对Debug\Lib的引用的Process Monitor跟踪

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


谢谢BlueMonkMN,这有些意义。如果库是动态加载的,则可以加载原始库,但我在帖子中附加的进程监视器日志是使用以下Lib1生成的。使用系统;命名空间Lib1 { public class Class1 { public void SayHello() { Console.WriteLine("Class1 :: SayHello"); } } }您能否运行进程监视器并检查控制台应用程序是否正在尝试加载两个dll。 - Faisal Mansoor
看起来它找不到它,因为我把DLL放在应用程序目录之外的一个目录中。 - BlueMonkMN

1

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

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


LoadFile不支持相对路径,它需要程序集的绝对路径,因此我认为上面的答案与这个问题无关。无论如何,谢谢。 - Faisal Mansoor

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接