При интеграции 1С со сторонними серверами по защищенному протоколу SFTP разработчики часто используют библиотеку WinSCP через COM-соединение. Штатный объект платформы FTPСоединение поддерживает работу только с FTP и FTPS, поэтому для SSH File Transfer Protocol требуется внешнее решение.
На этапе создания параметров сессии в объекте WinSCP.SessionOptions возникает распространенная ошибка: попытка присвоить свойству Protocol строковое значение вида "Protocol.Sftp" или "SFTP" приводит к исключению времени выполнения. Разберем причины такого поведения и рассмотрим правильные варианты настройки подключения.
Библиотека WinSCPnet.dll представляет собой .NET-сборку. В исходном коде библиотеки протокол определен как перечисление enum Protocol:
namespace WinSCP
{
public enum Protocol
{
Sftp = 0,
Scp = 1,
Ftp = 2,
Webdav = 3
}
}
Среда 1С:Предприятие при обращении к внешним COM-объектам не может напрямую оперировать типами данных .NET или вызывать статические свойства перечислений. В COM-модели все значения enum транслируются в обычные целые числа. Передача строки вызывает ошибку несовпадения типов.
Самый простой и надежный способ — передать в свойство Protocol целочисленный идентификатор нужного протокола.
Sftp (SFTP — SSH File Transfer Protocol);Scp (SCP — Secure Copy Protocol);Ftp (FTP — File Transfer Protocol);Webdav (WebDAV).Посмотрим на практический пример инициализации параметров сессии:
sessionOptions = Новый COMОбъект("WinSCP.SessionOptions");
sessionOptions.Protocol = 0; // Указываем SFTP числом
sessionOptions.HostName = "example.com";
sessionOptions.UserName = "user";
sessionOptions.Password = "mypassword";
sessionOptions.SshHostKeyFingerprint = "ssh-rsa 2048 xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx";
Полезный нюанс: в объекте WinSCP.SessionOptions значение по умолчанию для свойства Protocol уже равно 0 (SFTP). Если вам необходимо установить именно SFTP-соединение, строку с явной установкой протокола можно вовсе опустить.
Если параметры подключения хранятся в конфигурации в виде единой строки URL или формируются динамически, можно использовать встроенный метод ParseUrl объекта SessionOptions. Этот метод автоматически распознает протокол из схемы URL и заполняет соответствующие поля.
Разберем пример использования метода ParseUrl:
sessionOptions = Новый COMОбъект("WinSCP.SessionOptions");
sessionOptions.ParseUrl("sftp://user:mypassword@example.com/");
// Дополнительно задаем отпечаток ключа хоста для SFTP
sessionOptions.SshHostKeyFingerprint = "ssh-rsa 2048 xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx";
Рассмотрим комплексный пример: создание сессии, подключение к серверу, выгрузку файла и корректное освобождение системных ресурсов.
ПараметрыСессии = Новый COMОбъект("WinSCP.SessionOptions");
ПараметрыСессии.Protocol = 0;
ПараметрыСессии.HostName = "example.com";
ПараметрыСессии.UserName = "user";
ПараметрыСессии.Password = "mypassword";
ПараметрыСессии.SshHostKeyFingerprint = "ssh-rsa 2048 xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx";
Сессия = Новый COMОбъект("WinSCP.Session");
Попытка
Сессия.Open(ПараметрыСессии);
ПараметрыПередачи = Новый COMОбъект("WinSCP.TransferOptions");
ПараметрыПередачи.TransferMode = 0; // 0 = Binary, 1 = Ascii, 2 = Automatic
РезультатПередачи = Сессия.PutFiles("C:\Export\data.xml", "/remote/path/data.xml", Ложь, ПараметрыПередачи);
РезультатПередачи.Check(); // Вызовет исключение в случае ошибки передачи
Сессия.Dispose();
Исключение
Если Сессия <> Неопределено Тогда
Сессия.Dispose();
КонецЕсли;
ВызватьИсключение "Ошибка работы с SFTP через WinSCP: " + ОписаниеОшибки();
КонецПопытки;
Чтобы интеграция работала стабильно, необходимо учитывать несколько ключевых системных требований:
WinSCPnet.dll нельзя зарегистрировать стандартной утилитой regsvr32. Для регистрации сборки в реестре Windows используется утилита RegAsm.exe из состава .NET Framework с ключами /codebase /tlb. Разрядность утилиты RegAsm (32-bit или 64-bit) должна строго соответствовать разрядности процесса 1С (клиента 1cv8.exe или рабочего процесса сервера rphost.exe).WinSCPnet.dll является программной оберткой. В одном каталоге с DLL обязательно должен располагаться исполняемый файл WinSCP.exe (либо путь к нему передается в свойство Session.ExecutablePath).WinSCP.Session запускает отдельный системный процесс WinSCP.exe. После завершения операций обязательно вызывайте метод Сессия.Dispose() в блоке Исключение или финальной части алгоритма. В противном случае фоновые процессы зависают в памяти сервера, что приводит к утечке системных дескрипторов при выполнении регламентных заданий.Session.ScanFingerprint(SessionOptions, "SHA-256"). Для тестовых сред проверку можно отключить свойством SessionOptions.GiveUpSecurityAndAcceptAnySshHostKey = Истина.WinSCP.com, curl или клиент sftp через метод ЗапуститьПриложение().