Как в 1С отслеживать изменение внешнего файла и получать результат работы сторонних утилит

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

При интеграции 1С с внешними системами (например, банковскими терминалами, утилитами СБП или P2P-переводами Сбера) программисты часто сталкиваются с проблемой: внешнее приложение запускается, выполняет операцию, но не возвращает результат напрямую в 1С. Вместо этого результат записывается в текстовый лог-файл. В данной статье мы подробно разберем, как научить 1С «понимать», что файл изменился, и как правильно организовать ожидание ответа от стороннего ПО.

Метод 1. Использование встроенных функций ожидания завершения процесса

Если внешняя утилита закрывается сразу после завершения операции, самым простым и надежным способом будет использование встроенных средств платформы 1С. Вместо использования COM-объекта WScript.Shell, рассмотрим использование метода ЗапуститьПриложение. Этот метод позволяет приостановить выполнение кода 1С до тех пор, пока внешнее приложение не закончит свою работу.

Проанализируем пример реализации:


ПараметрыЗапуска = ДиректорияПрограммы + " /new """ + НомерОрдера + """";
КодВозврата = 0;
// Третий параметр "Истина" означает ожидание завершения приложения
ЗапуститьПриложение(ПараметрыЗапуска, , Истина, КодВозврата);

// После завершения программы читаем лог
Если КодВозврата = 0 Тогда
    ТекстЛога = Новый ТекстДокумента;
    ТекстЛога.Прочитать(ПутьКФайлуЛога);
    // Обрабатываем результат
КонецЕсли;

Важный нюанс: как отметили участники обсуждения, современные асинхронные вызовы в управляемом приложении требуют использования ЗапуститьПриложениеАсинх. Это позволяет не блокировать интерфейс пользователя, пока длится транзакция (которая может занимать до 9 минут).

Метод 2. Отслеживание изменения файла через контрольную сумму (Polling)

В ситуациях, когда внешняя программа не закрывается или 1С должна реагировать на промежуточные записи в логе, мы не можем просто «ждать завершения». В этом случае нам необходимо организовать периодический опрос файла. Рассмотрим способ проверки изменения файла через расчет хеш-суммы (SHA256). Этот метод точнее, чем проверка даты изменения, так как дата может обновиться без изменения содержимого.

Разберем алгоритм по шагам:

  1. Запускаем внешнюю утилиту.
  2. Запоминаем текущую контрольную сумму файла лога.
  3. Подключаем обработчик ожидания, который раз в несколько секунд будет проверять файл.

Пример функции для расчета хеш-суммы:


Функция ПолучитьХешФайла(ПутьКФайлу) Экспорт
    Файл = Новый Файл(ПутьКФайлу);
    Если Не Файл.Существует() Тогда
        Возврат "";
    КонецЕсли;
    
    ДвоичныеДанные = Новый ДвоичныеДанные(ПутьКФайлу);
    Хеширование = Новый ХешированиеДанных(ХешФункция.SHA256);
    Хеширование.Добавить(ДвоичныеДанные);
    Возврат СтрЗаменить(Строка(Хеширование.ХешСумма), " ", "");
КонецФункции

В обработчике ожидания сравним полученный хеш с предыдущим значением. Если они различаются — файл был дополнен новой информацией, и мы можем начать парсинг текста.

Метод 3. Мониторинг через системные события (WMI и API ОС)

Для более продвинутых решений, когда недопустимы лишние циклы опроса, можно рассмотреть использование подписок WMI (Windows Management Instrumentation). Это позволяет операционной системе самой уведомлять 1С о событии изменения файла. Рассмотрим, как это работает концептуально.

Выполнение запроса через WMI выглядит как работа с базой данных событий ОС. Мы создаем подписку на изменение объекта типа CIM_DataFile. Однако стоит учитывать, что работа с WMI напрямую из 1С через COMОбъект("winmgmts:") требует специфических прав доступа и определенных навыков системного программирования. Для большинства бизнес-задач этот метод является избыточным, но он незаменим при высоконагруженном мониторинге файловой системы.

Метод 4. Чтение стандартного потока вывода (Stdout)

Если утилита Сбера является консольным приложением, мы можем попытаться перехватить данные еще до того, как они попадут в файл лога. При использовании WScript.Shell метод Exec возвращает объект, у которого есть поток StdOut.

Рассмотрим пример кода:


WshShell = Новый COMОбъект("WScript.Shell");
Процесс = WshShell.Exec(КомандаЗапуска);

Пока Процесс.Status = 0 Цикл // Пока процесс запущен
    Если Не Процесс.StdOut.AtEndOfStream Тогда
        СтрокаВывода = Процесс.StdOut.ReadLine();
        // Сразу анализируем строку в 1С
    КонецЕсли;
КонецЦикла;

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

Рекомендации по обработке ошибок доступа

Проанализируем типичную ошибку: внешняя программа держит файл лога открытым для записи, и 1С не может его прочитать (ошибка «Файл занят другим процессом»). Чтобы избежать этой ситуации, следуйте правилам:

Заключение

Мы рассмотрели несколько способов мониторинга внешних данных: от простых встроенных функций 1С до низкоуровневых системных механизмов. Для интеграции с банковским ПО наиболее сбалансированным решением будет использование асинхронного запуска с обработчиком ожидания и проверкой даты или хеша файла. Это обеспечит стабильную работу интерфейса и гарантированное получение результата транзакции.

← На главную