Как исправить проблему с кодировкой (кракозябрами) при использовании метода КомандаСистемы в 1С?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке на платформе 1С часто возникает необходимость взаимодействия с операционной системой через командную строку. Использование метода КомандаСистемы — это самый простой способ выполнить внешнюю команду, например, получить список файлов или запустить скрипт. Однако разработчики часто сталкиваются с тем, что результат выполнения команды, перенаправленный в текстовый файл, превращается в нечитаемые символы («кракозябры»). Это происходит из-за конфликта кодировок между 1С, командным интерпретатором Windows (CMD) и текстовым файлом.

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

Выясним причину: почему появляются кракозябры?

Основная причина кроется в том, что по умолчанию командная строка Windows (cmd.exe) в русскоязычных версиях ОС использует кодировку OEM 866 (старая кодировка DOS). В то же время платформа 1С и большинство текстовых редакторов ожидают увидеть текст в кодировке Windows-1251 (ANSI) или UTF-8. Когда мы выполняем команду dir >> text.txt, данные записываются в файл в кодировке 866. Если затем мы пытаемся прочитать этот файл в 1С стандартными средствами, не указывая кодировку явно, платформа пытается интерпретировать байты 866 как символы 1251, что и приводит к появлению странных знаков.

Важно понимать нюанс метода КомандаСистемы: каждый раз при его вызове 1С создает новый сеанс командной строки, выполняет одну команду и немедленно закрывает его. Поэтому команда chcp 1251, выполненная отдельным вызовом, никак не повлияет на последующие вызовы, так как они будут работать в новых сеансах со стандартными настройками.

Способ 1. Чтение файла с явным указанием кодировки OEM

Если вы уже создали файл через КомандаСистемы и получили в нем текст в кодировке DOS, нам не обязательно менять способ записи. Мы можем изменить способ чтения этого файла в самой 1С. Рассмотрим, как это сделать программно.

Вместо стандартного чтения, которое использует системную кодировку, мы воспользуемся объектом ЧтениеТекста, где явно укажем, что файл сохранен в формате OEM.


// Выполняем команду, результат пишется в файл в кодировке 866 (OEM)
КомандаСистемы("dir > C:\Temp\result.txt");

// Читаем файл правильно
ПутьКФайлу = "C:\Temp\result.txt";
ТекстРезультат = Новый ЧтениеТекста(ПутьКФайлу, КодировкаТекста.OEM);
СтрокаДанных = ТекстРезультат.Прочитать();
ТекстРезультат.Закрыть();

Сообщить(СтрокаДанных);

Этот метод является самым простым и надежным, так как он не требует изменения настроек операционной системы или сложных манипуляций с командной строкой.

Способ 2. Использование ключа /U для вывода в Unicode

Командный интерпретатор Windows имеет встроенный ключ /U, который заставляет внутренние команды (такие как DIR, TYPE, ECHO) выводить данные в формате Unicode (UTF-16LE). Платформа 1С отлично распознает Unicode, поэтому это решит проблему с кодировкой на этапе создания файла.

Рассмотрим пример правильного вызова команды:


// Ключ /C означает выполнение команды и завершение работы CMD
// Ключ /U переводит вывод в формат Unicode
ПутьКФайлу = "C:\Temp\unicode_result.txt";
Команда = "cmd /U /C ""dir C:\Projects > " + ПутьКФайлу + """";
КомандаСистемы(Команда);

// Теперь 1С прочитает этот файл без дополнительных настроек
ТекстДок = Новый ТекстовыйДокумент;
ТекстДок.Прочитать(ПутьКФайлу);
Сообщить(ТекстДок.ПолучитьТекст());

Обратите внимание: При использовании этого метода файл будет содержать BOM (Byte Order Mark), что позволяет 1С автоматически определить кодировку файла как Unicode.

Способ 3. Использование PowerShell для гибкого управления кодировкой

Современным стандартом автоматизации в Windows является PowerShell. Он гораздо мощнее старого cmd.exe и позволяет явно указывать кодировку выходного файла. Проанализируем ситуацию: если нам нужен файл именно в UTF-8, мы можем вызвать PowerShell прямо из 1С.


// Формируем команду PowerShell
// Out-File позволяет задать кодировку utf8, ascii, unicode, oem и т.д.
КомандаPS = "powershell -Command ""Get-ChildItem C:\Projects | Out-File -FilePath C:\Temp\ps_out.txt -Encoding UTF8""";
КомандаСистемы(КомандаPS);

// Читаем результат
ФайлРезультата = Новый ЧтениеТекста("C:\Temp\ps_out.txt", КодировкаТекста.UTF8);
Результат = ФайлРезультата.Прочитать();
ФайлРезультата.Закрыть();

Использование PowerShell избавляет нас от необходимости возиться с устаревшими кодировками 866 и 1251, предоставляя современный способ работы с текстом.

Способ 4. Работа через COM-объект WScript.Shell (чтение StdOut)

Если ваша задача — не просто записать файл, а сразу получить результат выполнения команды в переменную 1С, то метод КомандаСистемы не самый лучший выбор, так как он не возвращает результат работы команды (только код завершения). Профессиональнее будет использовать объект WScript.Shell.

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


Шелл = Новый COMОбъект("WScript.Shell");
// Запускаем команду через метод Exec
Процесс = Шелл.Exec("cmd /C dir C:\Projects");
// Читаем поток вывода
РезультатТекст = Процесс.StdOut.ReadAll();

// Если текст все равно в OEM, можно воспользоваться функцией перекодировки
// Но обычно через COM-объект данные приходят в системной кодировке
Сообщить(РезультатТекст);

Этот способ позволяет более тонко контролировать процесс выполнения: вы можете проверять статус завершения или читать ошибки из потока StdErr.

Способ 5. Использование временного бат-файла (.bat)

Иногда возникают ситуации, когда нужно выполнить последовательность команд (например, смену кодировки и затем основную команду) в рамках одного сеанса. В этом случае лучше всего создать временный пакетный файл. Посмотрим на пример реализации:

  1. Создаем текстовый файл с расширением .bat.
  2. Записываем в него нужные команды, включая chcp 1251.
  3. Выполняем этот файл через КомандаСистемы.

ТекстБат = Новый ТекстовыйДокумент;
ТекстБат.ДобавитьСтроку("chcp 1251");
ТекстБат.ДобавитьСтроку("dir > C:\Temp\final_res.txt");
ПутьКБат = "C:\Temp\run.bat";
// Сохраняем батник в ANSI (1251), чтобы CMD его правильно понял
ТекстБат.Записать(ПутьКБат, КодировкаТекста.ANSI);

КомандаСистемы(ПутьКБат);

Важный момент: Чтобы сам файл .bat работал корректно с кириллицей внутри своих команд, его нужно сохранять в той кодировке, которую ожидает система (обычно ANSI для скриптов в РФ).

Подведем итоги и выберем лучшее решение

Проанализировав все способы, можно сделать следующие выводы:

Рекомендуем всегда проверять, действительно ли вам необходим вызов системных команд. В 1С есть мощные встроенные средства для работы с файловой системой (НайтиФайлы, КопироватьФайл и т.д.), которые работают стабильно и не зависят от кодировок операционной системы.

← На главную