К сожалению, большинство из них написано на технологии .COM и не могут использоваться на сервере.
Для использования в регламентных заданиях серверной базы их приходится переписывать на Native API.
Однако, иногда нет возможности переписать компоненту на новую технологию, но нужно вызвать ее в регламентном задании на сервере.
Например, не получится переписать компоненту, если вы не её автор и исходников просто нет. Либо если для ее работы недостаточно поддерживаемых технологией Native API простейших типов (число, строка, булево, дата).
При работе с файловой базой особых проблем нет. Регламентное задание вызывается в фоновом процессе обычного пользователя. Поэтому ему доступны клиенские вызовы. В серверной базе при запуске регламентного задания клиентского контекста нет, соответственно вызов ПодключитьВнешнююКомпоненту() недоступен.
Подробнее о том, почему недоступен, можно почитать на ИТС.
В этом случае можно вызывать компоненту на клиенте. Для этого достаточно выполнить из регламентного задания на сервере запуск еще одного сеанса 1С в котором на клиенте выполнить нужные действия. Ну и не забыть потом завершить запущенный сеанс.
Допустим, у нас в регламентном задании выполняется формирование и сохранение отчета, использующего для склонения ФИО внешнюю COM-компоненту NameDeclension.dll. На файловой базе такое регламентное задание будет работать корректно, на серверной компоненту подключить не получится.
Для устранения проблемы добавим в модуль регламентных заданий процедуру, которая в серверном режиме запустит еще один сеанс и в нем выполнит из внешней обработки вызов формирования отчета на клиенте.
#Если Клиент Тогда
Процедура ВыполнитьФормированиеИСохранениеОтчета() Экспорт
Если ПодключитьВнешнююКомпоненту("ОбщийМакет.NAMEDECL","Скл",ТипВнешнейКомпоненты.COM) Тогда
Компонента = Новый ("AddIn.Скл.NameDeclension");
//Тут код формирования и сохранения отчета
Иначе
ЗаписьЖурналаРегистрации("РеглЗадания", УровеньЖурналаРегистрации.Ошибка,,,
"Не удалось подключить внешнюю компоненту на клиенте");
КонецЕсли;
КонецПроцедуры
#Иначе
Процедура ВыполнитьФормированиеИСохранениеОтчета() Экспорт
ВыполнитьОперациюНаКлиенте("РеглЗадания.ВыполнитьФормированиеИСохранениеОтчета()");
КонецПроцедуры
Процедура ВыполнитьОперациюНаКлиенте(ПараметрДляВыполнения) Экспорт
ИмяПользователя = "";
ПарольПользователя = "";
ПутьКВнешнейОбработке = "c:/temp/Автозапуск.epf";
Кавычка = """";
КаталогBIN = КаталогПрограммы();
ПутьККонфигурации = СтрокаСоединенияИнформационнойБазы();
ПутьККонфигурации = СтрЗаменить(ПутьККонфигурации, Кавычка, Кавычка + Кавычка);
СтрокаЗапуска = Кавычка + КаталогBIN + "1cv8.exe" + Кавычка + " ENTERPRISE"
+ " /IBConnectionString " + Кавычка + ПутьККонфигурации + Кавычка
+ " /N " + Кавычка + ИмяПользователя + Кавычка
+ " /P " + Кавычка + ПарольПользователя + Кавычка
+ " /Execute " + Кавычка + ПутьКВнешнейОбработке + Кавычка
+ " /C " + Кавычка + ПараметрДляВыполнения + Кавычка;
ЗапуститьПриложение(СтрокаЗапуска);
КонецПроцедуры
#КонецЕсли
Код внешней обработки, которая просто вызовет в контексте клиента печать нужного отчета из модуля регламентных заданий и завершит сеанс после формирования отчета.
Попытка
Выполнить(ПараметрЗапуска);
Исключение
КонецПопытки;
ЗавершитьРаботуСистемы(Ложь);
Удобство решения в том, что при настройке регламентных заданий не важно, в каком режиме будет выполняться запуск задания. Если база файловая, то сразу запустится нужная процедура. Если база серверная и при запуске клиентский контекст отсутствует, то выполнится инициализация нового сеанса и в нем процедура корректно отработает в контексте клиента.
Код для обычного приложения. Теоретически полностью аналогично будет работать и в управляемом.
p.s. Также этот подход можно использовать для выполнения любых клиентских процедур в регламентных заданиях.
Гм.. А что насчет лицензий? Какой-то не очень дешевый способ обхода, если на каждого юзера по доп.лицензии надобно.. Да и старт-стоп клиента на сервере — тоже не самый безнакладный процесс..Эт прям вот оооочень сильно надо захотеть именно эту компоненту запустить..
(1) AlX0id, В данном случае речь в основном о кратковременном регламентном запуске процедур. Например, выгрузка отчетов, синхронизация с АТС, выгрузка/загрузка данных на сайт, считка информации со стороннего железа/сервисов. С точки зрения лицензий проблем не вижу. Лицензия занимается исключительно на время выполнения операции — в большинстве случаев несколько минут. Запуск и завершение сеанса тоже никакой особой загрузки не создает.
Конечно, это не идеальное решение. Скорее костыль, но вполне универсальный и стабильно работающий.
По опыту скажу, все ситуации, когда надо было использовать клиентский функционал на сервере можно переработать / переосмыслить таким образом, что это не требуется.
Использование запуска клиентских сессий на сервере еще чревато тем, что есть вероятность получения модального окна и зависшей сессии.
(3) theshadowco, Как ни переосмысливай, .COM — компоненты банально не работают на сервере. Альтернатив иногда нет. Проблемы с зависшими сеансами возможны. Но вообще от кода зависит. Если написан корректно, то никаких модальных окон там нет. У нас были периодически такие зависания, но именно из проблем с внешними системами. Решали выполнением при старте обработки автозавершения через обращение к кластеру всех сеансов текущего пользователя старше одного часа. Разумеется, пользователь отдельный именно для регламентных заданий.
А сделать DCOM ну или на край .NET обёртку не?
(5) comol, В смысле обёртку, которая будет обращаться к .dll а сама подключаться к 1С как Native API ? Или что-то другое имелось в виду?
Теоретически тоже возможно. Из минусов, появляется дополнительная прослойка и необходимость сериализации/десериализации данных, если для них простых типов Native API недостаточно.
Но лично я не умею такие обёртки писать, необходимости пока не было.
Самый большой минус технологии СOM — одноплатформенность. Как только у вас появляется сервер на Linux, о технологии COM приходится забыть.
(4)
Вот те на. Всю жизнь обмен через COM-соединение отлично работал на сервере, а тут оказывается что он «банально не работает». Это как?
UPD.
Может я действительно чего-то не понимаю, но в чем собственно проблема?
(8) yukon, Добро пожаловать в клиент-серверную архитектуру 🙂
Не подключаются на сервере com-компоненты. Уже очень давно.
Работают в файловой базе, так как доступен толстый клиент. Но не в серверной.
32.3. Особенности работы на сервере
При работе на сервере «1С:Предприятия» допустимо использовать только компоненты, разработанные по технологии Native API, которые могут быть как отдельными файлами, так и упакованными в специальные ZIP-архивы.
В СП описано 2 варианта подключения. Первый только для Native API. Второй для любых.
Но:
Описание варианта метода:
Компонент должен быть выполнен по технологии COM и зарегистрирован в реестре MS Windows.
Эти компоненты совместимы с компонентами 1С:Предприятия 7.7.
Внимание! Вариант метода не работает на сервере и во внешнем соединении.
В документации на ИТС по ссылке выше подробнее.
(8) yukon, Обмен через COM- соединение Вы имеете в виду подключение через comcntr.dll?
Оно работает корректно.
Это не внешняя компонента для 1С, это компонента для Виндовс.
Она не просто загружается в 1С, а устанавливается в Виндовс через службы компонентов.
Не могу объяснить, в чем разница, но технология другая.
Возможно, кто-то другой по принципу ее работы подскажет.
(10)
Все понятно. Действительно, компоненты в «старом» формате на сервере недоступны. В общем-то они могут регистрироваться через regsvr32 (увы, необязательно), а далее через Новый COMОбъект.
А вот с теми кто не может регистрироваться придется держать отдельного клиента, который через обработку ожидания будет выполнять действия. Ваш вариант решает, конечно, задачу, но уж сильно «костыльно».
(11) yukon, Насколько я понимаю, внешние компоненты не могут использоваться на сервере независимо от того, зарегистрированы ли они через regsvr32. Т.е. это принципиальное ограничение. Они просто не подключаются в 1С.
Возможно, чего-то не учитываю и есть нюансы.
По comcntr.dll мне самой хотелось бы понять, как она работает. Но информации не нашла.
(4) в 1С зависшие сессии вообще беда, у нас при одновременной работе более 150 человек постоянно появляются зависшие сеансы и блокировки базы, бороться с этим очень сложно…
Я так понимаю автор имел ввиду — что не работают некоторые com.
Может автор 32 битную запускает ? Или с визуализацией ?
Вообще что это было ?
У нас используется много разных com на сервере — и все прекрасно работает и при очень большой нагрузке
(14) kiruha, Мы говорим о внешних компонентах, выполненных по технологии .COM
Которые подключаются с использованием синтаксиса ПодключитьВнешнююКомпоненту().
О том, почему они не работают, описано выше в комментариях и по ссылкам на ИТС.
Спасибо за идею. Попробую решить одну задачку. Смысл ее в том что бы по заданию подключиться по COM к бухгалтериям и получить данные в отчет, и отчет разослать по списку. В клиенте все нормально, а вот в регламентном задании — швах.
Мне кажется, нет смысла делать ВК в технологии COM. Лучше тогда делать и использовать просто COM.
Интересный пример, но немного не удачный. ВыполнитьПечатьОтчета — из принтера на сервере выведет? Мне бы отчет на моем принтере нужен, а на сервере вообще принтер не подключен. Это только в обычном приложении контекст клиента и сервера выполняется на юзерском компе, для совместимости с управляемым.
И во многих случаях проблемы использования com-компонент вызваны особенностями разрядности Windows (х32, х64) а не контекстом выполнения.
(18) adapter, Тут речь о регламентных операциях, которые используют именно инфраструктуру сервера. Немного поменяла название процедуры в коде, чтобы было понятнее.
Разрядности Windows (х32, х64) это отдельная история. Но по ней уже вроде достаточно информации. Как именно оборачивать компоненту, чтобы она работала на Виндовс с другой разрядностью. Эту тему уже много раз поднимали.
(10) Возможно, кто-то другой по принципу ее работы подскажет.
А всё достаточно просто:
COM объект — самостоятельная программа, предоставляющая для работы с ней свои интерфейсы, через которые программы, поддерживающие технологию COM (теперь уже принято её ActiveX называть) могут обращаться к его свойствам и методам..
А вот внешняя COM компонента — это вспомогательная программа (плагин для 1С), которая взаимодействует с 1С, через только через интерфейсы, предоставляемые самой системой 1С:Предприятие. Ну и, соответственно наша внешняя COM компонента — плагин может быть запущена только в рабочем процессе 1С Предприятия.
А вариант с подключением через com к 1С — там (внешнее соединение) компоненты тоже не работают ?
Чтобы не запускать еще один сеанс в конфу добавляется «внутренняя» обработка с макетом, в котором двоичные данные из DLL. Потом все нормально подключается на сервере без проблем: Из внешней обработки подключение DLL невозможно, обязательно нужно вшивать в конфу, если хотите пользоваться «Native» компонентой.
(22) Nebiros777, С Native компонентами проблем никаких нет. Они отлично подключаются на сервере и без встраивания макетов.
Проблема только с .COM компонентами
(21) kiruha, с .com подключение К 1С проблем нет. Выше уже обсудили почему.
А почему тогда нельзя просто
(24) kiruha, Потому что МояПроцедураСВнешнейКомпонентойВнутри() не сможет использовать внешнюю компоненту на сервере.
Абсолютно пофиг, вызывается она снаружи или изнутри.
Она вызывает ее во внешнем соединении а не на сервере.
Есть dll которую можно скачать и проверить ?
(26) kiruha, Та копонента, что у меня в примере.
http://manual1c.ru/sklonenie-familii-imeni-i-otchestva-po-padezham-v-1s-8-2/
Где-то уже есть ее Native аналог, но эта вроде как раз .COM
Попробуйте подключить в регламентном задании на сервере (не в толстом клиенте)
Com сессия прекрасно вызвалась из под сервера, в отладчике показывается как внешнее соединение, но подключить внешнюю компоненту в этой сессии не удалось.
По какой причине не понял
Так что ваш метод пока единственный )
(28) kiruha, В режиме внешнего соединения нет клиентского контекста. Соответственно и .com компоненты не подключаются.
Народ, что же вы все уперлись в вырывание гланд через задний проход??? Ну если все равно придется запустить клиентский сеанс, тогда зачем его запускать через
жопусервер? Запустите вместо регламентного задания клиентский сеанс, используя внешний планировщик (да хоть встроенный Windows)(0) лучше использовать
Подскажите плиз…раньше свои внешние компоненты (COM) использовал в 1c8.2
там строка была Компонента = Новый («AddIn.SW»);
сейчас в 1с8.3 (управляемая форма) надо писать как тут описано в примере
Компонента = Новый («AddIn.Скл.NameDeclension»);
Вот интересует NameDeclension — что это такое? откуда брать?
А зачем ВК на сервере? Смысл ВК в событиях, окнах и доступе к глобальному контекста 1С.
http://infostart.ru/public/238584/
Используй COM. А например используя Библиотеки Net ты можешь написать, что угодно
Вот библиотека склоненияhttp://yeaahcode.blogspot.ru/2015/01/lingvonet.html
На самом деле интерес представляет Com объект который внутри будет вызывать методы IlanguageExtender
http://infostart.ru/public/345658/ только в обратную сторону.
На подобии
А твой подход я применял еще в 8.1 для сохранения в эксель итд
(32) zaverax, Это стандартная компонента для склонения.
«NameDeclension» это прописанное в ней имя.
Вообще если пишите сами, то лучше переделать сразу правильно на Native.
Будет стабильнее работать и удобнее.
Указанный в статье подход можно использовать исключительно если есть старая уже готовая компонента и нет возможности ее изменить (т.е. компонента чужая и банально нет исходников или специалистов по ней).
(35)
а есть пример написания COM и Native в Delphi?
у меня в делфи вот так описано CreateAddIn(‘sw’, ObjectGUID, TDM1,’AddInFPList’);
в 1с8 вызывал Компонента = Новый («AddIn.SW»);
если теперь вызываю Компонента = Новый («AddIn.SW.TDM1»); — то ошибка Тип не определен…
ПодключитьВнешнююКомпоненту(<Местоположение>, <Имя>, <Тип>)
Вот Имя и будет вторым после Addin
(0) Проблема еще в том, сами ВК 32 разрядные.
http://infostart.ru/public/238584/ есть пример обмена данными по TCP/IP
Кстати в
Смысл в том, что экономишь на запуске 1С, компоненты итд.
А так созданшь обработку, в которой запускаешь Tcp/IP клиента и обмениваешься данными.
Аналогичный обмен здесь
http://infostart.ru/public/434771/
(37) Serginio,
меня интересует что должно быть написано третим…AddIn.SW.хххххх — вместо ххххххх
что за класс?
CreateAddIn(‘sw’, ObjectGUID, TDM1,’AddInFPList’)….TDM1 — это класс который создается…но если я его подставляю в 1С то ошибка Тип не определен…
(36) zaverax, Тут не подскажу, к сожалению.
С нюансами разработки и регистрации внешних компонент я знакома плохо.
То, что ты задаешь в RegisterExtensionAs
http://habrahabr.ru/post/191014/
Никто не заметил комментария (31) ПрекратитьРаботуСистемы
Завершает работу системы не зависимо от наличия модальных диалогов, открытых редактируемых форм документов и справочников и т.д. При этом не вызываются процедуры-обработчики событий завершения работы системы.
(42) kiruha, (31) jan27,
Да, пожалуй, ПрекратитьРаботуСистемы() надежнее.
У меня ЗавершитьРаботуСистемы() тоже вполне хватало.
Беда в том, что такой запуск клиента из фонового задания не работает.
У меня внешняя dll с com-объектами, через которую надо подключиться к сторонней базе (не 1С) и забрать некоторые данные.
Хотел делать это в фоновом задании. Если это регламентное задание запустит на клиенте — проходит в лет. А через фоновое — доходит до строки ЗапуститьПриложение(СтрокаЗапуска);
и все. Новый сеанс не создается, и фоновое подвисает в бесконечности. Убить получается только перезапуском службы 1С на сервере.
(44) У меня такая же проблема
Получается нет решения кроме переписывания библиотек?
Интересная идея, надо попробовать.
Добрый день.
Если тема еще актуальна,
а вот так: Компонента = Новый COMОбъект(«AddIn.NameDeclension»); — не работает?
(48) Если на сервере зарегистрирована — то работает. Доп.обработка еще должна запускаться в небезопасном режиме, или в безопасном с дополнительными разрешениями. На днях ковырялся с COM — компонентой для 1С mysql.dll, в облаке нужно было регламентное сделать, которое ее использовало. Все получилось (8.3.12, УНФ 1.6.15), работает в фоне по расписанию.
(48) И похоже, у автора статьи именно так это и работает — компонента запускается на сервере, просто она там уже зарегистрирована. Основные методы по формированию табличного документа производятся в контексте сервера, значит на сервере вычисляется и склонение ФИО с использованием внешней com-компоненты. Вряд ли отчет написан так, что при формировании табличного документа сервер общается с клиентом с целью просклонять ФИО. Хотя конечно всякое можно придумать — получить на клиент табличный документ и на клиенте менять падеж в ячейках с ФИО.
Наконец, главное, что выяснил. Проблема была такая же: в серверной базе на облаке обработка работала в интерактиве через файл-открыть, нормально создавала объект COM-компоненты с помощью (т.е. админ предварительно зарегистрировал ее в реестре облачного сервера)
и дальше сервер 1С отрабатывал методы этого класса. Но когда запускал ее в регламентно-фоновом режиме — я журналировал ошибку
Дело оказалось в том, что профили безопасности 1С разрешали небезопасный режим для клиентского вызова сервера из внешней обработки, но запрещали его для фоновых заданий из справочника доп.обработок — принудительно ставили безопасный, несмотря на то, что обработка была зарегистрирована
Поскольку это было облако, с админами связываться долго, а результат непредсказуем, проблему решил следующим образом: