динамический выбор библиотек
От: Z-H  
Дата: 01.10.10 12:54
Оценка:
Помогите, плиз!!!
Есть программа на С#, которая использует библиотеку System.Data.SQLite.dll.
Библиотека System.Data.SQLite.dll существует для x86 и существует для x64
(называется в обоих случаях одинаково).
Если в WINDOWS x32 запустить программу и положить библиотеку для x32 рядом
с exe-файлом — программа работает.
Если в WINDOWS x64 запустить программу и положить библиотеку для x64 рядом
с exe-файлом — программа тоже работает.
Можно ли сделать так, чтобы программа в зависимости от разрядности системы
брала библиотеку не рядом с Exe — файлом, а скажем из поддиректории /X86
(или /X64)?
dll библиотека сборка x64 x86 динамический
Re: динамический выбор библиотек
От: _FRED_ Черногория
Дата: 01.10.10 12:58
Оценка: +3
Здравствуйте, Z-H, Вы писали:

Z-H>Можно ли сделать так, чтобы программа в зависимости от разрядности системы

Z-H>брала библиотеку не рядом с Exe — файлом, а скажем из поддиректории /X86
Z-H>(или /X64)?

Обычно этого не нужно: разрядность системы время от времени не меняется и положить рядом с одной сборкой другую, подходящюю первой в данном окружении — задача инсталятора.
Help will always be given at Hogwarts to those who ask for it.
Re[2]: динамический выбор библиотек
От: Z-H  
Дата: 01.10.10 13:03
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>Здравствуйте, Z-H, Вы писали:


Z-H>>Можно ли сделать так, чтобы программа в зависимости от разрядности системы

Z-H>>брала библиотеку не рядом с Exe — файлом, а скажем из поддиректории /X86
Z-H>>(или /X64)?

_FR>Обычно этого не нужно: разрядность системы время от времени не меняется и положить рядом с одной сборкой другую, подходящюю первой в данном окружении — задача инсталятора.


Забыл сказать, что программа задумывалась как PORTABLE. Т.е. она будет запускаться с одного носителя на разных по разрядности операционках.
Re[3]: динамический выбор библиотек
От: Sinix  
Дата: 01.10.10 13:26
Оценка: 2 (1) -1
Здравствуйте, Z-H, Вы писали:

Z-H>Забыл сказать, что программа задумывалась как PORTABLE. Т.е. она будет запускаться с одного носителя на разных по разрядности операционках.

Тогда build target в x86.
Re: динамический выбор библиотек
От: Pavel_Agurov Россия  
Дата: 01.10.10 13:39
Оценка: 2 (1) +2
Здравствуйте, Z-H, Вы писали:

Z-H>Помогите, плиз!!!

Z-H>Есть программа на С#, которая использует библиотеку System.Data.SQLite.dll.
Z-H>Библиотека System.Data.SQLite.dll существует для x86 и существует для x64
Z-H>(называется в обоих случаях одинаково).
Z-H>Если в WINDOWS x32 запустить программу и положить библиотеку для x32 рядом
Z-H>с exe-файлом — программа работает.
Z-H>Если в WINDOWS x64 запустить программу и положить библиотеку для x64 рядом
Z-H>с exe-файлом — программа тоже работает.
Z-H>Можно ли сделать так, чтобы программа в зависимости от разрядности системы
Z-H>брала библиотеку не рядом с Exe — файлом, а скажем из поддиректории /X86
Z-H>(или /X64)?

Конечно можно:

 AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);

private Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
  // тут суем нужную dll в зависимости от разрядности OS
}


Но я бы засунул обе эти dll в ресурсы exe и брал бы оттуда в зависимости от разрядности операционки. Тогда и "класть рядом" ничего не надо будет.
Re[2]: динамический выбор библиотек
От: Z-H  
Дата: 01.10.10 14:07
Оценка:
Здравствуйте, Pavel_Agurov, Вы писали:

P_A>Здравствуйте, Z-H, Вы писали:


Z-H>>Помогите, плиз!!!

Z-H>>Есть программа на С#, которая использует библиотеку System.Data.SQLite.dll.
Z-H>>Библиотека System.Data.SQLite.dll существует для x86 и существует для x64
Z-H>>(называется в обоих случаях одинаково).
Z-H>>Если в WINDOWS x32 запустить программу и положить библиотеку для x32 рядом
Z-H>>с exe-файлом — программа работает.
Z-H>>Если в WINDOWS x64 запустить программу и положить библиотеку для x64 рядом
Z-H>>с exe-файлом — программа тоже работает.
Z-H>>Можно ли сделать так, чтобы программа в зависимости от разрядности системы
Z-H>>брала библиотеку не рядом с Exe — файлом, а скажем из поддиректории /X86
Z-H>>(или /X64)?

P_A>Конечно можно:


P_A>
P_A> AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);

P_A>private Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
P_A>{
P_A>  // тут суем нужную dll в зависимости от разрядности OS
P_A>}
P_A>


суем нужную dll —
насколько я понимаю, это с помощью LoadFrom(......) и использования interfaces?
Спасибо, буду разбираться.
Просто наивно надеялся на существование более простого пути.
Re[4]: динамический выбор библиотек
От: Z-H  
Дата: 01.10.10 14:11
Оценка:
Здравствуйте, Sinix, Вы писали:

S>Здравствуйте, Z-H, Вы писали:


Z-H>>Забыл сказать, что программа задумывалась как PORTABLE. Т.е. она будет запускаться с одного носителя на разных по разрядности операционках.

S>Тогда build target в x86.

Имеется в виду в свойствах проекта вкладка "Build" — пункт "Platform target"?
Но тогда программа просто не будет работать в x64...
Или имелось в виду что-то совсем другое?
Re[5]: динамический выбор библиотек
От: LF  
Дата: 01.10.10 14:13
Оценка: 2 (1) +1
Z-H>Но тогда программа просто не будет работать в x64...
будет
Re[6]: динамический выбор библиотек
От: Z-H  
Дата: 01.10.10 18:57
Оценка:
Здравствуйте, LF, Вы писали:

Z-H>>Но тогда программа просто не будет работать в x64...

LF>будет
Да, действительно, проверил — работает. Причем библиотека X64 не нужна. Приложение в этом случае, как я понимаю, работает в режиме x32 (находясь в ОС x64). Но в данном случае этого вполне достаточно. Всем ответившим — огромное спасибо
Re[3]: динамический выбор библиотек
От: Pavel_Agurov Россия  
Дата: 01.10.10 19:37
Оценка:
P_A>>
P_A>> AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);

P_A>>private Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
P_A>>{
P_A>>  // тут суем нужную dll в зависимости от разрядности OS
P_A>>}
P_A>>


Z-H>суем нужную dll -

Z-H>насколько я понимаю, это с помощью LoadFrom(......) и использования interfaces?
Z-H>Спасибо, буду разбираться.
Z-H>Просто наивно надеялся на существование более простого пути.

Кто такие interfaces не знаю, но что может быть еще проще?


    private static Assembly currentDomain_AssemblyResolve(
                         object sender, ResolveEventArgs args)
    {
      if (args.Name.IndexOf("ClassLibrary2") >= 0) 
      {
        return Assembly.LoadFrom(@"x64\ClassLibrary2.dll");
      }
      return null;
    }


Еще один вариант, не знаю насколько подходящий — записать в конфиг где искать сборки:

<configuration>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <probing privatePath="Plugins" />
    </assemblyBinding>
  </runtime>
</configuration>


Может если оба каталога и x32 и x64 записать, то оно попытавшить загрузить из одного, полезет в другой. А может и нет... Не проверял.
Re[4]: динамический выбор библиотек
От: Z-H  
Дата: 02.10.10 09:29
Оценка:
Здравствуйте, Pavel_Agurov, Вы писали:


P_A>>>
P_A>>> AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);

P_A>>>private Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
P_A>>>{
P_A>>>  // тут суем нужную dll в зависимости от разрядности OS
P_A>>>}
P_A>>>


Z-H>>суем нужную dll -

Z-H>>насколько я понимаю, это с помощью LoadFrom(......) и использования interfaces?
Z-H>>Спасибо, буду разбираться.
Z-H>>Просто наивно надеялся на существование более простого пути.

P_A>Кто такие interfaces не знаю, но что может быть еще проще?



P_A>
P_A>    private static Assembly currentDomain_AssemblyResolve(
P_A>                         object sender, ResolveEventArgs args)
P_A>    {
P_A>      if (args.Name.IndexOf("ClassLibrary2") >= 0) 
P_A>      {
P_A>        return Assembly.LoadFrom(@"x64\ClassLibrary2.dll");
P_A>      }
P_A>      return null;
P_A>    }
P_A>


Сама загрузка проблем не вызывает. У меня не получалось потом создавать объекты из классов загруженной библиотеки. Найденные примеры в интернете не помогли (например, http://www.rsdn.ru/forum/dotnet/702738.flat.2.aspx
Автор: DJazz
Дата: 01.07.04
) — ошибка приведения к типу интерфейса.
Re[5]: динамический выбор библиотек
От: Pavel_Agurov Россия  
Дата: 02.10.10 11:32
Оценка: 2 (1)
P_A>>
P_A>>    private static Assembly currentDomain_AssemblyResolve(
P_A>>                         object sender, ResolveEventArgs args)
P_A>>    {
P_A>>      if (args.Name.IndexOf("ClassLibrary2") >= 0) 
P_A>>      {
P_A>>        return Assembly.LoadFrom(@"x64\ClassLibrary2.dll");
P_A>>      }
P_A>>      return null;
P_A>>    }
P_A>>


Z-H>Сама загрузка проблем не вызывает. У меня не получалось потом создавать объекты из классов загруженной библиотеки. Найденные примеры в интернете не помогли (например, http://www.rsdn.ru/forum/dotnet/702738.flat.2.aspx
Автор: DJazz
Дата: 01.07.04
) — ошибка приведения к типу интерфейса.


Вам и не надо ничего создавать. Подключите нужную библиотеку через reference и пишите код как обычно, без всяких рефлекшен и других сложностей. Совершенно ничего не надо менять, только добавить обработчик resolve. А уже в готовой поставке переложите dll в нужные каталоги. Обработчик вызывается, когда dll не будет найдена в обычных путях поиска. Тут-то вы и подсунете ее из каталога. И все. Никаких reflection, динамических созданий типов и т.д. вам не надо.
Re[6]: динамический выбор библиотек
От: Z-H  
Дата: 02.10.10 18:45
Оценка:
Здравствуйте, Pavel_Agurov, Вы писали:

P_A>>>
P_A>>>    private static Assembly currentDomain_AssemblyResolve(
P_A>>>                         object sender, ResolveEventArgs args)
P_A>>>    {
P_A>>>      if (args.Name.IndexOf("ClassLibrary2") >= 0) 
P_A>>>      {
P_A>>>        return Assembly.LoadFrom(@"x64\ClassLibrary2.dll");
P_A>>>      }
P_A>>>      return null;
P_A>>>    }
P_A>>>


Z-H>>Сама загрузка проблем не вызывает. У меня не получалось потом создавать объекты из классов загруженной библиотеки. Найденные примеры в интернете не помогли (например, http://www.rsdn.ru/forum/dotnet/702738.flat.2.aspx
Автор: DJazz
Дата: 01.07.04
) — ошибка приведения к типу интерфейса.


P_A>Вам и не надо ничего создавать. Подключите нужную библиотеку через reference и пишите код как обычно, без всяких рефлекшен и других сложностей. Совершенно ничего не надо менять, только добавить обработчик resolve. А уже в готовой поставке переложите dll в нужные каталоги. Обработчик вызывается, когда dll не будет найдена в обычных путях поиска. Тут-то вы и подсунете ее из каталога. И все. Никаких reflection, динамических созданий типов и т.д. вам не надо.


Это интересный вариант. Надо будет попробовать. Спасибо огромное.
Re[4]: динамический выбор библиотек
От: Lloyd Россия  
Дата: 02.10.10 19:05
Оценка: +1 :)
Здравствуйте, Sinix, Вы писали:

Z-H>>Забыл сказать, что программа задумывалась как PORTABLE. Т.е. она будет запускаться с одного носителя на разных по разрядности операционках.

S>Тогда build target в x86.

Плохое решение, даже скорее workaround, а не решение.
Вместо того, чтобы решить изначальную локальную проблему (выбор сборки), ты фактически предлагаешь отказаться всему предложению от преимуществ x64-платформы.
Re[5]: динамический выбор библиотек
От: Sinix  
Дата: 03.10.10 03:51
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>Плохое решение, даже скорее workaround, а не решение.


Ну да, я с ними заодно

*Кстати, в документации никаких оговорок про AssemblyResolve нет. Assembly.LoadFrom даже внутри AssemblyResolve загружает библиотеки в load-from context. Пруф:

The handler must load the assembly into the load-from context, into the load context, or without context...


Нафиг-нафиг, столько проблем с этим отхватывал...

If an assembly is loaded with LoadFrom, and the probing path includes an assembly with the same identity but a different location, an InvalidCastException, MissingMethodException, or other unexpected behavior can occur.

Re[7]: динамический выбор библиотек
От: Pavel_Agurov Россия  
Дата: 03.10.10 06:42
Оценка:
Z-H>Это интересный вариант. Надо будет попробовать. Спасибо огромное.

Тоже самое можно сделать засунув нужные dll в ресурсы. Мне так больше нравится — в результате получается один exe, без всяких каталогов. Делается точно также, только LoadLibrary читает не из файла, а из byte[], взятого из ресурсов.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.