Перехват методов серверных (x64) контекстов с использованием DynamicWrapperX

23.03.17

Разработка - Инструментарий разработчика

Применение COM-объекта DynamicWrapperX на x64-сервере приложений.

Скачать файлы

Наименование Файл Версия Размер
Тестовая база
.dt 59,82Kb
11
.dt 1.0 59,82Kb 11 Скачать

Коллеги, хочу предложить Вам небольшое исследование на предмет изменения функционала серверных контекстов. Речь пойдет о x64-версии 1С сервера приложений для ОС Windows.

Несколько слов о терминах.

    Наверное, я не ошибусь, если скажу, что большинство объектов(в широком смысле этого слова), которые мы привыкли использовать на внутреннем языке платформы, в реальности представляют собой COM-объекты. Именно ими оперирует система. Такие объекты, как <Справочники>, <РезультатЗапроса>, <ДокументОбъект> и т.д, суть COM-объекты внутри движка. Даже числа и строки "оборачиваются" в COM-интерфейсы.

    В данном изложении я буду использовать термин Контекст, подразумевая под ним набор интерфейсов подобных Com-объектов. Описание самих интерфейсов и их IID вы вряд ли найдете в MSDN и regedit'ом в реестре, поскольку это сугубо внутренние интерфейсы платформы. Я не говорю сейчас об IUnknown, IDispatch и прочих стандартных интерфейсах. Среди набора интерфейсов 'внутренних' COM-объектов нам будет интересен интерфейс "вызова через <.>". Мне он видится как некий аналог IDispatch. Я буду ссылаться на него как IContextExtImpBase.

    Когда мы пишем, например, Справочники.<...>, именно в этот момент происходит обращение к методам интерфейса IContextExtImpBase. Хотя нет, если посмотреть на это более детально, то окажется, что объект 'Справочники', это свойство одного из глобальных контекстов (которых в 1С порядка 33), т.е. внутри обращение к 'Справочники' выглядит так <ГК(i)>.Справочники...И каждый из ГК поддерживает тот же IContextExtImpBase.

    Как известно, любой COM-интерфейс имеет строго определенную последовательность методов в виртуальной таблице, поэтому можно попытаться выполнить подмену какого-либо методов интерфейса. Например, за вызовы методов 1С-объектов отвечает метод "IContextExtImpBase::call". Если его подменить на что-то своё, то все вызовы методов 1С-го объекта будут проходить через ваш метод. Причем, это коснется всего серверного рабочего процесса.

    Моя цель была, попытаться минимальными усилиями, после перехвата, "всплыть" на уровень модуля 1С и уже тут продолжить обработку. Для экспериментов я использовал объект Запрос, как наиболее интересный в плане изменения функционала.Перехватывая его методы, можно, например, собирать статистику, ну или налету подменять текст запроса.(Не могу с уверенностью утверждать, но даже если конфигурация поставляется без текста модулей, текст запроса можно получить.)

Вариант реализации.

    Я применил не совсем стандартный подход для решения данной задачи, каюсь. Основные инструменты, которые я использовал, это COM-объект DynamicWrapperX и кусок бинарного кода. (Исходник есть в тестовой базе. Я старался делать подробные комментарии.). Оба написаны на goAsm'е. Весь остальной код написан на стандартном языке 1С. Уверен, что существуют более изящные варианты реализации, но, в любом случае, это всего лишь пример того, как это можно сделать.

Теперь предлагаю посмотреть, что есть в тестовой конфигурации, и рассмотреть, как работает перехват.

  • Серверный общий модуль 'DWX_Информатор'. Тут находятся служебные процедуры и функции для доступа к методам интерфейса IContextExtImpBase. Вообще говоря, сам модуль может использоваться независимо от данной разработки, но отдельно представляет скорее теоретический интерес. Возможно, его можно применить для UNIT-тестирования.
  • Служебная обработка 'Перехват', которая забрасывает кусок бинарного кода на сервер и устанавливает/снимает перехват.
  • Служебная обработка '_proxyInterceptor'. Основная обработка, в которой происходят перенаправления вызовов. Именно сюда (в модуль обработки) "всплывает" перехваченный вызов.
  • Обработка 'ОбработчикПерехвата'. Содержит пользовательские обработчики методов перехваченного контекста.

                Вот один из вариантов, как мог бы выглядеть перехваченный метод Запроса 'Выполнить': 

	Функция Событие_Запрос_Выполнить(Запрос) Экспорт 
		Сообщение 		= Новый СообщениеПользователю;
		Сообщение.Текст = "" + Запрос.Текст;
		Сообщение.Сообщить();	
		
		Рез = Перехватчик.ВыполнитьОригинальноеСобытие();
		
		Колво 			= ?(Рез = Неопределено, 0, Рез.Выбрать().Количество());
		Сообщение.Текст = "Размер выборки:" + Колво;
		Сообщение.Сообщить();	
		
		Возврат Рез;
	КонецФункции

               (Имена пользовательских процедур/функций строятся по принципу Событие_ТипКонтекста_ИмяМетода).

Как работает перехват?

    Предлагаю для простоты считать, что мы имеем дело с объектом Запрос. Как сказано выше, перехват устанавливается глобально на весь рабочий процесс, в котором он вызван, а это значит, что все базы, которые подключены к этому процессу будут иметь дело с измененным методом "IContextExtImpBase::call" интерфейса. В момент вызова какого-либо метода объекта Запрос, выполняется поиск обработки с именем '_proxyInterceptor' в соответствующей базе. Если таковая существует, то выполняется поиск экспортного метода 'ВызватьПерехватчик'. Далее либо отрабатывает переопределенный метод из обработки 'ОбработчикПерехвата', либо выполняется вызов оригинального метода. Если обработки '_proxyInterceptor' не существует, то происходит вызов оригинального метода.

    Важно (1)! Чтобы упростить реализацию, я предполагаю, что право на использование обработки '_proxyInterceptor' есть у каждого пользователя, во всех базах, где она присутствует. Это критично. Если это не так хотя бы для какого-то пользователя, в какой-либо базе, где есть эта обработка, то произойдет перезагрузка серверного процесса (если будет использован объект Запрос). Так же имеет смысл выдать право на использование обработки  "ОбработчикПерехвата'. В случае отсутствия прав у пользователя, будет просто вызван стандартный метод.

    Важно (2)! Всё вышесказанное, тестировалось на релизе 8.3.9.1818. Скорее всего, на релизах 8.3.9.xxxx тоже будет работать (требует проверки). Про поддержку других релизов имеет смысл говорить, когда будет понимание, нужна ли данная "конструкция" вообще.

Ограничения.

    Что не удалось реализовать? "Нормальную" обработку 1С-х исключений. (Тут я привожу технические подробности, для понимания процесса.) В момент, когда тестовая база была практически готова, выяснилось, что при возникновении 1С-го исключения (например синтаксическая ошибка в тексте запроса) всё рушилось, т.е. рабочий процесс на сервере перегружался.

Поэтому, пришлось сделать рефакторинг 1С-го кода и обернуть критичные участки в Попытка...Исключение.

Далее. Если ошибка возникла при обработке оригинального события,              

	Рез = Перехватчик.ВыполнитьОригинальноеСобытие();

то устанавливается "флаг" ошибки и, уже в бинарном коде, повторно вызывается оригинальное событие, чтобы сгенерировать 1С-е исключение.

Если ошибка произошла внутри модуля обработчика, например, внутри функции,

	Функция Событие_Запрос_Выполнить(Запрос) Экспорт 
		.
		.
		.
	КонецФункции

то выводится просто сообщение об ошибке, выполнение при этом не прекращается. Пока мне не удалось это как-то обойти.

    Важно (3)! Заметил такой нюанс: если запустить какое-нибудь длительное фоновое задание, например, перепроведение документов, и в нём выводить тексты Запросов, то это может привести к перезагрузке рабочего процесса, поскольку просто переполняется очередь сообщений, а объёмный текст и количество запросов этому способствуют. В этой связи я делаю проверку на тип клиента при выводе текста.

    В заключении, хочу обратить внимание на ряд технических моментов, которые могут быть полезны при использовании DynamicWrapperX. Должен сказать, что с момента выхода DynamicWrapperX под x64, прошло более 2-х лет. И до последнего времени я и сам на x64-серверах  ничего путного, кроме как Sleep, не использовал. Здесь, в тестовой базе, можно посмотреть другие варианты применения этого Com-объекта. Например, передача параметров через "слой" 'бинарный код-1С' и наоборот, получение функций-оберток, использование интерфейсов COM-объектов, прочее.

Резюмируя вышесказанное.

Чтобы посмотреть, как это работает, необходимо:

  1. Тестовый сервер с релизом 8.3.9.1818.
  2. DynamicWrapperX (http://dynwrapx.script-coding.com/dwx/pages/dynwrapx.php). Вам нужна версия для x64. Ее необходимо зарегистрировать на сервере.
  3. Установить прилагающуюся тестовую базу.
  4. Запустить тонкого клиента и в меню Сервис выбрать обработку Тест.
  5. Включить перехват (соответствующая кнопка).
  6. Протестировать перехват объекта Запрос. (Кнопка 'Тест запроса').

Для других баз:

  1. Скопировать в базу общий модуль DWX_Информатор (галка сервер).
  2. копировать 2 обработки _proxyInterceptor и ОбработчикПерехвата. Выдать права на использование обработок всем пользователям.
  3. В тестовой базе включить перехват.
  4. Если обе базы (тестовая и данная) подцеплены к одному рабочему процессу, то в окне сообщений можно увидеть результат перехвата.

DynamicWrapperX x64 goAsm перехват ассемблер

См. также

Infostart Toolkit: Инструменты разработчика 1С 8.3 на управляемых формах

Инструментарий разработчика Роли и права Запросы СКД Платформа 1С v8.3 Управляемые формы Запросы Система компоновки данных Конфигурации 1cv8 Платные (руб)

Набор инструментов программиста и специалиста 1С для всех конфигураций на управляемых формах. В состав входят инструменты: Консоль запросов, Консоль СКД, Консоль кода, Редактор объекта, Анализ прав доступа, Метаданные, Поиск ссылок, Сравнение объектов, Все функции, Подписки на события и др. Редактор запросов и кода с раскраской и контекстной подсказкой. Доработанный конструктор запросов тонкого клиента. Продукт хорошо оптимизирован и обладает самым широким функционалом среди всех инструментов, представленных на рынке.

13000 руб.

02.09.2020    119956    656    389    

701

Infostart PrintWizard

Пакетная печать Печатные формы Инструментарий разработчика Платформа 1С v8.3 Запросы 1С:Зарплата и кадры бюджетного учреждения 1С:Конвертация данных 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 Платные (руб)

Инструмент, позволяющий абсолютно по-новому взглянуть на процесс разработки печатных форм. Благодаря конструктору можно значительно снизить затраты времени на разработку печатных форм, повысить качество и "прозрачность" разработки, а также навести порядок в многообразии корпоративных печатных форм.

18000 руб.

06.10.2023    7015    20    6    

37

Infostart УДиФ: Управление данными и формами

Инструменты администратора БД Инструментарий разработчика Роли и права Платформа 1С v8.3 Конфигурации 1cv8 Россия Платные (руб)

Расширение позволяет без изменения кода конфигурации выполнять проверки при вводе данных, скрывать от пользователя недоступные ему данные, выполнять код в обработчиках. Не изменяет данные конфигурации, легко устанавливается практически на любую конфигурацию на управляемых формах.

10000 руб.

10.11.2023    3253    10    1    

31

SALE! 30%

PowerTools

Инструментарий разработчика Инструменты администратора БД Платформа 1С v8.3 Управляемые формы Конфигурации 1cv8 Россия Платные (руб)

Универсальный инструмент программиста для администрирования конфигураций. Сборник наиболее часто используемых обработок под единым интерфейсом.

3600 2520 руб.

14.01.2013    177350    1071    0    

846

Многопоточность. Универсальный «Менеджер потоков» 2.1

Инструментарий разработчика Платформа 1С v8.3 Конфигурации 1cv8 Россия Платные (руб)

Восстановление партий или взаиморасчетов, расчет зарплаты, пакетное формирование документов или отчетов - теперь все это стало доступнее. * Есть желание повысить скорость работы медленных алгоритмов! Но... * Нет времени думать о реализации многопоточности? * о запуске и остановке потоков? * о поддержании потоков в рабочем состоянии? * о передаче данных в потоки и как получить ответ из потока? * об организации последовательности? Тогда ЭТО - то что надо!!!

5000 руб.

07.02.2018    99206    239    97    

296

[ЕХТ] Фреймворк для Расширений 1С

Инструментарий разработчика Платформа 1С v8.3 Управляемые формы Платные (руб)

"Фреймворк для Расширений 1С" это универсальное и многофункциональное решение, упрощающее разработку и поддержку создаваемых Расширений. Поставляется в виде комплекта из нескольких Расширений с открытым исходным кодом. Работает в любых Конфигурациях в режиме Управляемого приложения с режимом совместимости 8.3.12 и выше без необходимости внесения изменений в Конфигурацию.

3000 руб.

27.08.2019    17920    6    8    

38

1С HTML Шаблоны / HTML Templates

Инструментарий разработчика Платформа 1С v8.3 Конфигурации 1cv8 Платные (руб)

Быстрая и удобная обработка для работы с шаблонами HTML. Позволяет легко и быстро формировать код HTML.

2040 руб.

27.12.2017    27948    3    10    

14

Выполнение произвольного кода или запроса с параметрами через Web-сервис (замена COM-подключений)

Инструментарий разработчика Обмен между базами 1C Платформа 1С v8.3 Платные (руб)

В процессе работы в 1С часто возникает потребность получить данные из другой базы.  Обычно это делается через COM-соединение, и время выполнения запроса при этом оставляет желать лучшего. В данной публикации представлено универсальное решение, позволяющее практически моментально выполнить произвольный код или запрос с параметрами в другой информационной базе через Web-сервис.

2400 руб.

24.09.2019    23492    15    15    

31
Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. bulpi 215 24.03.17 13:35 Сейчас в теме
Автор, конечно, гигант, но практическая ценность сомнительна.
m.s.moiseev; +1 Ответить
2. МимохожийОднако 140 29.03.17 08:41 Сейчас в теме
Хотелось бы примеры практического использования
3. so-quest 140 29.03.17 12:03 Сейчас в теме
Оригинально. Респект за такое.
chessman; +1 Ответить
4. chessman 192 29.03.17 12:58 Сейчас в теме
Как, в общем-то, правильно отметили, «труд», в большей степени, представляет теоретический интерес.
В качестве практического инструмента, на мой взгляд, можно было бы собирать статистику по выполняемым Запросам. Как вариант, записывать тексты запросов, время выполнения, размер выборки, дату, пользователя, для дальнейшего анализа.
То, что касается общего модуля DWX_Информатор, как я уже упоминал, его можно использовать самостоятельно. Например, для создания более универсальных алгоритмов. Допустим, к нам в процедуру приехал Объект. Нам нужно вызвать его экспортный метод «Метод1()», но мы не знаем, есть ли он у Объекта. Кроме как через Попытка…Исключение, сейчас понять это нельзя (поправьте, если ошибаюсь). Выглядит это несколько коряво. Используя DWX_Информатор, это можно сделать.
Думаю, что данный опус, также может быть полезен в качестве примера использования ассемблера. Возможно, это кого-то вдохновит на дальнейшие исследования.
5. sashocq 193 03.04.17 00:10 Сейчас в теме
Интересное исследование.

Есть база КА 2.2. Периодически в ЖР проскакивают записи с непонятным именем события. Можно ли как-то с помощью этого DynamicWrapperX перехватывать каждый вызов ЗаписьЖурналаРегистрации() и залоггировать его контекст выполнения и значения параметров?
6. chessman 192 03.04.17 23:16 Сейчас в теме
(5) Александр, у меня сейчас нет физической возможности проверить это на x64, но на x32 перехват работает.
Тут нужно понимать, что ловятся именно вызовы ЗаписьЖурналаРегистрации(), т.е. если в тексте модуля был вызван этот глобальный метод. Стандартная запись событий сюда не попадает.
То, что касается контекста выполнения, то пока помочь не смогу, хотя сам по себе вопрос довольно актуальный.

Чтобы заработал перехват в Вашем случае, нужно сделать отдельную сборку, поскольку речь идет о перехвате методов Глобальных контекстов. Сделать это не сложно, так что если интересно пишите.
avishnya; sashocq; +2 Ответить
7. sashocq 193 04.04.17 14:16 Сейчас в теме
(6) Владимир, именно это и нужно. Подозреваю, что где-то в коде неправильное имя события передаётся. Простой визуальный осмотр результатов поиска ЗаписьЖурналаРегистрации ничего не дал, т. к. ооочень много кода.

Спасибо, пока добавлю в закладки на будущее. Сейчас слишком большая загрузка по проектам, а вопрос этот не критичный.
8. пользователь 22.12.23 19:50
Сообщение было скрыто модератором.
...
9. пользователь 22.12.23 19:57
Сообщение было скрыто модератором.
...
Оставьте свое сообщение