При интеграции 1С с торговым или промышленным оборудованием (принтеры этикеток, весы, контроллеры) часто возникает необходимость передать управляющую команду по протоколу Telnet. Однако стандартный клиент Windows telnet.exe не предназначен для автоматизации и часто вызывает ошибки при вызове из кода 1С. В этой статье мы подробно разберем, почему возникает ошибка «Не удается найти указанный файл», как ее обойти и какие современные альтернативы лучше использовать для стабильной работы.
Рассмотрим типичную ситуацию: вы проверяете наличие файла по пути C:\Windows\System32\telnet.exe, он там есть, но при вызове через WshShell.Exec или КомандаСистемы программа 1С выдает ошибку. Проанализируем причину этого явления.
Дело в том, что большинство дистрибутивов 1С являются 32-битными приложениями. В 64-битных версиях Windows реализован механизм FS Redirector (перенаправление файловой системы). Когда 32-битная программа обращается к папке System32, операционная система прозрачно для пользователя перенаправляет запрос в папку C:\Windows\SysWOW64. Поскольку утилита telnet.exe является системным компонентом и часто отсутствует в SysWOW64, 1С ее «не видит».
Чтобы решить эту проблему, следует использовать специальный виртуальный путь Sysnative, который позволяет 32-битным приложениям обращаться к реальной папке System32. Исправленный код вызова будет выглядеть так:
// Использование Sysnative для обхода редиректора файловой системы
ПутьКТелнету = "C:\Windows\Sysnative\telnet.exe";
objShell = Новый COMОбъект("WScript.Shell");
Попытка
objScriptExec = objShell.Exec(ПутьКТелнету + " 192.168.102.2");
Исключение
Сообщить("Ошибка запуска: " + ОписаниеОшибки());
КонецПопытки;
Даже если файл успешно запущен, возникает вторая проблема: стандартный telnet.exe в Windows — это интерактивная утилита. Она ожидает ввода пользователя с клавиатуры и не принимает команды через перенаправление потока данных (например, через символ | или <). Попытки использовать SendKeys для имитации нажатий клавиш крайне ненадежны, так как любая задержка сети или смена фокуса окна приведет к потере данных.
Разберем более надежные способы решения задачи.
Одним из самых стабильных решений является использование консольного клиента Plink (часть пакета PuTTY). В отличие от системного телнета, Plink отлично поддерживает автоматизацию и позволяет отправить команду одной строкой.
Рассмотрим пример отправки команды 12345 на устройство:
// Пример использования plink.exe
// -telnet указывает протокол
// -batch отключает интерактивные запросы
КомандаЗапуска = "C:\Tools\plink.exe -telnet -batch 192.168.102.2 -P 4001";
ТекстКоманды = "12345";
// Используем временный файл для передачи команды в поток stdin
ИмяФайлаСкрипта = ПолучитьИмяВременногоФайла("txt");
ТекстовыйДокумент = Новый ТекстовыйДокумент;
ТекстовыйДокумент.УстановитьТекст(ТекстКоманды);
ТекстовыйДокумент.Записать(ИмяФайлаСкрипта, КодировкаТекста.ANSI);
ПолнаяКоманда = "cmd /c type " + ИмяФайлаСкрипта + " | " + КомандаЗапуска;
ЗапуститьПриложение(ПолнаяКоманда, , Истина); // Ждем завершения
Если на сервере или компьютере пользователя нельзя устанавливать стороннее ПО, можно воспользоваться мощью PowerShell, который встроен в современные версии Windows. Мы можем создать TCP-соединение напрямую и отправить данные в сокет. Это наиболее «чистый» способ с точки зрения системного администрирования.
Проанализируем алгоритм: мы создаем объект TcpClient, открываем поток и записываем в него наши данные. Весь этот скрипт можно упаковать в одну строку и вызвать из 1С.
Функция ОтправитьКомандуЧерезPowerShell(IPАдрес, Порт, Команда)
// Формируем скрипт PowerShell
Скрипт = "$socket = New-Object System.Net.Sockets.TcpClient('" + IPАдрес + "', " + Порт + "); " +
"$stream = $socket.GetStream(); " +
"$writer = New-Object System.IO.StreamWriter($stream); " +
"$writer.WriteLine('" + Команда + "'); " +
"$writer.Flush(); " +
"$socket.Close();";
// Запускаем PowerShell с подавлением окна
КомандаВыполнения = "powershell -NoProfile -ExecutionPolicy Bypass -Command """ + Скрипт + """";
ЗапуститьПриложение(КомандаВыполнения, , Истина);
КонецФункции
В последних обновлениях Windows 10 и в Windows 11 утилита cURL встроена в систему по умолчанию. Она поддерживает протокол Telnet. Хотя для сложных интерактивных сессий она подходит меньше, для простой отправки «плевков» данных она может быть полезна.
Команда в консоли выглядит следующим образом: curl telnet://192.168.102.2:4001. Однако стоит учитывать, что cURL может ожидать ручного закрытия сессии, поэтому для автоматизации из 1С метод с PowerShell остается более предпочтительным.
Выясним важную деталь: если ваше устройство — это сетевой принтер, то зачастую использование Telnet избыточно. Большинство принтеров поддерживают RAW-протокол на порту 9100. Если ваша задача — просто отправить последовательность байтов, вы можете отправить файл напрямую на IP-адрес принтера.
В Windows это можно сделать через команду print или просто скопировав файл в сетевой порт, если принтер установлен в системе. Если принтер не установлен, можно использовать утилиту nc (Netcat) для Windows:
echo 12345 | nc -w 1 192.168.102.2 9100
Sleep).Подведем итог: для разовой отправки простой команды на устройство лучшим выбором будет использование PowerShell через ЗапуститьПриложение, так как это не требует внешних библиотек и легко отлаживается. Если же требуется сложный обмен данными с обработкой ответов от устройства, стоит рассмотреть написание или использование готовой Внешней компоненты (Native API) для работы с TCP/IP напрямую.