#c# #file-io #clr #.net-assembly
#c# #файл-ввод-вывод #среда clr #.net-сборка
Вопрос:
Итак, вот ситуация:
У меня есть сборка под названием Lib1.dll . По какой-то причине (не относящейся к вопросу) Мне пришлось переименовать имя файла сборки в Lib1New.dll , теперь при попытке загрузить переименованную сборку с помощью Assembly.LoadFile Я заметил, что среда CLR пытается загрузить Lib1.dll также.
Если Lib1.dll найдено в пути поиска, оно загружается в адресное пространство. Приложение работает нормально независимо от того, Lib1.dll был найден или нет. (Проблема в том, что если Lib1.dll обнаружено, что файл заблокирован и не может быть удален другими процессами).
Я не понимаю, почему LoadFile выполняет поиск и загружает Lib1.dll . Предполагается, что LoadFile загружает содержимое файла сборки в указанное местоположение, почему он ищет файлы.
Документация MSDN для LoadFile:
Используйте метод LoadFile для загрузки и проверки сборок, которые имеют одинаковый идентификатор, но расположены по разным путям. LoadFile не загружает файлы в контекст LoadFrom и не разрешает зависимости с использованием пути загрузки, как это делает метод LoadFrom. LoadFile полезен в этом ограниченном сценарии, потому что LoadFrom нельзя использовать для загрузки сборок, которые имеют одинаковые идентификаторы, но разные пути; он загрузит только первую такую сборку.
Ответ №1:
Я предлагаю вам попробовать упростить вашу проблему, потому что я просто попытался воспроизвести вашу ситуацию и не столкнулся с проблемой. Я создал Lib.dll сборка, скомпилировал ее, создал консольное приложение, которое загрузило ее с помощью LoadFile, затем переименовал Lib.dll и ссылка консоли на него, чтобы «LibNew.dll «. Затем я повторно скомпилировал lib.dll и запустил консольное приложение. На тот момент я не смог удалить LibNew.dll , но я смог удалить Lib.dll .
Я подозреваю, что ваш Lib.dll возможно, загружает некоторую информацию из своей собственной сборки при запуске и внутренне использует для этого другую функцию загрузки, которая в конечном итоге находит оригинал 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 в другой каталог, вы сможете принудительно изменить желаемое поведение? Однако, учитывая документацию, это странное поведение.
Комментарии:
1. Спасибо BlueMonkMN, в этом есть некоторый смысл. Если библиотека загружается динамически, то можно загрузить исходную библиотеку, но журнал process monitor, который я прикрепил к сообщению, был создан с использованием следующего Lib1 с использованием System; пространство имен Lib1 { открытый класс Class1 { public void sayHello() { Консоль. WriteLine(«Class1::sayHello»); } } } Можете ли вы запустить process monitor и проверить, пытается ли консольное приложение загрузить обе библиотеки DLL или нет.
2. Похоже, что он не нашел его, потому что у меня была DLL в каталоге, отличном от каталога приложения.
Ответ №2:
LoadFile
использует поиск файлов Windows, а не .Разрешение сборки NET. Но он все еще выполняет поиск файла.
Это похоже на вызов, new FileStream()
где вы можете передать имя файла, и он будет искать его в PATH и т.д., Если это относительный путь.
Комментарии:
1. LoadFile не работает с относительными путями, для этого требуется абсолютный путь к сборке, поэтому я не думаю, что приведенный выше ответ имеет отношение к этому вопросу. В любом случае, спасибо