Найти тему

Решение для работы внешней компоненты в веб-браузере под Windows: CMake+NSIS

Небольшой цикл статей про внешние компоненты (ВК) для веб-браузеров. Цель – описать общий механизм взаимодействия платформы 1С и ВК в этом режиме, предложить как доработанное решение, основанное на примере от 1С, так и собственную разработку - внешнюю обработку 1С. Решение позволяет обеспечивать работу в веб-браузере для любой нативной библиотеки, разработанной на основе шаблона ВК от 1С и работающей в тонком клиенте. На вход решение получает наименование компании, продукта, номер версии и т.д. а также файл библиотеки, на выходе - zip-архив для загрузки в макет в 1С.

WinLinCMake_1_0_1_1.zip

Пример для внешних компонент от 1С описан в статье Технология создания внешних компонент и построен на использовании CMake в качестве системы сборки, NSIS и Makeself для установщика для режима веб-браузера, шаблона 1С для нативных и COM компонент. Пример максимально универсален, предназначен для создание ВК для всех режимов применения:  на сервере, в тонком клиенте,  в мобильном приложении, в веб-браузере, для разных ОС и архитектур. Пример поддерживает:

  1. Типы компонент: native и COM.
  2. Десктопные ОС: Windows 32/64, Linux 32/64, macOS для PC, Linux для ARM64 и E2K (Эльбрус 2000).
  3. Мобильные ОС: android и iOS.
  4. Веб-браузеры: Chrome, Chromium, Firefox, Internet Explorer, Safari.

В этом примере нет разбивки по режимам применения, нет разбивки на данные входа, «чёрного ящика» самого решения и данные результата. Подобный подход позволил бы обойтись минимальными знаниями о внутренней работе примера и сильно упростил бы реализацию работы в режиме веб-браузера уже существующих внешних компонент. Предлагаемое решение, реализующее этот подход для режима веб-браузера, планируется опубликовать в цикле из трёх статей:

  1. Решение для работы внешней компоненты в веб-браузере под Windows: CMake + NSIS (данная статья).

Решение, описываемое в 1-ой и 2-ой статьях, представляет собой переработку примера от 1С и состоит из архива, содержащего настройки для сборки проекта. Упор сделан на минимальное знание CMake, NSIS и Makeself. В 3-ей статье приводится внешняя обработка 1С, которая используется для сборки вместо CMake, вместо NSIS применяется собственная разработка Installer+Uninstaller. Решение предназначено для работы с ОС Windows и Linux на PC 32/64, для веб-браузеров Chrome, Chromium, Firefox. Таким образом, в данном решении поддерживаются далеко не все варианты из примера 1С.

Расширение веб-браузера

Расширение веб-браузера – программа на javascript + CSS + HTML + файл настроек manifest.json. Расширение может быть загружено из интернет магазинов (Chrome Web Store, addons.mozilla.org), а также из файлов на диске.

Расширение веб-браузера от 1С (Расширение для работы с 1С:Предприятием) загружается при первой попытке подключения внешней компоненты в открытой в веб-браузере конфигурации.

Собственное приложение расширения

Собственным приложением является исполняемый файл, использующий стандартный ввод (stdin) и стандартный вывод (stdout). Собственным приложением может быть консольное приложение, скрипт на питоне и т.д.

Расширение веб-браузера может обмениваться сообщениями с собственными приложениями. Веб-браузер запускает собственный хост обмена сообщениями в отдельном процессе и взаимодействует с ним, используя стандартный ввод (stdin) и стандартный вывод (stdout). Один и тот же формат используется для отправки сообщений в обоих направлениях; каждое сообщение сериализуется с использованием JSON в кодировке UTF-8, и ему предшествует 32-битная длина сообщения в собственном порядке байтов. Максимальный размер одного сообщения от узла обмена сообщениями составляет 1 МБ, максимальный размер сообщения, отправляемого на узел обмена сообщениями, составляет 4 ГБ.

Для того чтобы собственное приложение веб-расширения могло взаимодействовать с браузером, необходимо создать в реестре Windows ключи: HKEY_CURRENT_USER\SOFTWARE\Google\Chrome\NativeMessagingHosts\<имя приложения> для Chrome, HKEY_CURRENT_USER\SOFTWARE\Mozilla\NativeMessagingHosts\<имя приложения> для Firefox, HKEY_CURRENT_USER\SOFTWARE\Chromium\NativeMessagingHosts\<имя приложения> для Chromium. Значение по умолчанию ключа должно содержать ссылку на каталог, где размещаются файлы собственного приложения.

Структура собственного приложения расширения от 1С

Собственное приложение от 1С для Windows состоит из:

  1. Адаптер (exe).
  2. Нативная библиотека (dll).
  3. Файл настроек для браузера Chrome (json).
  4. Файл настроек для браузера Firefox (json).
  5. Деинсталятор (exe).

Эти файлы помещаются в установщик собственного приложения.

Адаптер – вспомогательная программа, принимающая/передающая сообщения от браузера и вызывающая соответствующий метод библиотеки. Таким образом, в качестве собственного приложения выступает связка адаптер + библиотека. Взаимодействие кода 1С и внешней компоненты можно представить так: код 1С -> javascript фреймворк 1С -> веб-расширение 1С -> веб-браузер -> адаптер собственного приложения (исполняемый файл, exe)-> нативная библиотека (dll). Та же цепочка работает и для передачи результата в обратную сторону.

Установщик собственного приложения представляет собой исполняемый файл (exe). В шаблоне используется программа NSIS, создающая самораспаковывающиеся архивы. При запуске установщика он распаковывает файлы приложения и выполняет скрипт для добавления  ключей в реестр, создания необходимых директорий (в %AppData%) и помещении в них файлов. Именно здесь кроется проблема: любая антивирусная программа воспринимает файл установщика за вирус. Чтобы решить проблему 1С предлагает использовать механизм подписи файлов кодом разработчика. Для этого применяется программа signtool. Если у вас есть код разработчика, то нужно подписать все файлы в собственном приложении. В третьей статье цикла представлена моя попытка решения этой проблемы. В Linux этой проблемы нет.

Деинсталятор собственного приложения создаётся с помощью NSIS с именем uninstall.exe. Существует возможность стандартного удаления собственного приложения: Пуск -> Параметры -> Приложения и возможности. В списке приложений находим пункт с именем из настройки Полное наименование продукта из settings.cmake и с соответствующей настройкам версией, нажимаем Удалить, запускается файл uninstall.exe из каталога приложения, нажимаем Uninstall.

Алгоритм взаимодействия кода 1С с внешней компонентой в режиме веб-клиента

Для взаимодействия с собственным приложением веб-расширение 1С использует сообщения формата json с полем type равным "callHost" или "hello". Тип "hello" используется при подключении ВК, тип "callHost" при отправке запросов.

При подключении ВК в коде 1С вызывается процедура  НачатьПодключениеВнешнейКомпоненты, процедура инициирует вызов сервера и передаёт значения параметров os, arch и client. Из макета с архивом ВК на сервере извлекаются файлы, файл manifest.xml анализируется, на основании переданных в запросе значений находится строка в манифесте, на веб-клиент передаётся значение поля object. Например, для строки манифеста

<component os="Windows" path="WebExNativeAppTemplate_Win64_1001.rename_to_exe" type="plugin" object="com.mycompany.enterprise.webexnativeapptemplate.1001" arch="x86_64" client="Chrome" />

значения запроса будут os="Windows", arch="x86_64", client="Chrome", возвращаемое значение object - "com.mycompany.enterprise.webexnativeapptemplate.1001". Фреймворк 1С полученное значение передаёт веб-расширению 1С, веб-расширение при подключении ВК передаёт в веб-браузер сообщение «Hello», веб-браузер ищет в реестре Windows ключ HKEY_CURRENT_USER\SOFTWARE\Google\Chrome\NativeMessagingHosts\<значение object>com.mycompany.enterprise.webexnativeapptemplate.1001, берется значение по умолчанию ключа, являющееся ссылкой на файл манифеста собственного приложения для веб-браузера,

например: C:\Users\пользователь>\AppData\Roaming\MyCompany\WebExNativeAppTemplate\1.0.0.1\x64\com.mycompany.enterprise.webexnativeapptemplate.1001.json,

Пример файла манифеста собственного приложения для Chrome:

{

"name": "com.mycompany.enterprise.webexnativeapptemplate.1001",

"description": "WebExNativeAppTemplate Extension for Chrome",

"path": "AddInChrWin64.exe",

"type": "stdio",

"allowed_origins": [

"chrome-extension://pbhelknnhilelbnhfpcjlcabhmfangik/",

"chrome-extension://dabkapchgmdkcihphgicpalppegkpond/",

"chrome-extension://fbeahdpfmckplkadiogimnogijfcbnbd/"

]

}

В разделе path файла манифеста собственного приложения должен быть указан полный путь к адаптеру. Веб-браузер вызывает адаптер и передаёт ему сообщение «Hello», адаптер опрашивает нативную библиотеку, расположенную в одной с ним директории, и возвращает ответ. Если вся цепочка запросов прошла успешно, в параметр ОписаниеОповещения процедуры НачатьПодключениеВнешнейКомпоненты возвращается значение Истина, если что-то пошло не так, то Ложь.

Если результат Ложь, то ВК нужно установить. Для этого используем процедуру НачатьУстановкуВнешнейКомпоненты. Эта процедура отправляет запрос на сервер 1С с теми же параметрами, сервер 1С ищет в строке манифеста строку, значение реквизита path ищется среди файлов архива ВК, файл установщика отправляется в браузер.

Сообщение платформы 1С о загрузке установщика в Firefox
Сообщение платформы 1С о загрузке установщика в Firefox

Веб-браузер запускает процесс скачивания файла установщика и с периодичностью в несколько секунд ищет в реестре Windows ключ. Как только пользователь запустит установщик и тот произведёт инсталляцию, веб-браузер запускает цепочку передачи сообщения о начале подключения ВК - «Hello».

При обращении к методам и свойствам ВК из кода 1С фреймворк отправляет запрос на сервер, аналогичный приведенному выше, получает в ответ значение object, передаёт полученное значение веб-расширению. Веб-расширение пересылает с помощью веб-браузера адаптеру json сообщение с полем type = "callHost". Адаптер принимает сообщение из stdin, парсит, вызывает соответствующий метод нативной библиотеки. Результат по цепочке обратно возвращается в код 1С.

Структура решения

Предлагаемое решение состоит из архива, содержащего настройки для сборки проекта. Архив содержит файлы и каталоги:

  1. settings.cmake
  2. Extension.epf
  3. include
  4. lib
  5. NativeAPI
  6. project

В settings.cmake хранятся настройки данного проекта.

Образец settings.cmake из решения

#=====================================================#
#Наименование компании. Допускаются символы [A..Z],[a..z],_,[0..9]
SET(MyCompany "MyCompany" CACHE STRING "Company name")
#=====================================================#
#Наименование продукта. Допускаются символы [A..Z],[a..z],_,[0..9]
SET(MyProductName "WebExNativeAppTemplate" CACHE STRING "Product name")
#Полное наименование продукта. Допускаются любые символы
SET(MyProductNameFull "Шаблон собственного приложения для Web-расширения 1С" CACHE STRING "Full product name")
#=====================================================#
#Версия
SET(Addn_VERSION_MAJOR 1 CACHE STRING "Version major" )
SET(Addn_VERSION_MINOR 0 CACHE STRING "Version minor" )
SET(Addn_VERSION_BUILD 0 CACHE STRING "Version build" )
SET(Addn_VERSION_PATCH 1 CACHE STRING "Version patch" )
#=====================================================#
#Наименование файла-установщика собственного приложения. Допускаются символы [A..Z],[a..z],_,[0..9]
SET(ProductInstaller "WebExNativeAppTemplate" CACHE STRING "Product installer")

Заполнить нужно значения в кавычках - строковые значения и числа для версии.

Extension.epf – внешняя обработка 1С для тестирования собранного пакета.

include – каталог с шаблоном ВК от 1С.

lib – статические библиотеки из шаблона 1С для создание адаптера.

NativeAPI – каталог с нативными библиотеками разработчика в формате: AddIn<32|64>.dll. Библиотеки должны быть предварительно отлажены и скомпилированы при помощи cl.exe для Windows и gcc для Linux. В поставке решения в этом каталоге присутствуют нативные библиотеки из примера от 1С.

project – каталог, в котором содержится функциональная часть проекта:

  1. Каталог AddInChrome содержит файлы для сборки адаптера. В файле config.cpp в переменной typeComponent по умолчанию установлено значение eAddInNative - адаптер связан с нативной библиотекой. Если необходимо собрать адаптер для COM библиотеки, нужно установить значение переменной typeComponent = eAddInCom (но это не точно).
  2. Каталог AddInChromeSetup содержит файлы сборки установщика. AddInChromeSetup.nsi - файл настроек для NSIS. В файле CMake CMakeLists.txt в строке 24 можно изменить расширение установщика "rename_to_exe" на другое, например, "exe". Странное расширение установщика нужно для "обмана" антивируса (но не всегда помогает).
  3. Каталог conf_data_in содержит шаблоны файлов: манифесты, ресурсы и т.д.
  4. Каталог build содержит подкаталог pkg, в котором, после сборки, находятся файлы: manifest.xml, установщик, нативная библиотека. Кроме этого, в каталоге build находится файл с расширением zip - собранный пакет для загрузки в макет 1С.
  5. Скрипты win_build.cmd, win_build32.cmd, win_build64.cmd. Скрипт win_build.cmd собирает пакет сразу для 32-х и 64-х разрядных версий.

Работа с решением

Для того чтобы решение работало под Windows нам понадобятся 3 программы:

  1. Visual Studio 22 или выше с установленной поддержкой v141_xp toolset для сборки адаптера.
  2. CMake последней версии.
  3. NSIS последней версии.

Работа с решением строится по следующему принципу: заполняем своими значениями файл settings.cmake, копируем в каталог NativeAPI скомпилированные нативные библиотеки, выполняем в консоле скрипт project\win_build.cmd (или win_build64.cmd, win_build32.cmd),

Лог выполнения (сокращенный) скрипта win_build64.cmd в консоле
Лог выполнения (сокращенный) скрипта win_build64.cmd в консоле

если в консоле не было ошибок, в каталог project\build\pkg будут помещены файлы с библиотекой, установщиком и манифестом. В каталог project\build будет помещен собранный пакет в формате zip для загрузки в макет 1С. Пакет формируется для той ОС, в которой запущен скрипт. Какого-то механизма объединения пакетов для разных ОС и разрядностей в один в примере от 1С не предусмотрено.  Впрочем, это несложно сделать вручную - нужно просто добавить в zip-архив файлы библиотек и установщиков. Файл manifest.xml сразу идёт с значениями для всех вариантов, его дорабатывать не нужно.

Тестирование

Решение тестировалось в Windows 10 X64, CMake 3.27.9, NSIS 3.09, MS Visual Studio 2022, 1С:Предприятие 8.3 (8.3.23.1739), Chrome 121.0.6167.161 X64, Firefox 122.0.1 X64.