В процессе разработки и отладки конфигураций на платформе 1С:Предприятие 8.3 (особенно на управляемых формах, таких как 1С:Бухгалтерия 3.0) разработчики часто сталкиваются со странным поведением отладчика в файловом режиме. Типичный сценарий: один и тот же код в модуле набора записей регистра или модуле объекта под одним пользователем RDP успешно отлаживается и заходит внутрь инструкций препроцессора, а под другим пользователем RDP — просто проскакивает мимо этих блоков.
В этой статье мы подробно разберем, почему возникает такая разница в поведении среды выполнения, как устроена работа препроцессора в файловом варианте базы данных и какие существуют гарантированные способы определить текущий контекст выполнения прямо во время сеанса отладки.
Многие ошибочно полагают, что в файловой базе данных «1С:Предприятия» на управляемых формах все процессы всегда выполняются в одном и том же контексте. Однако это не так. Разница в поведении отладчика у различных пользователей в терминальной сессии (RDP) обусловлена двумя ключевыми техническими факторами.
1. Различные настройки запуска клиентского приложения (файл ibases.v8i)
У каждого пользователя операционной системы Windows формируется свой собственный профиль, где хранятся индивидуальные настройки списка баз. Этот файл расположен по пути: %APPDATA%\1C\1CEstart\ibases.v8i. В данном файле для каждой информационной базы прописаны параметры запуска:
DefaultApp=1CV8C или выбран режим «Выбирать автоматически», который по умолчанию стартует тонкий клиент).DefaultApp=1CV8).При запуске в режиме толстого клиента управляемого приложения препроцессор платформы ведет себя иначе, чем в тонком клиенте. В толстом клиенте код клиента и эмулируемый код сервера выполняются в рамках одного и того же физического процесса на локальном компьютере, что напрямую влияет на компиляцию блоков #Если Сервер.
2. Настройки подключения предметов отладки и права брандмауэра
В файловом режиме при работе через Тонкий клиент платформа имитирует клиент-серверное взаимодействие. Для этого запускается отдельный поток — так называемый локальный файловый сервер. В результате в системе регистрируются два независимых предмета отладки: клиентское приложение (Тонкий клиент) и серверный контекст (Файловый сервер).
Если у одного из пользователей RDP в конфигураторе не настроено автоматическое подключение серверных сеансов, отладчик будет игнорировать серверный код:
#Если Сервер.Поскольку инструкции препроцессора, начинающиеся с символа #, обрабатываются компилятором 1С еще до непосредственного исполнения кода, мы не можем просто написать их в окне вычисления выражений (Shift+F9) для проверки. Тем не менее, у нас есть несколько надежных способов узнать текущий контекст.
Самый простой способ — обратить внимание на цветовое оформление кода непосредственно в редакторе конфигуратора во время остановки на точке останова. Конфигуратор анализирует контекст текущей сессии отладки и динамически форматирует текст:
Если у одного пользователя блок под директивой #Если Сервер горит ярким цветом, а у другого — серым, значит, они запущены в принципиально разных клиентах или с разными настройками подключения отладки.
Когда выполнение программы прервано точкой останова, откроем окно Стек вызовов (горячие клавиши Ctrl + Alt + C). В данном окне отображается вся цепочка вызовов процедур и функций, приведшая к текущему состоянию. Обратим внимание на колонку с именами процедур:
#Если Сервер вернет истину).Давайте проанализируем, к каким процессам сейчас подключен наш конфигуратор. Для этого перейдем в меню Отладка -> Подключение...
В таблице «Подключенные предметы отладки» детально расписан тип каждого процесса. Здесь мы можем увидеть:
Если в списке подключенных предметов отсутствует «Файловый сервер», то любые точки останова на сервере будут игнорироваться.
Для гарантированного программного определения среды во время отладки мы можем использовать встроенные функции платформы. Откроем окно Вычислить выражение (клавиша Shift + F9) или добавим выражения в Табло.
Рассмотрим применение функции ИмяПриложения(). Она возвращает строковое системное имя запущенного клиента. Проанализируем возможные варианты:
// Введем в Табло: ИмяПриложения()
// Возможные возвращаемые значения:
// "1CV8" - Запущен Толстый клиент (управляемое или обычное приложение)
// "1CV8C" - Запущен Тонкий клиент
// "WebClient" - Запущен Веб-клиент в браузере
// "COMConnection"- База запущена в режиме внешнего соединения (COM)
Для того чтобы точно определить, не запущен ли толстый клиент в режиме обычного приложения (что соответствует условию препроцессора ТолстыйКлиентОбычноеПриложение), воспользуемся функцией ТекущийРежимЗапуска(). Она возвращает системное перечисление РежимЗапускаКлиентскогоПриложения.
Рассмотрим пример кода, демонстрирующий логику этой проверки:
Режим = ТекущийРежимЗапуска();
Если Режим = РежимЗапускаКлиентскогоПриложения.Обычное Тогда
// Это режим "ТолстыйКлиентОбычноеПриложение"
Сообщить("Запущено обычное приложение!");
ИначеЕсли Режим = РежимЗапускаКлиентскогоПриложения.Управляемое Тогда
// Запущено управляемое приложение (тонкий или толстый управляемый клиент)
Сообщить("Запущено управляемое приложение!");
КонецЕсли;
Комбинируя результаты функций ИмяПриложения() и ТекущийРежимЗапуска() в окне вычисления выражений отладчика, мы можем со 100% уверенностью определить, под какими именно условиями препроцессора сейчас работает текущий сеанс 1С.