Требуется уточнение: как среда выполнения .NET разрешает ссылки на сборки из родительской папки?

У меня есть следующая структура вывода исполняемых файлов в моем решении:

%ProgramFiles%
    |
    +-[MyAppName]
          |
          +-[Client]
          |     |
          |     +-(EXE & several DLL assemblies)
          |
          +-[Common]
          |     |
          |     +-[Schema Assemblies]
          |     |     |
          |     |     +-(several DLL assemblies)
          |     |
          |     +-(several DLL assemblies)
          |
          +-[Server]
                |
                +-(EXE & several DLL assemblies)

Каждый проект в решении ссылается на разные сборки DLL, некоторые из которых являются выходными данными других проектов в решении, а другие являются простыми сторонними сборками. Например, [Client] EXE может ссылаться на сборку в [Common], которая находится в другой ветви каталога.

Во всех ссылках для параметра «Копировать локально» установлено значение false, чтобы отразить расположение файлов в окончательном установленном приложении.

Теперь, если я взгляну на свойства ссылок в Visual Studio IDE, я увижу, что «Путь» каждой ссылки является абсолютным и соответствует фактическому выходному местоположению сборки. Это понятно и правильно. Как и ожидалось, решение компилируется и работает нормально.

Чего я не понимаю, так это почему все работает, даже когда я закрываю IDE, переименовываю каталог [MyAppName] и запускаю [Client] EXE вручную? Как среда выполнения находит сборки, если ссылочные пути не совпадают с теми, что были во время компоновки?

Чтобы было ясно, это именно то, что мне нужно: полураспределенный набор файлов приложений, которые нормально работают независимо от того, где находится каталог [MyAppName] или даже от того, как он называется. Я просто хотел бы знать, как и почему это работает без какого-либо конкретного разрешения пути с моей стороны.

Я прочитал ответы на этот похожий вопрос, но все же не понимаю.

Помощь очень ценится!


person aoven    schedule 20.01.2009    source источник


Ответы (4)


Насколько я знаю, единственное решение состоит в том, чтобы иметь по крайней мере «заглушки» exes в MyAppBase, а затем определять подкаталоги в качестве источников для DLL в app.config для каждого приложения.

NTFS поддерживает «монтирование» других каталогов (например, жестких ссылок) в качестве подкаталогов, но они очень неавтоматически, и, поскольку я не пробовал идти этим путем, кроме теоретизирования, я не могу сказать, сработает ли это как хак.

person Pasi Savolainen    schedule 25.04.2009
comment
Как определить источник DLL в app.config? - person Louis Rhys; 05.01.2011
comment
<configuration> <runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <probing privatePath="path\to\dlls"/> </assemblyBinding> </runtime> </configuration> доберется до path\to\dlls - person Pasi Savolainen; 05.01.2011

Вот как .Net находит необходимые сборки: http://msdn.microsoft.com/en-us/library/yx7xezcf(VS.71).aspx

Вам может быть интересно прочитать шаг 4: http://msdn.microsoft.com/en-us/library/15hyw9x3(VS.71).aspx

person Gerrie Schenck    schedule 20.01.2009
comment
Я читал эти ссылки раньше, но не нашел ответа на то, как среда выполнения находит сборку, которая не находится в ветке ApplicationBase, например [Common] в моем примере. - person aoven; 20.01.2009

Рассматривали ли вы возможность использования GACutil для добавления общего сборки в глобальный кэш сборок

person Rowland Shaw    schedule 20.01.2009
comment
Нет. Насколько я понимаю, GAC предназначен для общих сборок. Как и в тех, которые используются несколькими приложениями. Мои сборки не используются другими приложениями - они закрыты для установки моего приложения (будь то клиентская часть, серверная часть или, в редких случаях, обе). - person aoven; 20.01.2009

Может быть, папка Common была указана как параметр binpath при компиляции?

(См. Проверка частного binpath)

http://msdn.microsoft.com/en-us/library/15hyw9x3%28VS.71%29.aspx

-Мэтт

person Matt Frear    schedule 05.05.2010