Как отправить XML через cURL в 1С 7.7 и избежать ошибки «Неверное имя файла» при чтении ответа?

Программист 1С v7.7 IT и автоматизация бизнеса
← На главную

При интеграции 1С:Предприятия 7.7 с внешними сервисами разработчики часто сталкиваются с задачей отправки XML-пакетов по протоколам HTTP/HTTPS. Распространенным решением является вызов консольной утилиты curl.exe с сохранением тела ответа в текстовый файл на диске. Однако при попытке прочитать полученный файл через стандартный объект Текст платформа нередко выдает ошибку: «Неверное имя файла».

Разберем причины возникновения этой ошибки и рассмотрим надежные способы ее устранения, а также современные альтернативы отправки HTTP-запросов напрямую из 1С 7.7.

Почему возникает ошибка «Неверное имя файла»

Проанализируем механику работы кода. В платформе 1С 7.7 сообщение «Неверное имя файла» при вызове метода Открыть() объекта Текст является общей системной ошибкой ввода-вывода (I/O). Она возникает в следующих случаях:

  1. Асинхронный запуск процесса: процедура ЗапуститьПриложение() стартует указанную программу в отдельном потоке и немедленно передает управление следующей строке кода 1С. В этот момент утилита curl.exe еще только устанавливает сетевое соединение, и целевой файл либо еще физически не создан, либо заблокирован процессом cURL на запись.
  2. Блокировка файла на запись: пока внешний процесс удерживает дескриптор файла, объект Текст не может получить к нему доступ.
  3. Пробелы в путях: если в пути к исполняемому файлу или каталогу сохранения есть пробелы, командная строка Windows может некорректно интерпретировать параметры без дополнительного экранирования кавычками.

Способ 1. Использование синхронной процедуры «КомандаСистемы»

Самый простой и быстрый способ исправить поведение кода — заменить процедуру ЗапуститьПриложение() на КомандаСистемы(). В отличие от первого метода, КомандаСистемы() приостанавливает выполнение программного кода 1С до тех пор, пока вызванная консольная команда полностью не завершит свою работу и не закроет все файловые дескрипторы.

Посмотрим на пример правильной организации вызова:


ПутьККурлу = "C:\curl-7.52.0-win64-mingw\bin\curl.exe";
ПутьКФайлуОтвета = "D:\SERTHTTP\response.txt";
ПутьКXML = "D:\SERTHTTP\request.xml";
АдресСервера = "https://example.com/api/send";

// Формируем команду с явным перенаправлением ответа через флаг -o
ТекстКоманды = """" + ПутьККурлу + """ -s -S -X POST -d @" + """" + ПутьКXML + """ -H ""Content-Type: text/xml; charset=utf-8"" -o """ + ПутьКФайлуОтвета + """ """ + АдресСервера + """";

// Синхронный вызов - 1С ждет завершения работы curl
КомандаСистемы(ТекстКоманды);

// Чтение полученного ответа
Если ФС.СуществуетФайл(ПутьКФайлуОтвета) = 1 Тогда
    ФайлЛога = СоздатьОбъект("Текст");
    ФайлЛога.КодоваяСтраница(0);
    ФайлЛога.Открыть(ПустьКФайлуОтвета);
    Если ФайлЛога.КоличествоСтрок() > 0 Тогда
        // Обработка содержимого ответа
        Сообщить("Ответ успешно получен!");
    КонецЕсли;
Иначе
    Сообщить("Файл ответа не был создан.", "!");
КонецЕсли;

Способ 2. Запуск через WScript.Shell в фоновом режиме

Процедура КомандаСистемы() вызывает кратковременное мерцание черного окна командной строки (CMD), что может мешать пользователю. Чтобы выполнить синхронный вызов скрытно, воспользуемся системным COM-объектом WScript.Shell и его методом Run().

Разберем параметры метода Run(Команда, РежимОкна, ЖдатьЗавершения):

  1. РежимОкна = 0: скрытый запуск (окно консоли не отображается).
  2. ЖдатьЗавершения = 1: синхронный режим (скрипт ждет завершения внешней программы).

Посмотрим на реализацию вызова:


ПутьККурлу = "C:\curl-7.52.0-win64-mingw\bin\curl.exe";
ПутьКФайлуОтвета = "D:\SERTHTTP\response.txt";
ТекстКоманды = """" + ПутьККурлу + """ -s -o """ + ПутьКФайлуОтвета + """ https://example.com/api/send";

WshShell = СоздатьОбъект("WScript.Shell");
// Третий параметр = 1 обеспечивает синхронное ожидание без мигания окон
КодВозврата = WshShell.Run(ТекстКоманды, 0, 1);

Если КодВозврата = 0 Тогда
    Если ФС.СуществуетФайл(ПутьКФайлуОтвета) = 1 Тогда
        ФайлЛога = СоздатьОбъект("Текст");
        ФайлЛога.Открыть(ПутьКФайлуОтвета);
        // Извлечение информации
    КонецЕсли;
Иначе
    Сообщить("Ошибка при выполнении cURL. Код ошибки: " + КодВозврата, "!");
КонецЕсли;

Способ 3. Прямая отправка запросов через WinHttpRequest (без cURL и файлов)

Для интеграции с веб-сервисами в 1С 7.7 нет строгой необходимости использовать сторонний curl.exe и создавать промежуточные файлы на жестком диске. В Windows встроен стандартный COM-объект WinHttp.WinHttpRequest.5.1, который позволяет выполнять синхронные HTTP/HTTPS POST-запросы напрямую в оперативной памяти.

Рассмотрим пример отправки XML и получения статуса ответа сервера:


Попытка
    HTTP = СоздатьОбъект("WinHttp.WinHttpRequest.5.1");
    АдресСервера = "https://example.com/api/send";
    
    // Третий параметр 0 (Ложь) означает синхронный режим
    HTTP.Open("POST", АдресСервера, 0);
    HTTP.SetRequestHeader("Content-Type", "text/xml; charset=utf-8");
    
    // Подготовка тела XML-запроса
    ТекстXML = "<request><data>Тест</data></request>";
    HTTP.Send(ТекстXML);
    
    КодОтвета = HTTP.Status;
    ТекстОтвета = HTTP.ResponseText;
    
    Сообщить("Код ответа сервера: " + КодОтвета);
    Если КодОтвета = 200 Тогда
        // Обработка успешного ответа
        Сообщить("Ответ сервера: " + ТекстОтвета);
    Иначе
        Сообщить("Ошибка сервера: " + HTTP.StatusText, "!");
    КонецЕсли;
Исключение
    Сообщить("Не удалось выполнить сетевой запрос: " + ОписаниеОшибки(), "!");
КонецПопытки;

Способ 4. Работа с XML через объект MSXML2.ServerXMLHTTP

Если веб-сервер возвращает структурированный ответ в формате XML, удобно использовать компонент MSXML2.ServerXMLHTTP. Он позволяет не только отправить данные, но и сразу получить готовый DOM-документ через свойство responseXML.


XMLHTTP = СоздатьОбъект("MSXML2.ServerXMLHTTP.6.0");
XMLHTTP.Open("POST", "https://example.com/api/send", 0);
XMLHTTP.SetRequestHeader("Content-Type", "text/xml; charset=utf-8");
XMLHTTP.Send(ТекстЗапросаXML);

Если XMLHTTP.Status = 200 Тогда
    ОтветDOM = XMLHTTP.ResponseXML;
    // Работа с узлами XML через DOM-модель
    Корень = ОтветDOM.documentElement;
    Если ПустоеЗначение(Корень) = 0 Тогда
        Сообщить("Корневой узел ответа: " + Корень.nodeName);
    КонецЕсли;
КонецЕсли;

Особенности чтения ответа в кодировке UTF-8

Обратите внимание: встроенный объект платформы Текст и его метод КодоваяСтраница() в 1С 7.7 поддерживают только однобайтовые кодировки (ANSI/Windows-1251 и DOS/CP866). Если сервер возвращает ответ в кодировке UTF-8, при открытии через Текст символы кириллицы отобразятся искаженными («кракозябрами»).

Для корректного чтения файлов в кодировке UTF-8 используйте объект ADODB.Stream:


Поток = СоздатьОбъект("ADODB.Stream");
Поток.Type = 2; // Текстовый режим
Поток.Charset = "utf-8";
Поток.Open();
Поток.LoadFromFile("D:\SERTHTTP\response.txt");
ТекстОтвета = Поток.ReadText();
Поток.Close();

Сообщить("Корректно прочитанный текст: " + ТекстОтвета);
← На главную