Быстрое создание Внешних Компонент на C#. Примеры использования Глобального Контекста, IAsyncEvent, IExtWndsSupport, WinForms и WPF

15.02.16

Разработка - Разработка внешних компонент

В большинстве случаев хватает и обычного COM объекта, учитывая, что в 8.х можно использовать события. Но иногда нужно использовать Глобальный Контекст для вызова глобальных функций, таких как Сообщить, NewObject и т.д. Кроме того, для использования форм нужен дескриптор окна 1С.
Это продолжение статей
Использование сборок .NET в 1С 7.x b 8.x. Создание внешних Компонент. http://infostart.ru/public/238584/
Там же лежат и исходники

.NET(C#) для 1С. Динамическая компиляция класса обертки для использования .Net событий в 1С через ДобавитьОбработчик или ОбработкаВнешнегоСобытия
http://infostart.ru/public/417830/

1C Messenger для отправки сообщений, файлов и обмена данными между пользователями 1С, вэб страницы, мобильными приложениями а ля Skype, WhatsApp
http://infostart.ru/public/434771/

Использование классов .Net в 1С для новичков
http://infostart.ru/public/448668/

Написанием ВК я занимаюсь давно. Но никогда не писал напрямую.

Я никогда не понимал, зачем нужен IlanguageExtender, когда есть IDispatch.

 

 Давным-давно сделал ВК, которая загружает Объект Автоматизации, поддерживающий ITypeInfo и выполняет все его свойства и методы через IlanguageExtender.

 

Смысл её в том, что пишем обычный  COM класс, но для превращения её в ВК добавляем только один метод  InitFrom1C. Например

 

public void InitFrom1C(object Object1C)

        {

             try

            {

        EventTo1C = Object1C as IAsyncEvent;

 if (SynchronizationContext.Current == null)

       SynchronizationContext.SetSynchronizationContext(new WindowsFormsSynchronizationContext());

 

        Sc = SynchronizationContext.Current;

            }

            catch (Exception e)

            {

                MessageBox.Show(e.ToString());

                throw e;

 

            }

        }

И вызов из 1С

 

 

Сообщить(ПодключитьВнешнююКомпоненту("AddIn.AddInFromITypeInfo"));

     РаботаССоккетом  = новый("AddIn.AddInFromITypeInfo");




  //   Соккет=New COMОбъект("ДляОбменаДаннмиЧерезTCP");

 //   РаботаССоккетом.LoadOleObject(Соккет);
     РаботаССоккетом.LoadOleObject("ДляОбменаДаннмиЧерезTCP");
     Если ИспользоватьКПК Тогда
        Попытка
        РаботаССоккетом.ОткрытьАйПиПортСНомеромПорта(ТСПАйПиНомерПорта);
         Исключение
            Сообщить("Нужно подключить новую TCPConnectTo1C.dll");
         РаботаССоккетом.ОткрытьАйПиПорт();
        КонецПопытки;

     Сообщить(РаботаССоккетом.Команда);
     Сообщить(РаботаССоккетом.ДанныеДляКоманды);

   

 

Если в 1С 7.7 через COMОбъект объект нельзя было в параметрах передавать объекты 1С и использовать out и ref параметры, то в восьмерке таких ограничений нет. И можно отказаться от обертки и передавать в Com объект только  объект, передаваемый при вызове Init интерфейса IInitDone

 

public void Init([MarshalAs(UnmanagedType.IDispatch)]

     object connection)

    {

        глобальныйКонтекст = connection;

        Marshal.GetIUnknownForObject(глобальныйКонтекст);

 

    }

 

Вот как это выглядит в 1С

 

    врап=новыйCOMОбъект("NetObjectToIDispatch45");
     Попытка
        //Проверим зарегистрирована ли нужная версия NetObjectToIDispatch45
         тест=НовыйCOMОбъект("AddIn.GlobalContext1C");
         тест=Неопределено;
     Исключение
        ФайлNetObjetToIDispatch45=ЗаписатьМакет("NetObjectToIDispatch","NetObjetToIDispatch45");
         ЗарегистрироватьDLL(ФайлNetObjetToIDispatch45);
     КонецПопытки;


     ФайлТестВК=ЗаписатьМакет("ТестВК");
 
    Если ПодключитьВнешнююКомпоненту("AddIn.GlobalContext1C") Тогда
        объект=Новый ("AddIn.GlobalContext1C");
         ГлобальныйКонтекст=объект.ГлобальныйКонтекст;
         AppDispatch=ГлобальныйКонтекст.AppDispatch;
         AppDispatch.Сообщить("Привет");
         Сообщить(AppDispatch.СтатусСообщения.Важное);
     иначе
        сообщить("Компонента не загружена");
     КонецЕсли;

 



Кроме того, в 1С нельзя лего использовать Глобальный Контекст через AppDispatch

То есть AppDispatch.Сообщить(value)

 

ТипГК = ГК1С.GetType();

App1C = ГК1С.AppDispatch;

 

result = ТипГК.InvokeMember(binder.Name, BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public | BindingFlags.InvokeMethod, null, App1C, new object[]{value}););


Для простоты использования я сделал оберку через

DynamicObject


Теперь можно легко использовать

 

public dynamic Новый( paramsobject[] Параметры)

{

 return ГК.NewObject(Параметры);

 }

 public dynamic ПолучитьОписаниеТиповСтроки(int ДлинаСтроки)

 {

 return Новый("ОписаниеТипов", "Строка", null, Новый("КвалификаторыСтроки", ДлинаСтроки, ГК.ДопустимаяДлина.Переменная));

 } // ПолучитьОписаниеТиповСтроки()

 

ГК.Сообщить("Привет из ВК", ГК.СтатусСообщения.Важное);

Вот пример использования ГК и окон

 

Сборка=Врап.ЗагрузитьСборку(ФайлТестВК);
ТестВК=Сборка.GetType("ТестВК.ТестВК");
ТВК=Врап.СоздатьОбъект(ТестВК,ГлобальныйКонтекст);
Сообщить(ТВК.СоздатьОкно());

Использование окон WinForms и в особенности WPF позволяет использовать больший функционала, особенно при применении управляемого приложения.


Стоит отметить, что если для обычного приложения проходил такой код

 

тип=Врап.ПолучитьТипИзСборки("WPFLibrary.Window1",ФайлТестВК);
	Окно=Врап.СоздатьОбъект(тип,ЭтотОбъект,ГлобальныйКонтекст);
	Окно.Show();

То для управляемого приложения он не работает. Ошибка возвращаемого значениея.
Пришлось сделать статческий метод создания окна

 

Window1=Врап.ПолучитьТипИзСборки("WPFLibrary.Window1",ФайлТестВК);
Window1.СоздатьОкно(ЭтаФорма,ГлобальныйКонтекст);


Стоит отметить, что вместо использования ДобавитьОбработчик или ОбработкаВнешненго события

проще дать ссылку на модуль объекта или формы где прописать экспортные функции например

 
 
&НаКлиенте Процедура СообщитьСтр(стр) Экспорт

// Вставить содержимое обработчика. Сообщить(стр);

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

И вызывать из кода на C#

Модуль1С.СообщитьСтр(textBox.Text);

 

Ну и добавлю про использование немодального подключения ВК

 

&НаКлиенте
Процедура ПроверитьВК(Команда)
		ProgID="AddIn.GlobalContext1C";

	// Вставить содержимое обработчика.
	 Оповещение = Новый ОписаниеОповещения("УстановитьВК", ЭтотОбъект);
     НачатьПодключениеВнешнейКомпоненты(Оповещение, ProgID);

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

&НаКлиенте

Процедура УстановитьВК(Подключено,Параметры) Экспорт
	врап=новый COMОбъект("NetObjectToIDispatch45");

  ProgID="AddIn.GlobalContext1C";
    Попытка
        Вк = Новый (ProgID);
       
	Исключение
		стр=ОписаниеОшибки();
        ПоказатьПредупреждение(, "Компонента  не подключена"+стр);
		 Возврат
   КонецПопытки; 

	        ГК=Вк.ГлобальныйКонтекст;
		AppDispatch=ГК.AppDispatch;
		AppDispatch.Сообщить("Привет");
		Сообщить(AppDispatch.СтатусСообщения.Важное);

КонецПроцедуры
&НаКлиенте


Процедура ПриЗакрытии()
	// Вставить содержимое обработчика.
		ГлобальныйКонтекст=Неопределено;
	Если ТВК<>Неопределено Тогда
		ТВК.Закрыть();
		ТВК=Неопределено;
	КонецЕсли; 	

	
	GC=Врап.ПолучитьТип("System.GC");
	GC.Collect();
	GC.WaitForPendingFinalizers();
	Врап= Неопределено;

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

Ну и не забывать диспозить объект, содержащий ссылку на Глобальный Контекст, иаче 1С будет висеть в процессах

Внешние Компонеты C# .Net

См. также

Разработка внешних компонент POS терминал Рабочее место Розничная торговля Программист Пользователь Платформа 1С v8.3 1С:Комплексная автоматизация 1.х 1С:Управление торговлей 10 1С:Розница 2 1С:Управление нашей фирмой 1.6 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Розничная и сетевая торговля (FMCG) Рестораны, кафе и фаст-фуд Реклама, PR и маркетинг Управленческий учет Платные (руб)

Медиадисплей покупателя может отображать текущую покупку на кассовом месте, показывать видеорекламу, баннеры, во время простоя разворачивать рекламу на весь экран. Экран можно использовать в качестве графического меню-борда в кафе и видеовывески. В качестве устройства отображения можно использовать Android-планшеты, смарт-телевизоры с Android, мониторы или проекторы под управлением Windows или Linux-компьютера. Linux-версия успешно запускается на одноплатных компьютерах Raspberri Pi и Orange Pi. Настраивается ЛЮБОЙ ДИЗАЙН экрана при помощи встроенного графического редактора! Решение можно масштабировать от одного экрана до тысяч экранов с централизованным управлением.

18000 руб.

30.05.2017    54039    9    69    

46

Разработка внешних компонент Программист Платформа 1С v8.3 Конфигурации 1cv8 1С:Управление торговлей 11 Платные (руб)

Внешняя компонента для конвертации PDF файлов в картинки без использования дополнительных программ. Работает на сервере и в тонком клиенте.

2400 руб.

25.06.2024    1126    3    4    

3

Разработка внешних компонент Телефония, SIP Программист Платформа 1С v8.3 Конфигурации 1cv8 Россия Платные (руб)

Внешняя компонента выполнена по технологии Native API для 1С 8.х, обеспечивает доступ к программным АТС Asterisk (FreePBX, Elastix) через AMI интерфейс. Через него можно управлять многими функциями Asterisk (определение номеров, перевод звонков, набор телефона и т. д.)

2400 руб.

04.05.2018    47297    124    66    

67

Разработка внешних компонент Программист Платформа 1С v8.3 Платформа 1C v8.2 Платные (руб)

Внешняя компонента, позволяющая посылать команды и получать ответы по GraphQL протоколу из 1С.Может быть использована при интеграции. В 1С работает на стороне "клиента".

4600 руб.

27.06.2023    3598    3    0    

5

Разработка внешних компонент Программист Платформа 1С v8.3 Конфигурации 1cv8 Платные (руб)

Позволяет автоматизировать работу с картинками. С помощью компоненты можно измерять размер изображений, поворачивать их, наносить водяные знаки, конвертировать из одного формата в другой. Будет очень полезна для интернет-магазинов и всех, кому постоянно требуется работать с различными графическими форматами. Выполнена по технологии NativeAPI. Работает с форматами: jpg (jpeg), png, bmp, gif, tif

3600 руб.

02.09.2010    77515    72    257    

191

Разработка внешних компонент Программист Платформа 1С v8.3 Конфигурации 1cv8 1С:Управление нашей фирмой 1.6 1С:Бухгалтерия 3.0 Платные (руб)

Внешняя компонента позволяет работать c TWAIN-совместимым оборудованием (сканерами, камерами) . Полностью совместима со стандартной TWAIN-компонентой из БСП и может применяться как ее замена без изменения вызовов, при этом может работать с 64-разрядной платформой, а так же имеет расширенную функциональность, например, сохранение результата непосредственно в PDF без использования сторонних утилит. Прекрасно работает на сервере, тонком клиенте и веб-клиенте (проверена работа в браузерах Google Chrome, Mozilla Firefox и Microsoft Internet Explorer).

3000 руб.

12.05.2020    28655    138    100    

91

Разработка внешних компонент Системный администратор Программист Стажер Бесплатно (free)

Библиотека для работы с базами SQLite из 1С на основе внешней компоненты. Для Linux и Windows, бесплатно и с открытым исходным кодом!

14.01.2025    1817    bayselonarrend    10    

44

Разработка внешних компонент Программист Платформа 1С v8.3 Конфигурации 1cv8 Россия Бесплатно (free)

В статье описывается приложение-конструктор внешних компонент (native API). Конструктор упрощает процесс разработки за счет удобного добавления всех нужных функций и процедур в графическом режиме, с указанием их параметров и типов параметров. На выходе приложение генерирует готовый код на С++ и Rust и позволяет сразу приступить к реализации, без настройки API компоненты вручную.

04.12.2024    4715    kovalevdmv    26    

75
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. AlX0id 16.02.16 08:55 Сейчас в теме

Спасибо, будет что почитать на досуге :)
2. Serginio 941 16.02.16 09:45 Сейчас в теме
Большое спасибо за спасибо.
3. avz_1C 10 16.02.16 12:32 Сейчас в теме
Спасибо. Написано очень толково.
Я систематизировал свои знания по данному предмету, при помощи Вашей статьи.
4. Serginio 941 16.02.16 12:52 Сейчас в теме
Спасибо. Старался. Рад, что мои труды не пропадают зря.
5. O-Planet 6452 17.02.16 03:28 Сейчас в теме
Спасибо за статью. У меня com+ на с++ (Builder). Не совсем понимаю, как внутри этого объекта обратиться к глобальному контексту 1С. Объекты я передаю через VARIANT, например:

STDMETHODIMP TServerImpl::Make(VARIANT Object, int Numb, BSTR FileName)
{
bool Res=mycells->Make(Numb,AnsiString(WideString(FileName).c_bstr()));
Variant(Object).OleFunction("Вставить","Ок",(Res?"yes":"no"));
return S_OK;
}

Но как получить доступ в этой функции к глобальному контексту 1С, чтобы вызвать, например, NewObject? Что передать на вход? Или можно как-то подключиться к самой 1С? Вопрос - как? Не через OLE же. И теоретически, этот com может быть использован и не 1С. Есть возможность проверить, кто его создал и использует?
6. Serginio 941 17.02.16 07:33 Сейчас в теме
Ну судя по
ТипГК = ГК1С.GetType();

App1C = ГК1С.AppDispatch;

 

result = ТипГК.InvokeMember(binder.Name, BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public | BindingFlags.InvokeMethod, null, App1C, new object[]{value}););
Показать


Адрес функции берется из VMT ГК1С, а в EAX засылается ГК1С.AppDispatch
7. Serginio 941 17.02.16 07:38 Сейчас в теме
8. Serginio 941 17.02.16 08:27 Сейчас в теме
Адреса Idispatch GetIDsOfName(), Invoke()
То есть ссылку на Idispatch берется из передаваемого объекта при Init, а объект подставляется AppDispatch
9. Serginio 941 17.02.16 08:33 Сейчас в теме
Помню в Delphi для реализации интерфейса создавалось поле внутри объекта, а в методах интерфейса были заглушки которые корректировали this по смещению поля и вызывали реальные методы интерфейса объекта
10. frkbvfnjh 808 27.02.16 08:31 Сейчас в теме
Лююююююди! Кто нибудь может накидать шаблон на Delphi, что бы можно было работать в глобальном контексте? C# вообще не понимаю, да и COM технология с трудом дается, но очень хочется пользоваться функционалом платформы, поэтому хотелось бы шаблон native-компоненты на Delphi. Я так понимаю для людей, оставивших здесь комментарии, это не составит никакого труда. Сейчас для написания внешних компонент пользуюсь шаблоном из публикации http://infostart.ru/public/168254/. Сжальтесь над немощным... ну что Вам стоит?
11. Serginio 941 27.02.16 09:03 Сейчас в теме
(10) Тебе лучше обратиться сюда http://infostart.ru/public/88060/
Только вот глобальный Контекст это COM.
12. NittenRenegade 112 20.06.18 11:08 Сейчас в теме
Я внедряю CefSharp во внешнюю компоненту. Сложность в том, что её не скомпилируешь в одну dll. У него множество файлов-зависимостей разных типов, без которых например подпроцесс для отображения содержимого страницы просто не запустится.
Когда эти файлы лежат рядом с запускаемым приложением, у меня всё работает. Но когда я компилирую библиотеку и подключаю её из 1С, у меня пустой экран как если бы подпроцесс не стартовал. Подозреваю, дело в зависимостях. Куда сложить файлы зависимостей чтобы они подтянулись к моей dll? Или может как-то иначе эти зависимости прописать в самой dll
15. Serginio 941 20.06.18 12:03 Сейчас в теме
На самом деле если все dll в одной папке и есть доступ к папке для текущего пользователя, то все должно быть нормально
Оставьте свое сообщение