Внешняя компонента для 1с 8.2 на C# #682239


#0 by vudo
Когда-то писал внешние компоненты для 1С. Я наверное за два года что-то упустил :( Был у меня базовый класс для создания внешних компонент: ExtComponentBase (где брал уже не помню, но работало) Сейчас написал компоненту:     [ComImport]     public interface IWorkCompsMain     {     }     [ProgId("Comps")]     public class Comps : ExtComponentBase, IWorkCompsMain     {         private string _version = "";            [Export1c]         public string Version         {         }     } } Подписал строгим именем, выполнил: echo --------------------------------------------------- pause Все прошло замечательно! Дальше из 1С (Толстый клиент - Управляемое)     Попытка И тут ошибка: Тип не определен (Comps)! Какого не могу второй день понять... Кто знает?
#0 by vudo
Когда-то писал внешние компоненты для 1С. Я наверное за два года что-то упустил :( Был у меня базовый класс для создания внешних компонент: ExtComponentBase (где брал уже не помню, но работало) Сейчас написал компоненту:     [ComImport]     public interface IWorkCompsMain     {     }     [ProgId("Comps")]     public class Comps : ExtComponentBase, IWorkCompsMain     {         private string _version = "";            [Export1c]         public string Version         {         }     } } Подписал строгим именем, выполнил: echo --------------------------------------------------- pause Все прошло замечательно! Дальше из 1С (Толстый клиент - Управляемое)     Попытка И тут ошибка: Тип не определен (Comps)! Какого не могу второй день понять... Кто знает?
#1 by Serginio1
#2 by Serginio1
#3 by vudo
ПодключитьВнешнююКомпоненту("Comps") Уже проходил возвращает Ложь.
#4 by Serginio1
Но я использую ВК Сообщить(ПодключитьВнешнююКомпоненту("AddIn.AddInFromITypeInfo"));
#5 by Serginio1
А реально она у тебя ВК или просто COM объект?
#6 by vudo
По технологии создания внешних компонент примерно двух годичной свежести... Там наследуется ExtComponentBase
#7 by vudo
Спасибо конечно, но мне нужно решить через C#.
#8 by vudo
На форумы RSDN без регистрации перестали пускать :( Блин! Куда мир катится... Там хоть о чем?
#9 by vudo
+ Ан нет просто по прямой ссылке не пустило... Что там мне искать?
#10 by Serginio1
#11 by vudo
Нашел где брал ExtComponentBase! На том же rsdn:
#12 by Serginio1
Раз ПодключитьВнешнююКомпоненту не проходит значит не зарегестрирован или не видит IInitDone, Может вызываешь на стороне сервера, тогда нужно регистрировать через 64 разрядный regasm.exe
#13 by vudo
НаКлиенте IInitDone сейчас гляну...
#14 by Serginio1
В отладчике VS посмотри
#15 by Serginio1
У тебя  ExtComponentBase: ServicedComponent,IInitDone,ILanguageExtender поддерживает.
#16 by vudo
Та отож... :(
#17 by vudo
Там смотреть не на что - одна переменная... :(
#18 by vudo
Что-то еще... Вот только что?
#19 by Serginio1
В отладчике помотри на ExtComponentBase А имеено на методы InitDone. Вообще доходит ли до них.
#20 by vudo
Вот ссука... Прости господи что ругаюсь! В документации ведь ясно написано, что ProgID имеет вид Vendor.Component, где в качестве первой части Vendor используется Addin. Таким образом должно быть не [ProgId("Comps")], а [ProgId("Addin.Comps")] Плюс к этому в калс добавить пустой метод public void Initialization { } И после этого все работает! Вызов На такую куйню столько времени. И Спасибо  Serginio1 за поодержку. :)))) Йахо!!!! Пошел дальше ковырять.
#21 by vudo
А как в отладчике посмотреть для вызова 1с?
#22 by oleg_km
Можно я? Открываешь конфигуратор, запускаешь предприятие, открываешь студию, открываешь проект с ВК, в дебагере говоришь приаттачиться к процессу 1С Предприятие, ставишь точки останова в нужных местах, запускаешь Загружено = ПодключитьВнешнююКомпоненту("Addin.Comps");
#23 by vudo
А как дебагер в студио без отладки открыть?
#24 by oleg_km
Дебаггер в студии всегда есть. Меню просто щелкаешь Debug -> Attach to Process... Ну у меня VS2010. ну и dll нужно естетственно билдить в отладочном варианте
#25 by vudo
VS2010 Express Отладка -> Подключиться к отладке не вижу :(
#26 by oleg_km
Подключиться к процессу... тогда уж
#27 by vudo
Пусть так а результат тот же - нету...
#28 by Serginio1
ProjectPropertiesDebugStart external programm устанавливаешь нужный путь к 1cestart.exe например C:Program Files (x86)1cv82common1cestart.exe
#29 by oleg_km
У меня так не получалось, очень много возникало остановок на запуске, какие-то исключения, где нужно жать Continue. Мне кажется проще приаттачиться к уже запущенному 1С перед вызовом ВК
#30 by Serginio1
согласен. Редко сейчас программирую на C#. Ну поставь более навороченный вариант.
#31 by vudo
Неа В Express там только Аргументы командной строки и Рабочий каталог :(
#32 by vudo
Ладно, пока так справляюсь. Загоняю значения в поля классов и смотрю в 1с.
#33 by H A D G E H O G s
Жесть. Еще уж через ShowMessage отлаживай...
#34 by H A D G E H O G s
Ох уж эта ваша C++
#35 by oleg_km
А в чем разница с 1С? В 1С все то же, слегка усечено только
#36 by vudo
Продолжаю воевать с вк в управляемых формах... Куда загонять  созданный COM объект? В хранилище значений? Так а с асинхронными вызовами как? Что-то не соображу...
#37 by Serginio1
public void ПодключитьСканер(int НомерПорта)         { Где  SynchronizationContext Sc; поле Класса Которое можно Инициировать в Init
#38 by Serginio1
А ты на сервере вызываешь?
#39 by vudo
Нет пока на клиенте отлаживаю. И хочу с клиентом разобраться.
#40 by vudo
А какой эффект я получу от SynchronizationContext? Если на пальцах?
#41 by vudo
+ Я хочу получить от своей компоненты получить асинхронные вызовы в открытую форму. После вызова процедуры (нажатие кнопки) например: должен получить через ExternalEvent по одному компьютеры в сети. Как-то так; ВК = Новый("Addin.Comps"); Я же не должен каждый раз вызывать, а значит должен где-то эту ВК хранить. Вот и вопрос где? Да еще и так, что бы она генерировала события для формы?
#42 by Serginio1
На пальцах вызов будет в потоке 1С. Вообще IAsyncEvent ассинхронный, но нужно Нетовский поток инициализировать и прочее. У меня не получилось. Проще воспользоваться SynchronizationContext. Сделак ВК переменной формы. А зачем тебе асинхронные вызовы  для ВК.ПолучитьКомпютеры; Долгая операция? EventTo1C.ExternalEvent В форме ловится через
#43 by vudo
Почитал об SynchronizationContext. В принципе я делаю тоже, но только через делегаты:         public void GetListComs         {             IAsyncResult asyncRes = sd.BeginInvoke(new AsyncCallback(getedComps), null);         } И события генерируются пока существует экземпляр вызывающего класса. Так вот т.к. вызовы асинхронные, то выполнение продолжается после вызова ВК = Новый("Addin.Comps"); На этом выполнение 1с процедуры завершается и экземпляр ВК  уничтожается, передавать события некому и нечему. Успевает передать только первый компьютер (через ВнешнееСобытие истественно). Так что бы этого не происходило, необходимо ВК  держать открытой пока открыта форма по аналогии "Я художник! Я так вижу!" (с) :)
#44 by H A D G E H O G s
Хрень какая-то.
#45 by H A D G E H O G s
Возвращайте рассово верную ТЗ, просто дописывая строки в отдельном потоке ВК. В обработке внешнего события - удаляйте строки ТЗ, которые обработали.
#46 by H A D G E H O G s
Как у вас там все ... "непросто"
#47 by Serginio1
Нет SynchronizationContext обеспечивает вызов делегата из потока в котором был создан этот SynchronizationContext. Вообще в восьмерке есть подписка на события и можно ВК не использовать
#48 by Serginio1
Смотри
#49 by H A D G E H O G s
Это же через ISink2 ? А есть пример на Дельфях?
#50 by H A D G E H O G s
Интересно, для обработки этого 1С создает отдельный поток. Надо будет поэкспериментировать.
#51 by Принт
буэ на ваш мавзолей
#52 by Serginio1
На дельфях там все просто. В потоке инициализируем поток. В Net там немного сложнее, да и с используя SynchronizationContext проще не думать о проблемах
#53 by Serginio1
Нет для этого не создает. Но вот если событие срабатыватся в другом потоке, нужно позаботьться что бы вызов был в потоке 1С
#54 by vudo
Интересует не столько данная конкретная задача, сколько идеология в целом. Хм. Рекомендуешь использовать ActiveX? ДобавитьОбработчик мда много я пропустил... Надо будет покрутить. Спасибо. Но ушли в сторону.И все таки. Как получить многопоточность в 1с?
#55 by H A D G E H O G s
Что это? Я хотел узнать, как реализовать отправку события из ВК, чтобы 1С его отловила через ДобавитьОбработчик Компонента.onsocketread,ПриПолученииДанных;
#56 by H A D G E H O G s
Как получить многопоточность в 1с? Ваш К.О.
#57 by Serginio1
ты 37 внимательней посмотри. Там sp.DataReceived срабатыват при получении данных берет поток из пула потока и выполняет делегат Давно не брал я в руки Delphi. Но все тоже создаешь Event и подключаешься. Посмотри примеры по ActiveX.
#58 by vudo
Что-то вроде многопоточности... На самом деле вопрос только в том куда в управляемой форме запихнуть значение ВК. Так что бы экзепляр объекта существовал пока открыта форма.
#59 by H A D G E H O G s
В Клиентскую переменную
#60 by H A D G E H O G s
#61 by Serginio1
#62 by vudo
Спасибо.
#63 by Serginio1
Вспомнил нужно реализовать IConnectionPointContainer
#64 by H A D G E H O G s
Вооо, спасибо! А то всякие COM+
#65 by Serginio1
Да И подлючение в Вордовскому идет через IConnectionPointContainer try { TWordConnection is the COM object which receives the notifications from Word. Make sure to free WordSink when you are done with it. } Point.Advise((WordSink as IUnknown), WordSink.AppCookie); Point.Advise((WordSink as IUnknown), WordSink.DocCookie); end; except on E: Exception do ShowMessage(E.Message); end; end;
#66 by Serginio1
#67 by Serginio1
#68 by vudo
А как сделать SetBufferEvent? Сделал так: public bool SetBufferEvent(long depth) } и в интерфейсах:     public interface IAsyncEvent     { из 1с: Пишет не достаточно фактических параметров. Что не так?
#69 by vudo
Ах да и еще в ExtComponentBase:               protected IAsyncEvent Async         }
#70 by vudo
забыл к методу добавить атрибут [Export1c]
#71 by Serginio1
SetEventBufferDepth тебе нужен из ВК Описание: Устанавливает размер очереди событий для данного объекта. Если текущее количество событий в очереди больше устанавливаемой длины, последние события обрезаются. HRESULT ExternalEvent(BSTR bstrWho, BSTR bstrWhat, BSTR bstrData) Помещает событие в очередь, записывая источник события, наименование и параметры события. При обработке события эти данные передаются процедуре ОбработкаВнешнегоСобытия. При вызове метода ExternalEvent дальнейшая обработка события происходит следующим образом: событие записывается в очередь событий (если очередь полностью занята, событие теряется), затем при отсутствии системных событий из очереди берется первое событие (если очередь не пуста) и вызывается соответствующая функция ОбработкаВнешнегоСобытия. Этот процесс повторяется для всех объектов внешних компонент. Таким образом, обработка внешних событий синхронизируется с обработкой системных событий. Если у тебя Данные больше чем буфер то они обрезаются. Выход задать нужный размер, или записывать данные в свойство, откуда уже брать из 1С.
#72 by vudo
Да спасибо я уже сделал. Атрибут забыл прописать методу. Теперь последняя проблема никак не удается запустить метод ассинхронно. 1С после вызова метода блокируется, пока неотработаются события порожденные этим методом. Х.з. что делать... Вызываю так:             IAsyncResult asyncRes = sd.BeginInvoke(new AsyncCallback(getedComps), null); где private void GetList { } и в свою очередь: public event NameGetingHandler NameGeting; Ну вот какого?!!!
#73 by vudo
Уже не знаю с какой стороны и подползти... Уже вроде все перепробовал. Должно же работать. Или оно отслеживает после вызова метода живой поток или нет? Так вроде в разных потоках ассинхронные вызовы выполняются... Как????
#74 by Serginio1
getedComps покажи
#75 by H A D G E H O G s
Подползи со стороны Дельфи. Там все делается 10 строчками кода из WinAPI
#76 by vudo
private void getedComps(IAsyncResult result)         {         } :)
#77 by vudo
Ну ты фанат. :)))
#78 by Serginio1
Проверь AppDomain.GetCurrentThreadId Ну и ни очем не говорит?
#79 by Serginio1
У тебя поток запускается но ничего не делает
#80 by Serginio1
в C# еще проще через Или по старинке
#81 by Serginio1
#82 by vudo
Ну как это не делает? Готовит на выполнение GetList IAsyncResult asyncRes = sd.BeginInvoke(new AsyncCallback(getedComps), null); Запускает выполнение getedComps - это обратный вызов(после завершения выполнения GetList). GetList - замечательно выполняется! Иначе у меня бы вообще ничего в 1с не передавало бы...
#83 by vudo
Задачи спасибо покурю. Но вот почему ассинхронные вызовы 1с так странно обрабатвыает? Хочется разобраться...
#84 by H A D G E H O G s
Ты не поверишь, сколько странного есть в 1С.
#85 by H A D G E H O G s
Например, размещение гиганского табличного документа в памяти. Блоками по 16 мегабайт в созданных кучах, при этом, после очистки данного документа - кучи не удаляются, не ресайзятся, а тупо резервируются. Если заново открыть этот док - эти кучи снова задействуются, но попытка выделить память под что-то другое - ведет к падению по памяти (если не хватает памяти на создание новых куч).
#86 by Serginio1
где у тебя в getedComps dlgt.EndInvoke ( result)
#87 by Serginio1
Это дает, то что GetList  выполняется в потоке вызвавшем getedComps
#88 by vudo
Я был уверен, что getedComps будет вызван в любом случае и передан делегату где будет подписка, а если подписки нет, то ничего не произойдет. Вообщем-то я это проверял. Если в консоле запускаешь так как описано, Main идет до конца, хотя выполнение идет дальше, и консоль "умерает" только после того как завершится последняя команда из GetList; Сейчас не могу, но сегодня попробую прямо указать выполнение в другом потоке и грохнуть породивший поток.
#89 by vudo
Гы... Если все будет гладко выполняться, то мощностей компьютеров пяти летней давности для 8-мки с головой. А кто китайского производителя поддержит?
#90 by vudo
А дошло! Подписка в этом же потоке! Че-то туплю...
#91 by vudo
Нихрена не получается! 1С-ка блокируется пока живой хоть из одного потоков, а потом вываливает весь список внешних событий! Пробовал по всякому: Фантазия кончается... Как запустить метод асинхронно для 1С-ки???????
#92 by H A D G E H O G s
ППЦ. Я ОбъектОбработку помещал в отдельный поток ВК, запускал ее экспортную процедуру, она там обсчитывала все, при этом выводя в окно сообщений (не стоит так делать) и давая работать с 1С параллельно.
#93 by vudo
Гы. Сделал таймер:         } кал на его срабатывание: private void TimerProc(object state) {    if (startedList) } При срабатывании блокирует 1С... Теперь точно уже все. Что системную службу писать? Это же бред! Хотя может попробовать в другом классе отлавливать?.. Счас!
#94 by vudo
+ Ан нет смысла нету. Какая разница какой класс будет 1с-ку вешать...
#95 by Serginio1
Покажи GetList;
#96 by Serginio1
Покажи весь код вызова метода вызываемого из 1С
#97 by vudo
Все я 1Суку довел до истерики. Уходит в дамп когда из другого класса вызываю делегата на который подписаны события класса компоненты...
#98 by vudo
Счас.
Тэги: 1С 8
Ответить:
Комментарии доступны только авторизированным пользователям