IBProvider, Registration Free COM и AnyCPU.
Привет всем.
В дистрибутив .NET провайдера добавлен пример #23, в котором продемонстрирована работа с IBProvider-ом без регистрации в системе из .NET приложения, откомпилированного для AnyCPU платформы.
Общие положения.
1. Нужно модифицировать 32-битную и 64-битную сборки IBProvider-a. Они должны обрабатывать разные CLSID-ы.
Для этого нужно модифицировать ресурс PROG_REG_PARAMS.
Данные для 32-битного бинарника:
provider_file_ext =ibp; provider_clsid ={638BA021-35CB-43AE-83EF-D1907793E9A8}; error_service_clsid ={CE3D5A70-C784-4862-8FB4-3B554CBAC350}; data_link_page_clsid ={52D99D84-7A2F-4B5A-98BE-C2BA7D8334E1}; adv_data_link_page_clsid ={EBEC27FE-12E6-4DA9-B4EA-BCA8DEE196F5}; provider_prog_id ="LCPI.IBProvider.3.32bit.Private"; provider_prog_id_no_ver ="LCPI.IBProvider.32bit.Private"; provider_descr ="LCPI OLE DB Provider for InterBase [v3] [32bit] [Private]"; error_service_descr ="LCPI.IBProvider Error Lookup [v3] [32bit] [Private]"; data_link_page_descr ="LCPI.IBProvider Data Link Page [v3] [32bit] [Private]"; adv_data_link_page_descr ="LCPI.IBProvider Advanced Data Link Page [v3] [32bit] [Private]";
Данные для 64-битного бинарника:
provider_file_ext =ibp; provider_clsid ={B770F2BC-BEDC-4B88-8315-7F1E11B5F536}; error_service_clsid ={434FC88D-B928-4F19-A0EA-F282EEFEBD52}; data_link_page_clsid ={07793F79-8AF2-4EDA-B753-999BD19AC5CA}; adv_data_link_page_clsid ={EA135F17-A1E5-408E-9B7C-2B6B9F55DDA4}; provider_prog_id ="LCPI.IBProvider.3.64bit.Private"; provider_prog_id_no_ver ="LCPI.IBProvider.64bit.Private"; provider_descr ="LCPI OLE DB Provider for InterBase [v3] [64bit] [Private]"; error_service_descr ="LCPI.IBProvider Error Lookup [v3] [64bit] [Private]"; data_link_page_descr ="LCPI.IBProvider Data Link Page [v3] [64bit] [Private]"; adv_data_link_page_descr ="LCPI.IBProvider Advanced Data Link Page [v3] [64bit] [Private]";
Для модификации можно воспользоваться утилитой командной строки _Win32ResUpdater.exe из дистрибутива 32-битного IBProvider-a. В 64-битном провайдере лежит 64-битная версия этой утилиты — _Win32ResUpdater_w64.exe
Команда для модификации 32-битного провайдера будет выглядеть вот так:
_Win32ResUpdater.exe -write -file IBProvider.32bit.txt -module _IBProvider_v3_32bit_private.dll -id 1 -lang 1033 -type PROG_REG_PARAMS
64-битный провайдер, модифицируется аналогичным образом:
_Win32ResUpdater.exe -write -file IBProvider.64bit.txt -module _IBProvider_v3_64bit_private.dll -id 1 -lang 1033 -type PROG_REG_PARAMS
Утилита может еще выгружать/удалять/добавлять ресурсы из исполняемых модулей. Справка параметров командной строки прилагается.
2. Модифицированные DLL-и провайдера имеет смысл положить в подкаталоги исполняемого файла, который и будет использовать провайдер. В примере предлагается положить эти файлы в подкаталоги «private\32bit» и «private\64bit».
В эти же каталоги можно закинуть DLL-и Visual Studio CRT: msvcp120.dll и msvcr120.dll. Естественно, правильной разрядности.
3. Нужно модифицировать манифест исполняемого файла. В него добавляются такие элементы:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> <file name = "private\64bit\_IBProvider_v3_64bit_private.dll"> <comClass progid="LCPI.IBProvider.3.64bit.Private" clsid="{B770F2BC-BEDC-4B88-8315-7F1E11B5F536}" threadingModel = "Both" /> </file> <file name = "private\32bit\_IBProvider_v3_32bit_private.dll"> <comClass progid="LCPI.IBProvider.3.32bit.Private" clsid="{638BA021-35CB-43AE-83EF-D1907793E9A8}" threadingModel = "Both" /> </file> </assembly>
Для модификации следует воспользоваться утилитой из Windows SDK — mt.exe. Командная строка выглядит так:
mt.exe -updateresource:<путь к исполняемому файлу>;#1 -manifest ibprovider.manifest
Здесь ibprovider.manifest — это файл с вышеуказанными дополнительными данными для манифеста.
Отмечу, что операция модификации манифеста выполняется автоматически в процессе компиляции примера.
4. Собственно сам код работы с провайдером, в котором ключевым элементом является выбор идентификатора (ProgID) IBProvider-a в зависимости от разрядности процесса:
using System; using lcpi.data.oledb; namespace Sample_0023{ //////////////////////////////////////////////////////////////////////////////// //class Program class Program { private const string c_cn_str ="location=localhost:d:\\database\\employee.fdb;" +"user id=gamer;" +"password=vermut;"; //----------------------------------------------------------------------- static int Main() { int resultCode=0; try { var cnsb=new OleDbConnectionStringBuilder(c_cn_str); switch(IntPtr.Size) { case 4: cnsb.Provider="LCPI.IBProvider.3.32bit.Private"; break; case 8: cnsb.Provider="LCPI.IBProvider.3.64bit.Private"; break; default: throw new ApplicationException("Unexpected platform!"); }//switch using(var cn=new OleDbConnection(cnsb.ConnectionString)) { Console.WriteLine("Try to connect ..."); cn.Open(); Console.WriteLine("OK!"); var t=cn.GetSchema(OleDbMetaDataCollectionNames.DataSourceInformation); Console.WriteLine ("provider: {0}", t.Rows[0][OleDbMetaDataCollectionColumnNames .DataSourceInformation .LCPI_OleDbProviderFriendlyName]); }//using cn } catch(Exception exc) { resultCode=1; Console.WriteLine("ERROR: {0} - {1}",exc.Source,exc.Message); }//catch return resultCode; }//Main }//class Program //////////////////////////////////////////////////////////////////////////////// }//namespace Sample_0023