程序集文件重命名和Assembly.LoadFile

时间:2011-04-15 16:09:22

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

情况就是这样:

我有一个名为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 个答案:

答案 0 :(得分:2)

我建议您尝试简化您的问题,因为我只是尝试重现您的情况并且没有遇到任何问题。我创建了一个Lib.dll程序集,编译它,创建了一个用LoadFile加载它的控制台应用程序,然后将Lib.dll和Console对它的引用重命名为“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: Process Monitor Trace of LoadImage calls

但是,监视所有事件,我看到在应用程序目录中对Lib.dll进行了探测。 Process Monitor Trace of all references to Debug\Lib

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

答案 1 :(得分:1)

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

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

相关问题