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

23.03.17

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

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

Скачать файл

ВНИМАНИЕ: Файлы из Базы знаний - это исходный код разработки. Это примеры решения задач, шаблоны, заготовки, "строительные материалы" для учетной системы. Файлы ориентированы на специалистов 1С, которые могут разобраться в коде и оптимизировать программу для запуска в базе данных. Гарантии работоспособности нет. Возврата нет. Технической поддержки нет.

Наименование По подписке [?] Купить один файл
Тестовая база
.dt 59,82Kb ver:1.0
12
12 Скачать (1 SM) Купить за 1 850 руб.

Коллеги, хочу предложить Вам небольшое исследование на предмет изменения функционала серверных контекстов. Речь пойдет о 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 перехват ассемблер

См. также

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

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

12000 руб.

02.09.2020    170049    940    403    

906

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

Инструмент представляет собой обработку для проведения свёртки или обрезки баз данных. Работает на ЛЮБЫХ конфигурациях (УТ, БП, ERP и т.д.). Поддерживаются серверные и файловые базы, управляемые и обычные формы. Может выполнять свертку сразу нескольких баз данных и выполнять их автоматически без непосредственного участия пользователя. Решение в Реестре отечественного ПО

8400 руб.

20.08.2024    13106    100    46    

104

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

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

9360 руб.

17.05.2024    26758    90    48    

134

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

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

22200 руб.

06.10.2023    16948    41    15    

75

SALE! %

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

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

4800 3840 руб.

14.01.2013    190728    1151    0    

918

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

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

15000 руб.

10.11.2023    11461    40    27    

66

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

Разработка Конструктор автоматизированных рабочих мест "Конструктор АРМ" реализована в виде расширения и является универсальным инструментом для создания АРМ любой сложности в пользовательском режиме.

3600 руб.

27.12.2024    935    2    0    

5

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

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

5000 руб.

07.02.2018    104001    244    100    

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

Есть база КА 2.2. Периодически в ЖР проскакивают записи с непонятным именем события. Можно ли как-то с помощью этого DynamicWrapperX перехватывать каждый вызов ЗаписьЖурналаРегистрации() и залоггировать его контекст выполнения и значения параметров?
6. chessman 193 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
Сообщение было скрыто модератором.
...
Оставьте свое сообщение