Сборка переименования файлов и Assembly.LoadFile - PullRequest
5 голосов
/ 15 апреля 2011

Итак, вот такая ситуация:

У меня есть сборка под названием Lib1.dll.По какой-то причине (не относящейся к вопросу) мне пришлось переименовать имя файла сборки в Lib1New.dll, теперь при попытке загрузить переименованную сборку с помощью Assembly.LoadFile я заметил, что CLR пытается также загрузить Lib1.dll.

Если в пути поиска обнаружен Lib1.dll, он загружается в адресное пространство.Приложение работает нормально независимо от того, был ли найден Lib1.dll или нет.(Проблема в том, что если Lib1.dll найден, файл блокируется и не может быть удален другими процессами.)

enter image description here

Я не понимаю, почему LoadFile ищети загружает Lib1.dll.LoadFile должен загружать содержимое файла сборки в указанном месте, почему он ищет файлы.

Документация MSDN для LoadFile:

Используйте метод LoadFile для загрузки и проверки сборок, которые имеют одинаковые идентификационные данные, но расположены по разным путям.LoadFile не загружает файлы в контекст LoadFrom и не разрешает зависимости, используя путь загрузки, как это делает метод LoadFrom.LoadFile полезен в этом ограниченном сценарии, потому что LoadFrom не может использоваться для загрузки сборок, которые имеют одинаковые идентификаторы, но разные пути;он загрузит только первую такую ​​сборку.

Ответы [ 2 ]

2 голосов
/ 15 апреля 2011

Я предлагаю вам попробовать упростить вашу проблему, потому что я просто попытался воспроизвести вашу ситуацию и не столкнулся с проблемой. Я создал сборку 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();
    }
}

Lib:

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 голос
/ 15 апреля 2011

LoadFile использует поиск файлов Windows, а не разрешение сборки .NET.Но он все равно ищет файл.

Это похоже на вызов new FileStream(), где вы можете передать fileName, и он будет искать его в PATH и т. Д., Если это относительный путь.

...