Open sergey-s-betke opened 10 years ago
Из приятных новостей: приложение использует псевдоним BDE для подключения к базе данных, и этот псевдоним можно настроить! Мало того, и сам псевдоним можно изменить!
Естественно, псевдоним я предлагаю изменить. Использовать в качестве псевдонима $(var.ProductShortName)
. Пользователя и пароль будем задавать через свойства msi пакета.
Естественно, параметры соединения с базой данных будем записывать только в случае их отсутствия в файле, перезаписывать не будем.
Установка базы данных и настройка псевдонима должна осуществляться в одном компоненте (Feature
) пакета. Точнее - не так. Если базу данных устанавливаем, тогда параметры подключения настраиваем, в том числе - и псевдоним BDE настраиваем. Если же базу данных не устанавливаем, параметры подключения всё равно прописываем при их отсутствии, но псевдоним BDE уже не настраиваем.
В итоге ещё предстоит научиться регистрировать / настаивать псевдоним BDE при установке.
Об обеспечении "совместимости" BDE с Windows 7 следует почитать здесь: http://www.willneumann.net/2008/09/configuring-bde-for-windows7/.
О включении BDE в пакет и о регистрации Alias следует почитать здесь: http://www.slavssoft.ru/articles/?page=bde_p1
Итак, структура:
Файлы в формате .dbf
. Попробую использовать драйвер Microsoft DBase Driver.
С параметрами ещё предстоит разобраться - http://msdn.microsoft.com/en-us/library/ms710931.aspx:
DSN
- как я понимаю, можно указать ODBC источник. А его уже можно будет настроить и через .msi, и через GPO;DEFAULTDIR
- каталог, если не будем использовать предыдущий параметр;DESCRIPTION
- и так ясно.В результате работы мастера настройки BDE получил ini файл BDEmerge.ini
:
[Drivers]
Driver0=Microsoft dBase Driver (*.dbf)
[NevaTest3303P]
Driver=Microsoft dBase Driver (*.dbf)
Params=DSN:NevaTest3303P;DESCRIPTION:База данных результатов поверок НеваТест 3303П
С созданием псевдонима на этапе установке средствами BDE.msm есть некоторое неудобство: в оригинале подразумевается размещение ini файла BDEmerge.ini
рядом с .msi файлом. Что неудобно. Следует внимательнее изучить BDE.msm и найти способ регистрации псевдонима BDE без дополнительных файлов.
Пока не вижу красивого решения для "избавления" от .ini файла. Кривое решение, а писать свою custom action не так уж просто будет. Можно ещё поискать COM интерфейсы для этого.
В общем, решения не нашёл. Придётся пока использовать BDEmerge.ini
.
Однако. Рядом с msi разместить файл недостаточно. Всё равно получаем диалоговое окно о невозможности слияния и необходимости использования для слияния конфигурации bdeadmin. Пробовал копировать и в c:\windows\installer, и в c:\windows\temp - не помогает.
Однако... Причина может быть в очередной раз в совсем "кривом" msm. Всё больше склоняюсь к идее переписать msm самостоятельно для BDE.
Проблема следующая: custom action в указанном msm определены как type 1. То есть они будут исполнены с правами пользователя, а не с повышенными правами системы! Естественно, прав на запись ни в idapi32.cfg, ни в реестр не будет, и - получим ошибку, что ожидаемо, блин.
Итак, к типу добавить нужно msidbCustomActionTypeFirstSequence
(256), и msidbCustomActionTypeInScript
+ msidbCustomActionTypeNoImpersonate
(3072).
Ещё одна проблема в том, что custom action BDEConfig
(то, что нам и надо, судя по всему) выполняется после InstallFinalize
. В таком варианте заставить перевести её в deferred
не выйдет, необходимо менять очерёдность её выполнения.
В общем, проблемы с "родным" BDE.msm налицо. Начиная непосредственно с BDEadmin, которая не является UAC совместимой, библиотеками, которым необходим доступ на запись в некоторые ветки реестра, кончая проблемами с дистрибутивом...
Попробую поискать сторонние библиотеки для реализации custom action для регистрации драйверов и псевдонимов BDE.
Хоть какой-то просвет: http://community.flexerasoftware.com/showthread.php?1464-New-InstallShield-user-asking-about-BDE-Alias-adding-to-existing-BDE-installation.
Стоит посмотреть в сторону IDAPINST.DLL
и конкретно функции int AddAlias( char *pszCfgFile, char *pszAliasName, char *pszDriverType, char *pszParams, int biDAPI16, char *sLang )
.
Похоже, решение от InstallShield IDAPINST.DLL
именно то, что нам надо. Да, оно не даст нам полноценных custom action с обработкой дополнительных таблиц, но всё-таки лучше, чем то, что мы имеем сейчас.
Кое-какие примеры: http://www.databaseteam.org/7-paradox/694fce20c3a1880d.htm.
Ещё информация: http://community.flexerasoftware.com/archive/index.php?t-31554.html, оттуда предложение использовать IDAPI32.DLL
и dbiAddAlias
оттуда для этих целей.
Пример кода:
AnsiString aliasParams = "SERVER NAME:" + Edit1->Text +"; USER NAME:" + Edit2->Text +";";
DbiAddAlias(NULL, Edit3->Text.c_str(), "INTRBASE", aliasParams.c_str(), TRUE);
Для начала следует попробовать создать только ODBC DSN, не создавая псевдонима BDE. А уж если не поможет - тогда IDAPI32.DLL
.
Но BDE.msm придётся в любом случае перепаковать...
Перепаковал BDE.msm
. Собрал ITG.BDE_PRO.msm
через отдельный wix проект.
Дополнительно целесообразно разобраться с назначением файлов в BDE, разделить их на компоненты / features, добавить параметры конфигурации для merge module с тем, чтобы обеспечить возможность включения в конечный пакет только действительно необходимых компонентов.
Да, кстати, в отличии от "оригинального" msm регистрирую ProgId Borland.Database_Engine.4
, который по какой-то причине не был установлен родным msm. Следует посмотреть, какие методы этот объект предоставляет, возможно - можно для регистрации псевдонимов воспользоваться его методами, тогда и дополнительные .dll не потребуются, достаточно будет jscript custom action!
Считаю, будет лучше убрать bdeadmin.cpl
, потому как данная утилита вносит неоднозначность: она не запрашивает UAC, но при этом и не может прочитать / сохранить конфигурацию, хотя считает, что ей это удалось. Принудительно придать ей запуск от имени администратора не смог, потому как запускается она через rundll32.exe
.
Наличие idapi32.cfg
следует проверять более тщательно: следует искать не файл в каталоге BDE, а файл, указанный в реестре. И перезаписывать / регистрировать его, если не найдены записи в реестре либо файл на диске.
Итак, что же делать с bdeadmin.cpl
? О запуске аплетов панели управления с повышенными правами информация есть, но не совсем та:
Достаточно подробное описание возможностей настройки панели управления через реестр: http://windxp.com.ru/reestr44.htm.
Описание возможностей использования rundll32.exe
, в том числе - и масса примеров вызовов аплетов панели управления - http://user.alexanderklimov.ru/tutorial/rundll32.php.
Однако - замечательная статья о регистрации .exe файлов в качестве аплета панели управления, начиная с Windows Vista: http://blogs.msdn.com/b/cjacks/archive/2007/05/03/registering-an-executable-file-exe-as-a-control-panel-applet-on-windows-vista-using-windows-installer-xml-wix.aspx?Redirected=true, официально - http://msdn.microsoft.com/en-us/library/windows/desktop/hh127450.aspx.
Следует попробовать. В этом случае процесс будет не control.exe и не rundll32.dll, и, возможно, удастся применить параметры совместимости и принудительно запустить этот "аплет" от имени администратора.
Итого - именно данным решением и воспользуемся:
Нашёл способ запуска аплета панели управления от имени администратора! - Необходимо использовать вместо глагола open
глагол runas
.
С панелью управления осталась последняя проблема: задачи (sh:task
) не вызывают аплет лишь потому, что регистрация прошла в 32-тном реестре, а необходима она для задач и в 64битном реестре. Глупо на первый взгляд, ну уж как есть.
Итак, с регистрацией BDE Administrator в панели управления все вопросы решены. Всё прекрасно запускается сразу с правами администратора.
Осталось:
idapi32.cfg
из реестра, если он там уже есть.Не нашёл я способа проверить наличие конкретного файла, указанного в реестре. Жаль.
Однако, в любом случае поискать путь к idapi32.cfg
в реестре стоит, и устанавливать свой файл следует только в случае отсутствия уже зарегистрированного там файла конфигурации.
Пытаюсь разобраться с объектом Borland.Database_Engine.4
(для целей регистрации псевдонимов). Однако, при попытке создания экземпляра получаю следующее:
$bde = New-Object -ComObject 'Borland.Database_Engine.4'
New-Object : Не удалось получить фабрику класса COM для компонента с CLSID {FB99D710-18B9-11D0-A4CF-00A024C91936} из-за следующей ошибки: 80040154 Класс не зарегистрирован (Исключение из HRESULT: 0x80040154 (REGDB_E_CLASSNOTREG)).
Видимо, чего-то я не доделал (несмотря на то, что и так прописал в реестр куда больше, чем оригинальный msm писал).
Опять забыл о Wow. Ведь класс то регистрирую я InprocServer32, поэтому и пробовать использовать его стоит только в 32битной редакции PoSh:
$bde = New-Object -ComObject 'Borland.Database_Engine.4'
New-Object : Не удалось получить фабрику класса COM для компонента с CLSID {FB99D710-18B9-11D0-A4CF-00A024C91936} из-за следующей ошибки: 800401f9 Ошибка в библиотеке DLL (Исключение из HRESULT: 0x800401F9 (CO_E_ERRORINDLL)).
Ошибка уже совсем другая. Куда теперь копать - отдельная песня.
Кстати - необходимо при установке увеличивать значение параметра:
[HKEY_LOCAL_MACHINE\Software\Borland\Database Engine]
"UseCount"
Иначе можем получить неприятный эффект - какое-нибудь приложение с не msi дистрибутивом BDE при удалении удалит BDE из-за того, что мы не увеличили счётчик и не показали таким образом, что BDE необходимо.
Действия следующие:
idapi.dll
(исключить необходимо восстановление) через RegSearch
читаем значение из реестра. Затем через custom action увеличиваем на единицу и пишем его в реестр. По умолчанию свойству даём значение 0
.Цитаты из реестра с установленным BDE: http://www.delphipraxis.net/1221396-post26.html
Наткнулся на проект, который как раз решает задачи автоматизации слияния конфигураций BDE: https://github.com/oboroc/bdecli.
Для вызова функций idapi32.dll
планирую использовать DynamicWrapper
activeX. Наиболее гибкий и компактный вариант на мой взгляд.
http://www.script-coding.com/dynwrapx.html - более предпочтительный вариант - аналог указанной выше библиотеки. На него перейдём. Сайт - http://yuripopov.ucoz.net/index/dynwrapx/0-11. Обсуждение - http://forum.script-coding.com/viewtopic.php?id=2216.
Итак, будем использовать DynamicWrapperX. Версию 2.0.0. Под неё, похоже, отдельный msm или как минимум wixlib целесообразно собрать...
Задачу с UseCount
решил на 3х jscript custom action.
Возвращаемся к регистрации псевдонимов и настройке параметров.
И для удаления "оригинальных" дистрибутивов, и для регистрации алиасов стоит придерживаться идеологии msi, а не плодить толпу custom actions. Речь идёт о создании специализированных таблиц для этих нужд.
Попробовать как раз можно на удалении инсталляторов...
Неплохой комментарий (интересен именно комментарий) по правильной подготовке custom action (http://stackoverflow.com/questions/128279/how-best-to-define-a-custom-action-in-wix). Рекомендовано изучить код IIS расширения к Wix. Он как раз использует дополнительные таблицы, его и изучим.
Возможно, имеет смысл сохранить скрипты для UseCount
в файлы, чтобы изменить тип custom action и контролировать код возврата.
Несколько отвлекаясь: будет правильным переделать custom action для UseCount
так, чтобы планировать только одно действие явно. А уже в его коде определять тип действия (установка или удаление), и планировать необходимые commit и rollback действия.
Вскрылись дополнительные проблемы с регистрацией BDE администратора в панели управления. Ярлык в AdminToolsFolder у нас advertised, поэтому при вызове через этот ярлык приложение запускается в LUA. Этот ярлык необходимо сделать обычным!
И ODBC администратор отнесён к группе Система и безопасность / Администрирование. Туда же следует отнести и BDE Administrator.
Итак, итоги кратко. Лучший вариант, безусловно, создать собственный WMI провайдер для BDE, и уже сценарием custom action через WMI регистрировать необходимые псевдонимы. Но интерфейсы WMI провайдера не IDispatch
, для их реализации придётся придётся создавать именно COM сервере. Использовать для этого скриплеты (.wsc, Windows Scripting Components) можно, но только после создания специального "адаптера", который подзволит заявить поддержку интерфейсов WMI провайдера.
Кроме того, для реализации через скриплеты потребуется всё равно использовать DynamicWrapperX для вызовов dll функций.
Поэтому для решения данной задачи всё решил использовать DynamicWrapperX. Для его установки целесообразно отдельный msm и wixlib собрать.
У DynWrapX есть одна зависимость от msvcrt.dll
.
DynamicWrapperX.dll
в проект добавил, теперь осталось написать сценарий с его использованием.
Проблема с параметрами совместимости при запуске bdeadmin из панели управления / администрирование решена - ключи необходимо регистрировать в x64 реестре.
hyyb.ini
содержит в том числе параметры подключения к базе данных:Ясны только первых три параметра. Их и будем рассматривать в данном контексте.