При автоматизации обмена данными по протоколу SFTP разработчики часто используют консольную утилиту WinSCP. Типичная ситуация: код прекрасно отрабатывает при ручном запуске в интерактивном сеансе, но при переносе в регламентное задание (фоновый процесс) выполнение прерывается с ошибкой или вовсе «зависает». В этой статье мы разберем причины такого поведения и предложим надежные способы решения проблемы.
Разберем ситуацию, с которой столкнулся автор темы. В коде использовалось имя профиля (сохраненного подключения), созданного в графическом интерфейсе WinSCP:
ПутьWinSCP = "C:\Program Files (x86)\WinSCP\WinSCP.com";
ПрофильWinSCP = "favclient";
СтрокаПрограммы = """" + ПутьWinSCP + """" + " /console /command " + """option batch abort"" " + """open " + ПрофильWinSCP + """ " + """put " + Лок_ИмяФайла + " " + Внеш_ИмяФайла + """ " + """close"" ""exit""";
net = Новый COMОбъект("WScript.Shell");
Результат = net.Run(СтрокаПрограммы, 0, Истина);
Причина неудачи: WinSCP по умолчанию хранит профили подключений в реестре Windows в ветке HKEY_CURRENT_USER. Когда 1С запускает фоновое задание, оно выполняется от имени специальной системной учетной записи (например, USR1CV8). У этой учетной записи своя ветка реестра, в которой профиля favclient просто не существует. Программа пытается открыть несуществующее подключение и завершается с ошибкой.
Самый надежный способ заставить WinSCP работать в фоновом режиме — отказаться от именованных профилей и передавать все необходимые параметры (адрес сервера, логин, пароль) непосредственно в команде open. Рассмотрим, как изменить строку подключения, чтобы она стала универсальной:
// Вместо open favclient используем полный URL
СтрокаСоединения = "open sftp://ftp_user:password123@192.168.1.100/";
СтрокаПрограммы = """" + ПутьWinSCP + """" + " /console /command " + """option batch abort"" " + """" + СтрокаСоединения + """ " + """put " + Лок_ИмяФайла + " " + Внеш_ИмяФайла + """ " + """close"" ""exit""";
Проанализируем этот подход: теперь WinSCP не зависит от настроек конкретного пользователя Windows, так как все данные для авторизации передаются в явном виде.
Даже если вы указали верный логин и пароль, фоновое задание может зависнуть. Это происходит потому, что при первом подключении к новому серверу WinSCP запрашивает подтверждение безопасности: «Доверяете ли вы этому серверу (его SSH-ключу)?». В фоновом процессе некому нажать кнопку «Да», и выполнение останавливается.
Чтобы избежать этого, необходимо добавить ключ -hostkey или -certificate. Для полной автоматизации в тестовых или защищенных контурах часто используют «маскировку» проверки ключа, хотя с точки зрения безопасности правильнее указывать конкретный отпечаток ключа сервера:
Рассмотрим пример добавления параметров безопасности:
// Использование -hostkey="*" позволяет принимать любой ключ сервера автоматически
СтрокаСоединения = "open sftp://user:pass@IP/ -hostkey=""*""";
// Или если используется сертификат
СтрокаСоединения = "open sftp://user:pass@IP/ -certificate=""*""";
Важно помнить: использование звездочки * делает соединение уязвимым к атакам типа «человек посередине» (MITM). В промышленной эксплуатации лучше один раз получить отпечаток ключа сервера вручную и прописать его точно: -hostkey="ssh-rsa 2048 xx:xx:xx...".
Если WScript.Shell возвращает Результат = 1, это говорит лишь о факте ошибки, но не о её причине. Чтобы выяснить корень зла, проанализируем возможности логирования WinSCP. Добавим в параметры запуска ключ /log:
ПутьКЛогу = "C:\Logs\winscp_log.txt";
СтрокаПрограммы = """" + ПутьWinSCP + """" + " /log=""" + ПутьКЛогу + """ /loglevel=0 /command ...";
Важный нюанс: Убедитесь, что у учетной записи, под которой работает служба 1С (например, USR1CV8), есть права на запись в папку C:\Logs\. Если прав не будет, лог не создастся, и вы не сможете прочитать сообщение об ошибке.
Для того чтобы «поймать» момент выполнения кода в фоне, воспользуемся стандартными средствами платформы:
/debug в строке запуска службы 1С).СтрокаПрограммы.Теперь, когда регламентное задание запустится, отладчик 1С автоматически остановится на нужной строке, и мы сможем проверить содержимое переменной СтрокаПрограммы на наличие лишних кавычек или ошибок в путях.
Если работа через WScript.Shell и формирование длинных текстовых команд кажется слишком громоздкой, рассмотрим вариант использования WinSCP .NET Assembly. Это библиотека, которую можно подключить к 1С как COM-объект. Это дает ряд преимуществ:
Попытка ... Исключение.WinSCP.com.Пример логики работы через сборку:
// Примерный алгоритм
SessionOptions = Новый COMОбъект("WinSCP.SessionOptions");
SessionOptions.Protocol = Protocol_Sftp;
SessionOptions.HostName = "192.168.1.100";
SessionOptions.UserName = "user";
SessionOptions.Password = "pass";
SessionOptions.GiveUpSecurityAndAcceptAnySshHostKey = Истина;
Session = Новый COMОбъект("WinSCP.Session");
Session.Open(SessionOptions);
// Далее выполнение методов PutFiles и т.д.
Для стабильной работы SFTP в фоновых процессах 1С необходимо придерживаться следующих правил:
open.-hostkey, чтобы WinSCP не ждал интерактивного подтверждения.Соблюдение этих рекомендаций позволит сделать ваши интеграции по SFTP надежными и прозрачными для мониторинга.