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