Админ

среда, 22 октября 2025 г.

Полуавтоматическое обновление клиента и сервера СУБД Firebird на Windows

|

Однажды у меня возникла задача: нужно было обновить файлы СУБД Firebird на нескольких сотнях клиентских машин (клиентскую часть) и дюжине компьютеров разработчиков (где установлены и клиент, и локальный сервер). При этом в процессе установки следовало отметить определённые нестандартные опции, но чтобы пользователю не было нужды выбирать их вручную.

Для этого пришлось разработать отдельное решение, потому что по каким-то причинам разработчики Firebird не предусмотрели официального способа обновления установленной СУБД в автоматическом режиме (или я просто не нашёл этого способа). Непродвинутому (да и продвинутому, в общем, тоже) пользователю неудобно вручную удалять ранее установленную СУБД, скачивать инсталлятор, запускать его и выбирать нужные опции галочками или пунктами выпадающего списка.

Оглавление

Что это такое?

Простой скрипт на языке Nullsoft Scriptable Installation System (NSIS), предназначенный для автоматизированного обновления (установки, переустановки) клиента или сервера СУБД Firebird под Windows. Мне хотелось, чтобы пользователь мог скачать единственный exe-файл, запустить его (вернее, нашему пользователю вообще делать ничего не надо, всё автоматически скачивает и запускает менеджер обновлений), а это файл уже сам:

  • проверил наличие установленной версии Firebird,
  • удалил её, если нужно,
  • распаковал инсталлятор в папку для временных файлов,
  • запустил его, отметив нужные опции,
  • подождал завершения работы
  • и, наконец, удалил временные файлы.
Для создания такой программы я использовал NSIS, потому что это мой привычный инструмент, которым я давно пользуюсь. Попутно я сделал так, чтобы программа не только обновляла Firebird, но и устанавливала его, если он не был установлен ранее.

Исходник лежит здесь: https://github.com/MichaelDemidov/Firebird-Auto-Updater (там есть файл readme, но он просто является почти дословным переводом данной статьи на английский). Если вы хорошо знаете язык NSIS, то можете вносить какие угодно изменения в скрипт: например, вместо вариантов для клиента и сервера можно сделать ассортимент каких-то своих, см. примечания в самом конце статьи.

Важные замечания

  1. Для сборки скрипта требуется инсталлятор Firebird (например, с официального сайта). В процессе сборки он упаковывается внутрь итогового файла (при запуске распаковывается во временную папку), так что на выходе его не будет видно.
  2. Для запуска полученной программы на компьютере нужны права администратора, потому что она устанавливает СУБД на компьютер. В момент запуска пользователю выдаётся диалоговое окно с подтверждением запуска от имени администратора или запрашивается пароль администратора.

С февраля 2024 по октябрь 2025 года программа была протестирована на более чем 250 компьютерах под управлением Windows 7, 8, 10 и 11. За исключением нескольких предупреждений антивируса и сообщений от фильтра SmartScreen (детали см. ниже), проблем не замечено.

Как пользователь запускает программу?

Для начала установки или обновления, пользователь должен запустить исполнимый файл Firebird_update_X_X_X.exe. Также при запуске можно указать пару параметров командной строки:

  1. Firebird_update_X_X_X.exe без параметров проверяет текущую установленную версию Firebird и, если она меньше, чем указанная в скрипте, удаляет Firebird с компьютера и устанавливает новую версию. При этом будет установлен только клиент, без компонентов сервера.
  2. Firebird_update_X_X_X.exe /server делает всё то же, но устанавливает серверные компоненты.
  3. Firebird_update_X_X_X.exe /force пропускает проверку установленной версии Firebird, сразу сносит текущую и ставит новую.

Разумеется, можно комбинировать параметры /server и /force в любом порядке.

Совет

Для запуска программы с параметрами от имени администратора: нажмите комбинацию клавиш Win + R, чтобы открыть диалог «Выполнить», введите в нём команду cmd и нажмите Ctrl + Shift + Enter. Если вы иcпользуете какой-нибудь панельный файловый менеджер (FAR Manager или Total Commander), вы можете запустить этот файловый менеджер с правами администратора и ввести нужные команды в его командной строке. Но прежде прочтите параграф про ложные срабатывания антивируса в конце этой статьи.

Важные замечания

  1. Если вы обновляете сервер Firebird, не забудьте сначала сделать резервные копии всех баз данных, расположенных на этом компьютере. После обновления восстановите их, чтобы у них была новая структура файла (ODS).
  2. В частности, если вы используете Interbase Expert, который хранит свои настройки в пользовательской БД (IBExpert User Database), и при этом в его настройках указано использовать для доступа к этой базе стандартную клиентскую библиотеку Firebird (т. е. не встроенный сервер, который является частью поставки Interbase Expert).

Как скомпилировать скрипт

Разместите файл официального инсталлятора Firebird в той же папке, что и скрипт, задайте значения констант, в частности, FB_VERSION and INSTALLER (см. подробности ниже), и скомпилируйте скрипт при помощи компилятора NSIS.

Исходный код

Требования

Для работы нужен компилятор NSIS версии 3.08 или новее. Скрипт использует расширения WordFunc и FileFunc, которые включены в стандартную поставку NSIS, поэтому ничего устанавливать больше не нужно.

Алгоритм

Текст скрипта начинается с объявления некоторых констант. Я перечислю их ниже.

  1. Скрипт ищет установленный на компьютере клиент Firebird. Для этого он обращается к системному реестру за ссылкой на папку, в которую устанавливается СУБД Firebird (например, C:\Program Files\Firebird\Firebird_3_0). Если папка не найдена, то Firebird, вероятнее всего, не установлен (или установлен некорректно) — программа пропускает шаги 2–4 и сразу переходит к шагу 5.
  2. Если пользователь указал ключ командной строки /force, пропустить шаги 3 и 4, перейти к шагу 5.
  3. Если скрипт содержит константу CHECK_GDS32 (см. ниже), он проверяет наличие файла gds32.dll в папке Windows\System32 или Windows\SysWOW64. Если такого файла нет, переходит к шагу 5.
  4. Скрипт содержит номер устанавливаемой версии Firebird в формате N.N., N.N.N и т. д. При запуске программа пытается извлечь номер уже установленной версии Firebird из динамической библиотеки fbclient.dll в папке установки Firebird (найденной на шаге 1). В случае неудачи при получении этой версии происходит установка Firebird (шаг 6). Если же версия в скрипте больше, чем уже установленная, то программа должна удалить установленную СУБД перед установкой новой (переход к шагу 5). Наконец, если номер версии в скрипте меньше или равен уже установленной, то больше ничего делать не надо (выйти из программы).
  5. Программа запускает деинсталлятор Firebird, который расположен в ранее (на шаге 1) найденной папке Firebird и ждёт завершения его работы. После завершения деинсталляции он удаляет папку Firebird со всем содержимым, потому что официальный деинсталлятор оставляет временные файлы в этой папке (при этом может возникнуть ошибка, см. ниже параграф про антивирусы!).
  6. Наконец, программа запускает установку Firebird и ждёт её завершения.

Важное замечание

Иногда после установки новой версии Firebird, система предлагает перезагрузить компьютер (насколько я понимаю, это связано с тем, что в момент обновления клиентская DLL используется каким-то процессом). Это сообщение генерируется самим инсталлятором Firebird, а не программой обновления; пользователь может его проигнорировать, но это может привести к проблемам в работе Firebird.

Замечание

Может случиться так, что ранее установленная СУБД Firebird имела другую разрядность (32 или 64 бита), нежели устанавливаемая. Если бы на шаге 1 выше проверялась ветка регистра HKLM, то в такой ситуации предыдущая версия не была бы найдена и удалена. Поэтому скрипт проверяет отдельно ветки HKLM32 и HKLM64.

Константы

Приведу просто в виде локализованного фрагмента скрипта с комментариями, тут всё должно быть понятно:
; --- локализация ---

; наименование для отображения
!define INST_NAME "Firebird"

; язык интерфейса, например, для отображения шкалы или сообщений
; о перезапуске компьютера (имя файла локали, см. здесь:
; ${NSISDIR}\Contrib\Language files\*.nsh)
!define LANGUAGE "Russian"

; предупреждение об админских правах (если пользователь запустил
; программу без них)
!define ADMIN_WARNING "Требуются права администратора!"

; --- настройка Firebird ---

; номер версии для установки
!define FB_VERSION "3.0.11"

; проверять ли наличие файла gds32.dll в папке System?
!define CHECK_GDS32 "yes"

; имя exe-файла (+ относительный путь, если надо)
!define INSTALLER "Firebird-3.0.11.33703_0_Win32.exe"

; имя файла деинсталлятора
!define UNINSTALLER "unins000.exe"

; настройки для установки клиента Firebird:
; * LANG = аббревиатура языка
; * DIR = каталог установки. Если не указан, берётся по умолчанию Program
;   Files. Здесь $1 -- предопределённая константа, которая будет заменена на
;   абсолютный путь к РОДИТЕЛЬСКОЙ папке предыдущей установки Firebird (если
;   она есть) или на путь по умолчанию Program Files\Firebird (если её нет)
; * GROUP = имя папки для главного меню Windows (вместо этого можно
;   использовать ключ /NOICONS, тогда никакой папки не будет, см. ниже)
; * TYPE = тип установки (клиент или сервер, см. примеры ниже)
; * COMPONENTS = компоненты для установки
; * TASKS = дополнительные задачи, например: создать gds32.dll для поддержки
;   унаследованных приложений и скопировать его в папку Windows\System32 (или
;   Windows\SysWOW64)
; * SILENT = запустить установку в "тихом" режиме, т.е. без взаимодействия
;   с пользователем. Без этой настройки теряется смысл всех прочих
!define CLIENT_INST_OPTIONS '/LANG=ru /DIR="$1\Firebird_3_0" /GROUP="Firebird \
3.0 (Win32)" /TYPE=clientinstall /COMPONENTS=clientcomponent \
/TASKS=copyfbclienttosystask,copyfbclientasgds32task /SILENT'

; настройки для установки сервера Firebird (смысл всех настроек идентичен
; клиентским, см. выше)
!define SERVER_INST_OPTIONS '/LANG=ru /DIR="$1\Firebird_3_0" /GROUP="Firebird \
3.0 (Win32)" /TYPE=serverinstall /COMPONENTS=servercomponent,devadmincomponent,\
clientcomponent /TASKS=usesuperservertask,useservicetask,autostarttask,\
copyfbclienttosystask,copyfbclientasgds32task,enablelegacyclientauth /SILENT'

; настройки деинсталлятора: здесь мы запускаем его в "тихом" режиме, чтобы он не
; требовал взаимодействия с пользователем
!define UNINST_OPTIONS "/SILENT"
  

Как получить значения констант ..._INST_OPTIONS?

Разумеется, взять откуда-то из головы устрашающую конструкцию вида TASKS=copyfbclienttosystask,copyfbclientasgds32task и прочее из примеров выше невозможно, потому что все эти ключевые слова «вшиты» в инсталлятор Firebird и нигде никак не документированы (или, опять же, я не смог найти документацию). Чтобы получить список допустимых значений этих настроек, можно прибегнуть к такому приёму.

Сначала нужно удалить Firebird, если он установлен (если нельзя или страшно экспериментировать на рабочем компьютере, то нужно или найти другой, или использовать виртуальную машину).

Затем запустить официальный инсталлятор Firebird с параметром командной строки /SAVEINF=fb_client.inf, например:

Firebird-3.0.11.33703_0_Win32.exe /SAVEINF=fb_client.inf

В процессе установки Firebird следует установить все галочки и пункты списков именно таким образом, каким они должны быть установлены потом у пользователей.

В результате этих действий в папке с инсталлятором будет сгенерирован текстовый файл с указанным именем (в нашем примере это fb_client.inf), содержимое которого имеет примерно такой вид:

[Setup]
Lang=ru
Dir=C:\Program Files (x86)\Firebird\Firebird_3_0
Group=Firebird 3.0 (Win32)
NoIcons=0
SetupType=clientinstall
Components=clientcomponent
Tasks=copyfbclienttosystask,copyfbclientasgds32task

Список ключевых слов и значений для константы CLIENT_INST_OPTIONS можно получить из этого файла. Но напрямую взять их отсюда нельзя, сначала нужно поменять некоторые вещи:

  • значения ключей Dir и Group заключить в двойные кавычки,
  • добавить косую черту (slash) в начало каждой строки, а знак равенства после имени ключа заменить на пробел,
  • конвертировать имена ключей в верхний регистр. Не уверен, что это 100% необходимо, но в ранее виденных примерах было именно так, да и читать полученную строку так легче,
  • переименовать SETUPTYPE в TYPE,
  • заменить строку /DIR "..." на /DIR "$1\Firebird_...", где имя папки (Firebird_...) зависит от мажорной версии Firebird (в примере это 3),
  • удалить строку, которая начинается с /NOICONS, если в главном меню Windows нужна папка Firebird. А если папка не нужна, то оставить (добавить) /NOICONS, но убрать значение (0 или что там было), тогда папка в главном меню не появится, и ключ /GROUP тоже станет не нужен,
  • наконец, добавить в конец списка опций строку /SILENT.

В итоге должно получиться так:

/LANG ru
/DIR "C:\Program Files (x86)\Firebird\Firebird_3_0"
/GROUP "Firebird 3.0 (Win32)"
/TYPE clientinstall
/COMPONENTS clientcomponent
/TASKS copyfbclienttosystask,copyfbclientasgds32task
/SILENT

Осталось собрать это всё в одну строку, заменив переводы строк пробелами, и можно записать получившуюся строку в константу CLIENT_INST_OPTIONS.

Таким же образом формируется значение константы SERVER_INST_OPTIONS: снова удалить Firebird, установить со всеми нужными опциями и т. д.

Известные проблемы и идеи для совершенствования

Антивирусы и SmartScreen

Некоторые антивирусы (в частности, дефолтный Microsoft Defender) иногда ошибочно помечают Firebird_update_X_X_X.exe как троян — возможно, из-за того, что он требует административных привилегий для запуска другой программы (инсталлятора Firebird), которая вносит изменения в операционную систему. К сожалению, я не знаю пока, как избавиться от этого совсем, но есть пара соображений.

Во-первых, исследования показывают, что проблема с Microsoft Defender иногда появляется, если пользователь запускает командный интерпретатор cmd с правами администратора и затем запускает инсталлятор из него.

Во-вторых, по неясным причинам Microsoft Defender иногда не любит команду удаления папки RmDir /r $0 (в скрипте она расположена после метки uninstall:). В случае появления такой ошибки можно попробовать закомментировать или убрать эту строку, хотя это приведёт к тому, что пустая папка удаляться не будет.

Наконец, даже если с антивирусом всё было в порядке, заблокировать запуск приложения может функция Windows SmartScreen. Тут ничего не поделаешь: если планируется распространять инсталлятор среди пользователей посредством скачивания с какого-то централизованного сервера или пересылки его через интернет, то нужно предупредить людей, чтобы они нажимали нужные кнопки, разрешающие запуск программы.

Учётные записи пользователей СУБД

Этот пункт касается только тех, кто переустанавливает сервер Firebird.

Поскольку скрипт полностью удаляет предыдущую версию Firebird, после установки новой версии нужно обязательно поменять пароль суперадминистратора SYSDBA (разумеется, если вы не оставили пароль по умолчанию masterkey) и, возможно, заново создать учётные записи остальным пользователям (если они существовали).

Если у вас есть какие-нибудь соображения о том, как этого избежать, дайте знать, пожалуйста. Может быть, можно сделать бэкап и восстановление системной базы данных.

Автоматическое распознавание клиента и сервера СУБД

На данный момент я не придумал способа определить, что именно было установлено ранее: клиент или сервер. Было бы неплохо автоматически распознавать это и выбирать нужный тип установки безо всяких ключей командной строки.

С другой стороны, я не очень активно изучал этот вопрос, потому что в моём конкретном случае серверная часть Firebird устанавливается гораздо реже, чем клиентская.

И есть ещё одна сложность, которая заключается в том, что сервер Firebird может быть установлен и запущен как приложение или как служба Windows. То есть нужно распознавать не только тип установки, но и способ запуска сервера. Всё это очень усложнило бы нехитрый скрипт.

Автоматическое определение разрядности

Было бы очень здорово, если бы можно было автоматически определить разрядность ранее установленной версии клиента (32 или 64 бита) и иметь возможность обновлять его с учётом этой разрядности. Конечно, это привело бы к примерно двукратному увеличению размера исполнимого файла, но зато он стал бы более универсальным. Сейчас устанавливается только одна версия — та, которую вы включите в инсталлятор.

Комментариев нет:

Отправить комментарий

Пожалуйста, не используйте в сообщениях ненормативную лексику и нарушающие закон темы

К началу