Доброго времени суток форумчане.
Т.к. я не особо люблю и не умею писать статьи, а поделиться хочется, пишу сюда свою реализацию выгрузки файлов на sftp.
Работать должна на любых платформах 1С. Я лично выполнял на 1С УТ 11.3.17.1851.
Основная задача для меня - это избежать дополнительных настроек на сервере (не хотелось устанавливать WinScp и регистрировать различные COM объекты).
Что я сделал:
1) Создал справочник "Хранилище файлов" у него два реквизита (наименование - это строка, Хранилище - это ХранилищеЗначения);
2) Написал простенькую консольную программу на .NET(С#). Ссылку для скачивания прилагаю ниже
Мой github
3) В репозиторий описано как пользоваться утилитой + исходники все в открытом доступе. Там в принципе ни чего гениального);
4) Загружаю полученные exe и dll в "Хранилище файлов". Обязательно наименование dll нужно указать то, которое у вас получиться при компиляции моей утилиты (пункт 2). В результате у нас в 1С будут храниться двоичные данные sftp_client.exe и Renci.SshNet.dll. Мы сможем при необходимости выгружать их на локальный компьютер.
5) Собственно код ниже:
Функция ВыгрузитьНаSFTP(сервер, логин, пароль, директория, ИмяФайла, ПолноеИмяФайла = "", ДД = Неопределено) Экспорт
РезультатФункции = 0;
ЛокальныйПривилегированныйРежим = Ложь;
Если Не ПривилегированныйРежим() Тогда
УстановитьПривилегированныйРежим(Истина);
ЛокальныйПривилегированныйРежим = ПривилегированныйРежим();
КонецЕсли;
Продолжать = Ложь;
Если ЗначениеЗаполнено(ПолноеИмяФайла) Тогда
Файл = Новый Файл(ПолноеИмяФайла);
Если Файл.Существует() Тогда
Продолжать = Истина;
КонецЕсли;
КонецЕсли;
Если Не Продолжать Тогда
ПолноеИмяФайла = КаталогВременныхФайлов() + ИмяФайла;
Если ДД <> Неопределено Тогда
ДД.Записать(ПолноеИмяФайла);
Файл = Новый Файл(ПолноеИмяФайла);
Если Файл.Существует() Тогда
Продолжать = Истина;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если Продолжать Тогда
СтрокаКоманды = " """ + сервер + """" +
" """ + логин + """" +
" """ + пароль + """" +
" """ + директория + """" +
" """ + ПолноеИмяФайла + """";
Структура = ВыгрузитьДопУтилиты();
Если Не Структура.Ошибка Тогда
КодВозврата = 0;
Результат = МОЕ_ЗапуститьПриложение(СтрокаКоманды, Структура.ИсполняемыйФайл,, Истина, КодВозврата);
Если Не Результат ИЛИ КодВозврата <> 0 Тогда
// 0 - все ок, 1 - не подключился к SFTP, 2 - не найден файл, -1 - не отслеживаемая ошибка
Если Не Результат Тогда
РезультатФункции = -1;
Иначе
РезультатФункции = КодВозврата;
КонецЕсли;
КонецЕсли;
Иначе
Сообщить(Структура.ТекстОшибки);
КонецЕсли;
КонецЕсли;
Если ЛокальныйПривилегированныйРежим Тогда
УстановитьПривилегированныйРежим(Ложь);
КонецЕсли;
Возврат РезультатФункции;
КонецФункции
Функция МОЕ_ЗапуститьПриложение(СтрокаКоманды, ИсполняемыйФайл = Неопределено, ТекущийКаталог = "", ДождатьсяЗавершения = Ложь, КодВозврата = Неопределено)
РезультатФункции = Истина;
ЛокальныйПривилегированныйРежим = Ложь;
Если Не ПривилегированныйРежим() Тогда
УстановитьПривилегированныйРежим(Истина);
ЛокальныйПривилегированныйРежим = ПривилегированныйРежим();
КонецЕсли;
ТекСтрокаКоманды = СтрокаКоманды;
Если ИсполняемыйФайл <> Неопределено Тогда
Файл = Новый Файл(ИсполняемыйФайл);
Если Файл.Существует() Тогда
ТекСтрокаКоманды = "" + ИсполняемыйФайл + ТекСтрокаКоманды;
Иначе
РезультатФункции = Ложь;
КонецЕсли;
КонецЕсли;
Если РезультатФункции Тогда
Попытка
ЗапуститьПриложение(ТекСтрокаКоманды, ТекущийКаталог, ДождатьсяЗавершения, КодВозврата);
Исключение
РезультатФункции = Ложь;
КонецПопытки;
КонецЕсли;
Если ЛокальныйПривилегированныйРежим Тогда
УстановитьПривилегированныйРежим(Ложь);
КонецЕсли;
Возврат РезультатФункции;
КонецФункции
Функция ВыгрузитьДопУтилиты()
РезультатФункции = Новый Структура;
РезультатФункции.Вставить("ИсполняемыйФайл", "");
РезультатФункции.Вставить("Ошибка", Ложь);
РезультатФункции.Вставить("ТекстОшибки", "");
ЛокальныйПривилегированныйРежим = Ложь;
Если Не ПривилегированныйРежим() Тогда
УстановитьПривилегированныйРежим(Истина);
ЛокальныйПривилегированныйРежим = ПривилегированныйРежим();
КонецЕсли;
ИсполняемыйФайл = Неопределено;
ХранилищеМассивСсылок = ПолучитьХранилищеФайлов(); // Тут я получаю массив справочников "Хранилище файлов" запросом (ссылка на Renci.SshNet.dll и ссылка на sftp_client.exe)
Для каждого ХранилищеСсылка из ХранилищеМассивСсылок Цикл
Если ЗначениеЗаполнено(ХранилищеСсылка) Тогда
РасширениеВременногоФайла = ПолучитьРасширение(ХранилищеСсылка); // Получаем нужное расширение
ИмяФайла = ПолучитьИмяФайлаХранилища(ХранилищеСсылка, РасширениеВременногоФайла); // Получаем имя файла можно и статично задать sftp_client.exe и Renci.SshNet.dll
ИмяВременногоФайла = КаталогВременныхФайлов() + ИмяФайла;
МОЕ_СохранитьФайлНаДиск(ИмяВременногоФайла, ХранилищеСсылка);
Если РасширениеВременногоФайла = "exe" Тогда
РезультатФункции.ИсполняемыйФайл = ИмяВременногоФайла;
КонецЕсли;
Иначе
РезультатФункции.Ошибка = Истина;
РезультатФункции.ТекстОшибки = "ОШИБКА: Хранилище пустое!";
КонецЕсли;
КонецЦикла;
Если ЛокальныйПривилегированныйРежим Тогда
УстановитьПривилегированныйРежим(Ложь);
КонецЕсли;
Возврат РезультатФункции;
КонецФункции
Процедура МОЕ_СохранитьФайлНаДиск(ИмяВнешнегоФайла, ХранилищеСсылка)
ЛокальныйПривилегированныйРежим = Ложь;
Если Не ПривилегированныйРежим() Тогда
УстановитьПривилегированныйРежим(Истина);
ЛокальныйПривилегированныйРежим = ПривилегированныйРежим();
КонецЕсли;
Если Не ПустаяСтрока(ИмяВнешнегоФайла) Тогда
ВнешнийФайл = ХранилищеСсылка.Хранилище.Получить();
Если ВнешнийФайл <> Неопределено Тогда
ВнешнийФайл.Записать(ИмяВнешнегоФайла);
КонецЕсли;
КонецЕсли;
Если ЛокальныйПривилегированныйРежим Тогда
УстановитьПривилегированныйРежим(Ложь);
КонецЕсли;
КонецПроцедуры