0
Голосовать

События com объектов, использование методов

Создано:

Добрый день. У меня два вопроса:

1. Создал новое окно wnd_InfinytiWorkspace, со скриптом wnd_InfinytiWorkspaceScript

//-----------------------------------------------------------------------------
// wnd_InfinytiWorkspaceScript
//-----------------------------------------------------------------------------

function GetCore() {
Core = new ActiveXObject("InfinityCCCore.InfinityCCCoreObj");
return Core;
}

function wnd_InfinytiWorkspaceOnPrepare(Window) {
var Core = GetCore();
Core.Logon();

edtCallManagement.ActiveXProgID = 'InfinityCCCallManagement.InfinityCCCallManagementObj';
var CallManagement = edtCallManagement.ActiveXObject;
CallManagement.Init(Core);

edtQueue.ActiveXProgID = 'InfinityCCQueue.InfinityCCQueueObj';
var Queue = edtQueue.ActiveXObject;
Queue.Init(Core);

edtClientCard.ActiveXProgID = 'InfinityCCClientCard.InfinityCCClientCardObj';
var ClientCard = edtClientCard.ActiveXObject;
ClientCard.Init(Core);

edtStatus.ActiveXProgID = 'InfinityCCStatus.InfinityCCStatusObj';
var Status = edtStatus.ActiveXObject;
Status.Init(Core);

edtAutoDial.ActiveXProgID = 'InfinityCCAutoDial.InfinityCCAutoDialObj';
var AutoDial = edtAutoDial.ActiveXObject;
AutoDial.Init(Core);

edtMyCalls.ActiveXProgID = 'InfinityCCMyCalls.InfinityCCMyCallsObj';
var MyCalls = edtMyCalls.ActiveXObject;
MyCalls.Init(Core);

edtSoftphoneActiveX.ActiveXProgID = 'InfinityCCSoftphone.InfinityCCSoftphoneObj';
var SoftphoneActiveX = edtSoftphoneActiveX.ActiveXObject;
SoftphoneActiveX.Init(Core);

edtPlay.ActiveXProgID = 'InfinityCCInfWavePlayer.InfinityCCInfWavePlayerObj';
var Play = edtPlay.ActiveXObject;
Play.Init(Core);

edtMyConActiveX.ActiveXProgID = 'InfinityCCMyContactList.InfinityCCMyContactListObj';
var MyConActiveX = edtMyConActiveX.ActiveXObject;
MyConActiveX.Init(Core);

edtOperActiveX.ActiveXProgID = 'InfinityCCNumbersMon.InfinityCCNumbersMonObj';
var OperActiveX = edtOperActiveX.ActiveXObject;
OperActiveX.Init(Core);

}

function Call(number) {
Core.Dial(number);

}

Далее подключаю этот скрипт в scr_ContactEdit и пытаюсь вызвать его функцию Call(number), где number = dlData.Dataset.Values('Communication1')

В результате TS выдает ошибку "You cannot have more one TdxDockingManager instance on a Form"

Метод OnPrepare окна wnd_InfinytiWorkspace существует!

2. При вхолящем звонке, у объекта Core срабатывает некое событие, в параметре которого находится номер звонящего, каким образом в TS можно отследить появление этого события?

Спасибо!

Комментарии

Карло Сергей

Добрый день, Павел!

1. Ошибка вызвана ядром Infinity. Вам необходимо обратиться в их службу поддержки с этим вопросом. Мы не используем в ядре Terrasoft компоненты DevExpress (TdxDockingManager). Мы в принципе стараемся не использовать такие тяжеловесные пакеты, как DevExpress.

2. Ниже приведен пример кода, который показывает как можно подписаться на события произвольного COM объекта. В качестве примера взят COM объект Oktell.

var OktellComClientCoClassGUID = '{645CB11F-244B-4CD7-B0B8-D37D81A2D582}';
Oktell = new Object();
Oktell.Instance = new ActiveXObject('OktellClient.ComLib.OktellComClient');
Oktell.EventsDispatcher =
        System.CreateObject('TSObjectLibrary.EventsDispatcher');
Oktell.EventsDispatcher.Script =
        Services.GetSingleItemByUSI('scr_OktellUtils');
Oktell.EventsDispatcher.SubscribeForEvent('Oktell', Oktell.Instance,
        OktellComClientCoClassGUID, 'OnCommunicate', 'OnOktellCommunicate');
Oktell.EventsDispatcher.SubscribeForEvent('Oktell', Oktell.Instance,
        OktellComClientCoClassGUID, 'OnError', 'OnOktellError');
Oktell.EventsDispatcher.SubscribeForEvent('Oktell', Oktell.Instance,
        OktellComClientCoClassGUID, 'OnServiceMessage',
        'OnOktellServiceMessage');

Обратите внимание на необходимость передачи CoClassGUID-а в метод SubscribeForEvent. Этот GUID должен быть указан в SDK к Infinity.
Параметры метода SubscribeForEvent:

1. Логическое имя объекта, на события которого необходимо подписаться. Произвольное.

2. Экземпляр объекта, на события которого необходимо подписаться.

3. CoClassGUID объекта, на события которого необходимо подписаться. Необходимо взять из документации Infinity.

4. Название события объекта.

5. Имя метода скрипта, которое необходимо вызывать при наступлении события.

Павел Крышкин

Огромное спасибо, Сергей!

Еще один небольшой вопрос: как мне удалить вышеупомянутые com объекты Infinity, т.е. выгрузить их из памяти (пробовал Delete, не получается)

Карло Сергей

Не очень понятна формулировка "удалить". Вы имеете в виду выгрузить из памяти? Если да, то управление памятью в JScript, операция необычная. Разработчик не может непосредственно указать, какой именно объект выгрузить. Этим занимается сборщик мусора. Он с определенной периодичностью запускает процесс удаления объектов, которые больше нигде не используются, т.е. те объекты, на которые количество ссылок равно нулю. В общем это является стандартом для технологии COM, на которой построено ядро Terrasoft. Все что может сделать разработчик - это явно запустить процедуру сборки мусора. Для этого можно вызвать глобальный метод CollectGarbage(). Его вызов НЕ гарантирует удаление объектов, т.к. на них могут быть ссылки.

Павел Крышкин

Сергей, прошу прощения за неточную формулировку, Вы правильно поняли "выгрузить из памяти". Именно так и делаю, запускаю при закрытии TS CollectGarbage(), но видимо, действительно, существуют ссылки на com сервер инфинити, т.к. объекты остаются в памяти. Каким образом я могу отследить эти ссылки, а также удалить их?
Спасибо!

Карло Сергей

Ссылки могут держатся в следующих случаях:

1. Глобальные переменные скриптов. Перед вызовом сборки мусора в такие глобальные переменные нужно положить null (или undefined), но это может и не помочь.

2. Пока на события объекта подписан кто либо, он держится (самый вероятный вариант). Перед закрытием необходимо также обязательно отписываться от событий. Для этого указанный мной ранее код также сожержит следующие строки

if (Oktell.EventsDispatcher) {
        Oktell.EventsDispatcher.Unsubscribe('Oktell');
}

3. Ссылки могут быть внутренние, те которые держит сам Infinity. Вероятность таких ссылок конечно очень маленькая, но исправить их без вмешательства их разработчиков не получится, и идентифицировать тоже.

Павел Крышкин

Спасибо за оперативность, помог пункт 1.

Карло Сергей

Надеюсь в ближайшее время мы сможем увидеть результат интеграции ;-)

Kalinin Andrey

Подскажите пожалуйста
В 1С 8.1 при создании com
Соединитель = Новый COMObject("oktellClient.ComLib.OktellComClient");

выдает ошибку //не удается найти указанный файл
В чем может быть проблема?

Карло Сергей

Ну в принципе дублировать вопрос не обязательно. Я ответил на него в его основной ветке

Руслан aka Pipo

Добрый день Сергей!

Карло Сергей пишет:
var OktellComClientCoClassGUID = '{645CB11F-244B-4CD7-B0B8-D37D81A2D582}';
Oktell = new Object();
Oktell.Instance = new ActiveXObject('OktellClient.ComLib.OktellComClient');
Oktell.EventsDispatcher =
System.CreateObject('TSObjectLibrary.EventsDispatcher');
Oktell.EventsDispatcher.Script =
Services.GetSingleItemByUSI('scr_OktellUtils');
Oktell.EventsDispatcher.SubscribeForEvent('Oktell', Oktell.Instance,
OktellComClientCoClassGUID, 'OnCommunicate', 'OnOktellCommunicate');
Oktell.EventsDispatcher.SubscribeForEvent('Oktell', Oktell.Instance,
OktellComClientCoClassGUID, 'OnError', 'OnOktellError');
Oktell.EventsDispatcher.SubscribeForEvent('Oktell', Oktell.Instance,
OktellComClientCoClassGUID, 'OnServiceMessage',
'OnOktellServiceMessage');

На платформе 3.2.1.14 у нас возникает ошибка на строке: Oktell.EventsDispatcher.SubscribeForEvent('Oktell', Oktell.Instance,OktellComClientCoClassGUID,'OnCommunicate', 'OnOktellCommunicate'); -

"TSObjectLibrary.EventsDispatcher: File 'mscoree.dll' is not exists"

Underscore a.k.a. _

mscoree.dll - это Microsoft .NET Runtime Execution Engine. Может фреймворк обновить.

Руслан aka Pipo
Underscore a.k.a. _ пишет:
mscoree.dll - это Microsoft .NET Runtime Execution Engine. Может фреймворк обновить.

Дело в том, что на той же машине запустить 3.3 версию, то этот же скрипт работает без проблем

Underscore a.k.a. _

Так может изменился механизм подписки на события, и в новой версии эта библиотека не дергается.

Руслан aka Pipo

А альтернативного способа подписки на события COM нет??

Underscore a.k.a. _

Ну можно написать свой объект, который подписывается на события и транслирует их в скрипт :) Но проще таки с mscoree.dll разобраться.

Руслан aka Pipo

Спасибо тех. поддержке!!! Вот решение:

Цитирую: "Данная ситуация связана с тем, что используется COM Объект, написанный на .Net. С такими объектами есть особенности работы, и для этого специально выполнялись доработки".

Рекомендуем Вам обновиться до последних бинарных файлов версии 3.2.1

Все отлично работает!

Кулак Олег

Есть проблема:

function GetCore() {
        Core = new ActiveXObject("InfinityCCCore.InfinityCCCoreObj");
        return Core;
}

function NewCall(){
        Core = GetCore();
        Core.Logon();
}

После ввода данных логина (Core.LogOn()) выпадает ошибка:
Не удалось подключиться к серверу: Сервер InfinityGuardian не отвечает
Возможно, служба InfinityGuardian остановлена или указан неверный адрес сервера

При этом, при подключении через клиент Infinity, все работает.

Репко Артём

Олег, дело в том, что Infinity использует настройки подключения те, что находятся в папке вызывающего приложения (в данном случае папка BIN Террасофт). Если настроек в этой папке нет, то создается папка Data и чистый конфигурационный файл, который ищет сервер на 127.0.0.1.
Предлагаю или внести адрес сервера вручную (это правый верхний угол в окне авторизации) или скопировать конфигурационный файл из папки клиента Infinity.

Aberro

Попытался создать COM-библиотеку среды .NET, с объектом, имеющим события.
Почему-то, сразу после создания объекта, клиент Terrasoft весьма специфически зависает: он обрабатывает системные события, прорисовывает, система не считает, что приложение зависло, но никакие движения мыши, клики, нажатия клавиш не работают.
Не подскажете, в чем может быть дело?

Aberro

С этим разобрался - оказалось, есть большие ограничения на работу с потоками в COM-объектах.
Теперь другое - EventDispatcher.SubscribeForEvent не вызывает метода привязки к событию.

Яворский Алексей

Предлагаю обсуждать тему в http://www.community.terrasoft.ua/forum/topic/7068

С уважением,
Яворский Алексей
Эксперт 3-й линии поддержки