В процессе работы в 1С через терминальный сервер (RDP) разработчики и администраторы могут столкнуться с крайне специфической ошибкой: при выполнении запроса система выдает сбой исполнения, а в тексте самого запроса или в журнале регистрации появляются случайные китайские иероглифы и нечитаемые символы. При этом в конфигураторе код выглядит абсолютно корректно, а у пользователей, работающих локально (без RDP), ошибка не воспроизводится.
Рассмотрим подробнее причины возникновения этого сбоя и разберем по шагам действенные методы его устранения.
Выясним причину, почему обычный текст на кириллице в строковых буферах превращается в иероглифы Unicode. Ключевая особенность ошибки заключается в том, что она проявляется исключительно в RDP-сессиях. Это указывает на комплексную проблему взаимодействия платформы 1С с операционной системой и терминальной средой:
Проанализируем конфигурацию операционной системы на терминальном сервере. Чаще всего сбой связан с тем, что системный язык по умолчанию отличается от языка сеанса пользователя.
Русский (Россия).HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\CodePage значение параметра 1252 заменено на c_1251.nls (если на сервере ранее некорректно исправлялась кодировка).Посмотрим на процедуру очистки временных файлов. Поскольку переподключение к RDP помогает лишь временно, необходимо полностью удалить кэш конфигурации конкретного пользователя на сервере.
Очистить кэш можно вручную, удалив содержимое каталогов с GUID-именами из следующих папок профиля Windows:
%userprofile%\AppData\Local\1C\1Cv8
%userprofile%\AppData\Roaming\1C\1Cv8
Также полезно пересоздать сам профиль Windows терминального пользователя (NTUSER), если проблема воспроизводится у строго определенных учетных записей.
Если проблема возникает в динамически формируемых запросах, перепишем алгоритм так, чтобы сборка текста не нагружала память 32-разрядного клиента и не приводила к искажению строк.
1. Выполнение сборки и запроса на стороне сервера:
Перенесите формирующий запрос код в контекст &НаСервере. На стороне сервера (особенно 64-разрядного) адресация памяти работает стабильно, а лимиты 32-битного клиента отсутствуют.
2. Использование параметров вместо прямой конкатенации:
Избегайте склеивания текста запроса из фрагментов строк через оператор +. Используйте метод УстановитьПараметр().
Рассмотрим пример правильной передачи строковых условий:
// Корректный подход: передача параметров вместо динамической склейки строк
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Контрагенты.Ссылка КАК Контрагент,
| Контрагенты.ИНН КАК ИНН
|ИЗ
| Справочник.Контрагенты КАК Контрагенты
|ГДЕ
| Контрагенты.Наименование ПОДОБНО &СтрокаПоиска";
Запрос.УстановитьПараметр("СтрокаПоиска", "%" + ИскомоеНаименование + "%");
Результат = Запрос.Выполнить();
3. Использование объекта СхемаЗапроса:
Для безопасного программного построения сложных запросов вместо ручной сборки текста рекомендуется использовать встроенный объект СхемаЗапроса. Это исключает прямой контакт со строковыми буферами:
// Программное формирование структуры запроса через СхемуЗапроса
Схема = Новый СхемаЗапроса;
Пакет = Схема.ПакетыЗапросов[0];
Оператор = Пакет.Операторы[0];
// Добавление источника данных и полей
Источник = Оператор.Источники.Добавить("Справочник.Контрагенты", "Контрагенты");
Оператор.ВыбираемыеПоля.Добавить("Контрагенты.Ссылка");
Запрос = Новый Запрос;
Запрос.Текст = Схема.ПолучитьТекстЗапроса();
РезультатЗапроса = Запрос.Выполнить();
В старых версиях платформы (включая ветки 8.3.6) присутствовали платформенные ошибки управления динамической памятью при работе с Unicode-строками. Если вышеописанные шаги не дают длительного эффекта, рекомендуется: