При администрировании и разработке в системе 1С:Предприятие 7.7 на современных операционных системах (таких как Windows 7, Windows 10, Windows Server 2012 / 2016 / 2019) специалисты часто сталкиваются с неприятной проблемой. При программном добавлении записей в журнал регистрации с помощью функции ЗаписьЖурналаРегистрации вместо привычного русского текста на кириллице записываются нечитаемые символы — так называемые «кракозябры». При этом штатные системные события могут регистрироваться на нормальном русском языке, а искажения происходят именно в сообщениях, формируемых программным путем.
В рамках данной статьи мы подробно разберем, почему возникает этот сбой, проанализируем компромиссное решение с двойным преобразованием кодировок в коде и рассмотрим правильные системные методы исправления локали Windows без модификации программного кода 1С.
Платформа 1С:Предприятие 7.7 разрабатывалась во времена доминирования однобайтовых кодировок (ANSI/OEM) и не имеет встроенной поддержки Юникода (Unicode). Вся работа с текстовыми файлами, включая запись в журнал регистрации, который физически хранится в файле 1cv7.mlg в каталоге SYSLOG, опирается на системные вызовы Windows API.
Когда мы вызываем функцию ЗаписьЖурналаРегистрации, платформа передает строку операционной системе для записи на диск. На современных ОС Windows, особенно в многопользовательских терминальных средах (RDP) или на англоязычных версиях систем без должной локализации, возникает конфликт интерпретации кодовых страниц. Это происходит по следующим причинам:
BkEnd.dll, BkEndUtls.dll). Некоторые из этих неофициальных исправлений при перехвате системных вызовов некорректно обрабатывают передачу указателей на строки, ошибочно преобразуя ANSI-строки в OEM-формат DOS и обратно.В результате на диск записывается искаженная последовательность байтов, которая при последующем чтении журналом регистрации отображается в виде хаотичного набора спецсимволов.
Рассмотрим временное решение, к которому пришел автор обсуждения на форуме. Если у вас нет прав на администрирование сервера или проблему нужно решить оперативно «здесь и сейчас» непосредственно в конфигурации, можно использовать принудительное двойное преобразование строки перед ее записью в лог.
Выяснилось, что если последовательно применить к строке функции преобразования кодировок из ANSI в OEM и обратно, то на выходе мы получаем байтовую последовательность, которую искаженный механизм записи платформы воспринимает корректно.
Посмотрим на пример кода, реализующий этот обходной путь:
// Некорректный вариант, вызывающий появление кракозябр на проблемных серверах:
ЗаписьЖурналаРегистрации("Мое сообщение", "ДопПараметр", 3, "МоеСобытие", "Описание");
// Обходной («костыльный») вариант с двойным преобразованием:
ИсправленныйТекст = AnsiToOEM(OEMToAnsi("Мое сообщение"));
ЗаписьЖурналаРегистрации(ИсправленныйТекст, "ДопПараметр", 3, "МоеСобытие", "Описание");
Проанализируем эту ситуацию. С логической точки зрения функции AnsiToOEM (перевод из Windows-1251 в DOS CP866) и OEMToAnsi (перевод из DOS в Windows) должны полностью компенсировать друг друга, возвращая строку в исходное состояние. Однако в условиях некорректно настроенной локали операционной системы этот двойной вызов искусственно сдвигает байты символов кириллицы так, что после ошибочного системного преобразования самой Windows в файл лога записывается правильная кодировка Windows-1251.
Важное предупреждение: Мы настоятельно не рекомендуем использовать данный метод на постоянной основе! Постоянный вызов функций перекодирования строк нагружает процессор (особенно при интенсивной записи в журнал регистрации в циклах или при проведении документов) и ухудшает читаемость исходного кода.
Чтобы решить проблему раз и навсегда для всех баз данных и исключить необходимость модификации кода конфигурации, мы должны правильно настроить системную локаль Windows. Разберем по шагам, как это сделать на примере Windows Server 2012 / 2016:
В некоторых случаях (особенно если операционная система сервера изначально была англоязычной) стандартной смены локали в панели управления бывает недостаточно. Тогда нам потребуется жестко перенаправить обработку западноевропейских кодовых страниц на кириллическую непосредственно через системный реестр Windows.
Выполним следующие шаги:
Win + R, введя команду regedit и нажав клавишу Enter.HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\CodePageREG_SZ) со следующими именами:
1250 (Центрально-европейская кодовая страница)1252 (Западно-европейская кодовая страница)c_1252.nls) на кириллическую страницу: c_1251.nls.1251 также должен иметь значение c_1251.nls.Этот способ принудительно заставляет Windows обрабатывать любые ANSI-строки старых программ через кириллическую таблицу символов, полностью устраняя проблему «кракозябр» в 1С 7.7.
В процессе экспериментов со сбитой кодировкой системные администраторы часто сталкиваются со странным поведением платформы: при попытке открыть журнал регистрации в режиме «Предприятие» программа неожиданно запрашивает пароль, хотя никто его не устанавливал.
Проанализируем причину этого явления. Из-за некорректных преобразований или аварийных сбоев при записи поврежденных символов в файл 1cv7.mlg записываются бинарные нули или неопознанные спецсимволы. Платформа 1С 7.7, считывая этот «мусор» в начале или конце файла, ошибочно интерпретирует искаженные данные как зашифрованный лог-файл и выводит стандартное окно авторизации.
Для исправления этой проблемы выполним следующие действия:
SYSLOG.1cv7.mlg. При следующем запуске программа автоматически создаст новый чистый лог-файл, и запрос пароля пропадет.1cv7.mlg в любом продвинутом текстовом редакторе (например, Notepad++). Перейдем в самый конец файла, найдем поврежденную строку с нечитаемыми бинарными символами (часто она обрывается на середине из-за сбоя питания), удалим ее и сохраним файл в кодировке ANSI (Windows-1251).Таким образом, мы рассмотрели как быстрые программные методы локализации ошибки, так и фундаментальные системные настройки, позволяющие раз и навсегда вернуть корректное отображение кириллицы в журнале регистрации 1С 7.7 на любых современных операционных системах.