Свои References, но в подпапке

210
24 мая 2017, 03:35

Есть решение с двумя проектами

  • DLL библиотека

  • WPF приложение, использующее DLL в References

При компилировании проекта WPF, DLL помещается в папку с EXE. Однако по независимым от меня причинам необходимо что бы WPF приложение искало эту DLL в папке [номер версии] в папке приложения т.е.:

Если приложение находится в папке c:\MyProject\project.exe, а у файла версия 1.0.3.24 значит DLL будет находиться в c:\MyProject\1.0.3.24\MyLibrary.dll

Вот моё решение:

Свойство Build Action у App.xaml установил в Page, а в App.xaml.cs добавил код.

[STAThread]
public static void Main()
{
  try
  {
    //Берём Assembly приложения
    System.Reflection.Assembly assembly = System.Reflection.Assembly.GetExecutingAssembly();
    //Берём папку приложения
    string appDirectory = System.IO.Path.GetDirectoryName(assembly.Location);
    //Берём версию приложения
    string appVersion = System.Diagnostics.FileVersionInfo.GetVersionInfo(assembly.Location).FileVersion;
    //Вычисляем папку с DLL
    string dllpatch = System.IO.Path.Combine(appDirectory, appVersion);
    //Берем переменную окружения PATH
    string environmentPATH = Environment.GetEnvironmentVariable("PATH");
    //Устанавливаем переменную окружения PATH
    Environment.SetEnvironmentVariable("PATH", environmentPATH + ";" + dllpatch, EnvironmentVariableTarget.Process);
    //Запускаем приложение
    var application = new App();
    application.InitializeComponent();
    application.Run();
  }
  catch (Exception ex)
  {
    //Эта строка не срабатывает, Exeption не отлавливается
    System.Diagnostics.EventLog.WriteEntry("MyApplication", ex.Message + "\n" + ex.StackTrace, System.Diagnostics.EventLogEntryType.Error);
  }
}

Однако, при запуске проекта всё нормально, но как только я помещаю dll в вышеуказанную папку try catch не срабатывает, приложение сваливается в исключение, а лог винды выводиться:

Приложение: project.exe Версия платформы: v4.0.30319 Описание. Процесс был завершен из-за необработанного исключения. Сведения об исключении: System.IO.FileNotFoundException
в MyNameSpace.App.Main()

Answer 1

Попробуй воспользоваться codeBase в app.config.

<configuration>  
   <runtime>  
      <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">  
       <dependentAssembly>  
         <assemblyIdentity name="myAssembly"  
                           publicKeyToken="32ab4ba45e0a69a1"  
                           culture="en-us" />  
         <codeBase version="2.0.0.0"  
                   href="http://www.litwareinc.com/myAssembly.dll"/>  
       </dependentAssembly>  
      </assemblyBinding>  
   </runtime>  
</configuration>  

Еще есть <probing>. В нем можно указывать директории для поиска сборок.

<configuration>
   <runtime>
      <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
         <probing privatePath="bin;bin2\subbin;bin3"/>
      </assemblyBinding>
   </runtime>
</configuration>
Answer 2

Событие AssemblyResolve

Событие AssemblyResolve позволяет вмешаться в процесс и вручную загрузить сборку, которую CLR не может найти. Если это событие обрабатывается, то ссылаемые сборки можно распределять по различным местоположениям и по-прежнему обеспечивать их загрузку.
Внутри обработчика события AssemblyResolve производится поиск сборки и ее загрузка за счет вызова одного из трех статических методов класса Assembly: Load, LoadFrom или LoadFile. Эти методы возвращают ссылку на вновь загруженную сборку, и данная ссылка затем возвращается вызывающему коду:

static void Main()
{
    AppDomain.CurrentDomain.AssemblyResolve += FindAssembly;
    ...
}
static Assembly FindAssembly (object sender, ResolveEventArgs args)
{
    string fullyQualifiedName = args.Name;
    Assembly а = Assembly.LoadFrom(...);
    return а;
}

PS. Да, это необычное событие - оно имеет возвращаемый тип. При наличии множества обработчиков преимущество получает первый обработчик, который возвратил отличный от null объект Assembly.

Литература:
Албахари, Джозеф, Албахари, Бен.
С# 6.0. Справочник. Полное описание языка, 6-е изд. : Пер. с англ. - М. : ООО "И.Д. Вильямс", 2016. - 1040 с.: ил. - Парал. тит. англ.
ISBN 978-5-8459-2087-4 (рус.)

READ ALSO
Где найти описание протокола SSL proxy?

Где найти описание протокола SSL proxy?

Хочу написать SSL proxyМожет быть у кого-нибудь есть описание протокола?

233
Необработанное исключение типа &ldquo;System.OverflowException&rdquo; в mscorlib.dll

Необработанное исключение типа “System.OverflowException” в mscorlib.dll

ConvertToInt16 выбрасывает OverflowException если переданное значение не укладывается в диапазон Int16, т

207
Проблема в обработчике формы с Recaptcha

Проблема в обработчике формы с Recaptcha

У меня на локалке форма с капчей срабатывает На локалке, а на сервере пишет ОшибкаСообщение не отправлено!

275
Unable to register extension &ldquo;*&rdquo; as extensions have already been initialized

Unable to register extension “*” as extensions have already been initialized

При загрузке Extension в Twig, происходит ошибка Unable to register extension "SectionParser" as extensions have already been initialized

393