Как из 1С отправить файл на SFTP-сервер с помощью WinSCP?

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

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

Рассмотрим два основных способа решения этой задачи: через COM-объект WinSCP, который является более гибким и современным, и через вызов из командной строки, который может быть проще в первоначальной настройке.

Решение 1: Использование COM-объекта WinSCP (рекомендуемый способ)

Этот метод предполагает прямое взаимодействие с WinSCP из кода 1С через его .NET-сборку, что дает полный контроль над процессом, включая обработку ошибок. Разберем по шагам, что нужно сделать.

Шаг 1. Подготовка окружения

Прежде чем писать код, необходимо подготовить сервер, на котором будет выполняться выгрузка (обычно это сервер 1С:Предприятия). Без этих действий магия не случится.

  1. Установите WinSCP. Скачайте и установите последнюю версию WinSCP на сервер. Убедитесь, что во время установки был выбран компонент ".NET-сборка".
  2. Зарегистрируйте библиотеку winscpnet.dll. Это ключевой момент. Без регистрации 1С просто не увидит нужный COM-объект. Регистрацию нужно выполнить через командную строку, запущенную от имени администратора. Путь к утилите RegAsm.exe и к самой библиотеке может отличаться в зависимости от версии Windows и пути установки WinSCP.

    Выполните обе команды, чтобы зарегистрировать библиотеку для 32-битной и 64-битной архитектуры:

    
    C:\Windows\Microsoft.NET\Framework64\v4.0.30319\RegAsm.exe "C:\Program Files (x86)\WinSCP\winscpnet.dll" /codebase /tlb:WinSCPnet.tlb
    C:\Windows\Microsoft.NET\Framework\v4.0.30319\RegAsm.exe "C:\Program Files (x86)\WinSCP\winscpnet.dll" /codebase /tlb:WinSCPnet.tlb
    

Шаг 2. Получение отпечатка ключа хоста (SshHostKeyFingerprint)

При первом подключении к SFTP-серверу WinSCP запрашивает подтверждение ключа хоста, чтобы убедиться, что вы подключаетесь к подлинному серверу. В автоматическом режиме этот диалог не появится, и соединение просто оборвется. Чтобы этого избежать, нужно заранее узнать отпечаток ключа и передать его в параметрах подключения.

Как получить отпечаток:

Отпечаток выглядит примерно так: "ssh-rsa 2048 xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx". Он нам понадобится в коде.

Шаг 3. Написание кода в 1С

Теперь, когда окружение готово, можно приступать к написанию кода. Проанализируем основной алгоритм.

  1. Создаем COM-объекты. Нам понадобятся WinSCP.Session для управления сессией и WinSCP.SessionOptions для хранения параметров подключения.
  2. Заполняем параметры подключения. Указываем адрес сервера, порт, логин, пароль и, самое главное, полученный на предыдущем шаге отпечаток ключа хоста.
  3. Устанавливаем соединение. Вызываем метод Open у объекта сессии, передавая ему параметры.
  4. Отправляем файлы. Используем метод PutFiles, указывая путь к локальному файлу (Источник) и путь на удаленном сервере (Получатель).
  5. Проверяем результат и закрываем соединение. После отправки важно проверить результат на наличие ошибок с помощью метода Check и обязательно закрыть сессию методом Dispose.

Посмотрим на пример кода, который реализует этот алгоритм. Его можно использовать в обработке или регламентном задании.


Процедура ОтправитьФайлНаSFTP()

    Попытка
        // Шаг 1: Создаем COM-объекты
        Сессия = Новый COMОбъект("WinSCP.Session");
        ПараметрыПодключения = Новый COMОбъект("WinSCP.SessionOptions");

        // Шаг 2: Заполняем параметры подключения
        ПараметрыПодключения.Protocol = 3; // 3 соответствует протоколу SFTP
        ПараметрыПодключения.HostName = "адрес_вашего_сервера";
        ПараметрыПодключения.UserName = "имя_пользователя";
        ПараметрыПодключения.Password = "пароль";
        ПараметрыПодключения.PortNumber = 22; // Стандартный порт для SFTP
        
        // ВАЖНО: Указываем отпечаток ключа хоста, полученный ранее
        ПараметрыПодключения.SshHostKeyFingerprint = "ssh-rsa 2048 ...";

        // Шаг 3: Открываем сессию
        Сессия.Open(ПараметрыПодключения);

        // Шаг 4: Отправляем файл
        Источник = "C:\Temp\MyFile.zip"; // Полный путь к файлу, который отправляем
        Получатель = "/remote/path/MyFile.zip"; // Путь на удаленном сервере. Обратите внимание на слэши!
        
        РезультатПередачи = Сессия.PutFiles(Источник, Получатель);

        // Шаг 5: Проверяем результат
        РезультатПередачи.Check();
        
        Сообщить("Файл успешно отправлен!");

    Исключение
        Сообщить("Произошла ошибка при отправке файла: " + ОписаниеОшибки());
        
    КонецПопытки;

    // Обязательно закрываем сессию, даже если была ошибка
    Если Сессия <> Неопределено Тогда
        Сессия.Dispose();
    КонецЕсли;

КонецПроцедуры

Важный момент по поводу путей в PutFiles: будьте очень внимательны. Если в пути получателя указать только каталог (например, /remote/path/), WinSCP может скопировать весь каталог-источник, а не только файл. Всегда указывайте полный путь, включая имя файла на удаленном сервере.

Решение 2: Использование командной строки и КомандаСистемы()

Этот способ не требует регистрации DLL и может показаться проще. Его суть в том, чтобы запустить консольную версию WinSCP (WinSCP.com) с параметрами, которые указывают, что нужно сделать.

Шаг 1. Проверка окружения

Убедитесь, что на сервере 1С установлен WinSCP и путь к его исполняемым файлам (включая WinSCP.com) добавлен в системную переменную PATH, либо используйте полный путь к файлу в коде.

Также важно выяснить, от имени какого пользователя запущен сервер 1С (обычно это USR1CV8). У этого пользователя должны быть права на запуск приложений из командной строки и доступ к каталогам, где лежат файлы для отправки и куда будут писаться логи.

Шаг 2. Формирование командной строки в 1С

Мы сформируем одну длинную строку, которая будет содержать все команды для WinSCP.


Процедура ОтправитьФайлЧерезКоманднуюСтроку()

    ПутьКWinSCP = """C:\Program Files (x86)\WinSCP\WinSCP.com""";
    ИмяПользователя = "имя_пользователя";
    Пароль = "пароль";
    АдресСервера = "адрес_вашего_сервера";
    КлючХоста = "ssh-rsa 2048 ..."; // Тот же отпечаток ключа
    
    Источник = "C:\Temp\MyFile.zip";
    Получатель = "/remote/path/MyFile.zip";
    
    // Формируем строку команды
    КоманднаяСтрока = СтрШаблон("%1 /log=""C:\Temp\winscp.log"" /command " +
        """open sftp://%2:%3@%4/ -hostkey=""""%5"""""" " +
        """put ""%6"" ""%7"""" " +
        """exit""",
        ПутьКWinSCP,
        ИмяПользователя,
        Пароль,
        АдресСервера,
        КлючХоста,
        Источник,
        Получатель
    );

    // Для отладки можно сначала вывести команду в сообщение
    // Сообщить(КоманднаяСтрока);

    // Запускаем команду
    КомандаСистемы(КоманднаяСтрока);

КонецПроцедуры

Разберем параметры командной строки:

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

← К списку