Помогите, плиз!!!
Есть программа на С#, которая использует библиотеку System.Data.SQLite.dll.
Библиотека System.Data.SQLite.dll существует для x86 и существует для x64
(называется в обоих случаях одинаково).
Если в WINDOWS x32 запустить программу и положить библиотеку для x32 рядом
с exe-файлом — программа работает.
Если в WINDOWS x64 запустить программу и положить библиотеку для x64 рядом
с exe-файлом — программа тоже работает.
Можно ли сделать так, чтобы программа в зависимости от разрядности системы
брала библиотеку не рядом с Exe — файлом, а скажем из поддиректории /X86
(или /X64)?
Здравствуйте, Z-H, Вы писали:
Z-H>Можно ли сделать так, чтобы программа в зависимости от разрядности системы Z-H>брала библиотеку не рядом с Exe — файлом, а скажем из поддиректории /X86 Z-H>(или /X64)?
Обычно этого не нужно: разрядность системы время от времени не меняется и положить рядом с одной сборкой другую, подходящюю первой в данном окружении — задача инсталятора.
Help will always be given at Hogwarts to those who ask for it.
Здравствуйте, _FRED_, Вы писали:
_FR>Здравствуйте, Z-H, Вы писали:
Z-H>>Можно ли сделать так, чтобы программа в зависимости от разрядности системы Z-H>>брала библиотеку не рядом с Exe — файлом, а скажем из поддиректории /X86 Z-H>>(или /X64)?
_FR>Обычно этого не нужно: разрядность системы время от времени не меняется и положить рядом с одной сборкой другую, подходящюю первой в данном окружении — задача инсталятора.
Забыл сказать, что программа задумывалась как PORTABLE. Т.е. она будет запускаться с одного носителя на разных по разрядности операционках.
Здравствуйте, Z-H, Вы писали:
Z-H>Забыл сказать, что программа задумывалась как PORTABLE. Т.е. она будет запускаться с одного носителя на разных по разрядности операционках.
Тогда build target в x86.
Здравствуйте, 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 и брал бы оттуда в зависимости от разрядности операционки. Тогда и "класть рядом" ничего не надо будет.
Здравствуйте, 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?
Спасибо, буду разбираться.
Просто наивно надеялся на существование более простого пути.
Здравствуйте, Sinix, Вы писали:
S>Здравствуйте, Z-H, Вы писали:
Z-H>>Забыл сказать, что программа задумывалась как PORTABLE. Т.е. она будет запускаться с одного носителя на разных по разрядности операционках. S>Тогда build target в x86.
Имеется в виду в свойствах проекта вкладка "Build" — пункт "Platform target"?
Но тогда программа просто не будет работать в x64...
Или имелось в виду что-то совсем другое?
Здравствуйте, LF, Вы писали:
Z-H>>Но тогда программа просто не будет работать в x64... LF>будет
Да, действительно, проверил — работает. Причем библиотека X64 не нужна. Приложение в этом случае, как я понимаю, работает в режиме x32 (находясь в ОС x64). Но в данном случае этого вполне достаточно. Всем ответившим — огромное спасибо
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 не знаю, но что может быть еще проще?
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 не знаю, но что может быть еще проще?
Сама загрузка проблем не вызывает. У меня не получалось потом создавать объекты из классов загруженной библиотеки. Найденные примеры в интернете не помогли (например, http://www.rsdn.ru/forum/dotnet/702738.flat.2.aspx
Z-H>Сама загрузка проблем не вызывает. У меня не получалось потом создавать объекты из классов загруженной библиотеки. Найденные примеры в интернете не помогли (например, http://www.rsdn.ru/forum/dotnet/702738.flat.2.aspx
Вам и не надо ничего создавать. Подключите нужную библиотеку через reference и пишите код как обычно, без всяких рефлекшен и других сложностей. Совершенно ничего не надо менять, только добавить обработчик resolve. А уже в готовой поставке переложите dll в нужные каталоги. Обработчик вызывается, когда dll не будет найдена в обычных путях поиска. Тут-то вы и подсунете ее из каталога. И все. Никаких reflection, динамических созданий типов и т.д. вам не надо.
Z-H>>Сама загрузка проблем не вызывает. У меня не получалось потом создавать объекты из классов загруженной библиотеки. Найденные примеры в интернете не помогли (например, http://www.rsdn.ru/forum/dotnet/702738.flat.2.aspx
) — ошибка приведения к типу интерфейса.
P_A>Вам и не надо ничего создавать. Подключите нужную библиотеку через reference и пишите код как обычно, без всяких рефлекшен и других сложностей. Совершенно ничего не надо менять, только добавить обработчик resolve. А уже в готовой поставке переложите dll в нужные каталоги. Обработчик вызывается, когда dll не будет найдена в обычных путях поиска. Тут-то вы и подсунете ее из каталога. И все. Никаких reflection, динамических созданий типов и т.д. вам не надо.
Это интересный вариант. Надо будет попробовать. Спасибо огромное.
Здравствуйте, Sinix, Вы писали:
Z-H>>Забыл сказать, что программа задумывалась как PORTABLE. Т.е. она будет запускаться с одного носителя на разных по разрядности операционках. S>Тогда build target в x86.
Плохое решение, даже скорее workaround, а не решение.
Вместо того, чтобы решить изначальную локальную проблему (выбор сборки), ты фактически предлагаешь отказаться всему предложению от преимуществ x64-платформы.
*Кстати, в документации никаких оговорок про 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.
Z-H>Это интересный вариант. Надо будет попробовать. Спасибо огромное.
Тоже самое можно сделать засунув нужные dll в ресурсы. Мне так больше нравится — в результате получается один exe, без всяких каталогов. Делается точно также, только LoadLibrary читает не из файла, а из byte[], взятого из ресурсов.