Переключение на Главную Страницу Страницы: [1] 2 3 ... 5 ОтправитьПечать
Очень популярная тема (более 25 ответов) ВК для асинхронной обработки событий COM-объектов. (число прочтений - 62930 )
steban
1c++ developer
Отсутствует


#define sizeof(x) rand()

Сообщений: 787
Зарегистрирован: 19. Мая 2006
Пол: Мужской
ВК для асинхронной обработки событий COM-объектов.
12. Июля 2006 :: 06:12
Печать  
EventProxy - ВК для асинхронной обработки событий COM-объектов.

Содержит единственный объект [b]EventProxy[/b].

Свойства:
[list][*][b]ГлубинаБуфераСобытий[/b](EventBufferDepth) - глубина буфера событий интерфейса IAsyncEvent
[*][b]ГлобальныйКонтекст[/b](GlobalContext) - собственно он и есть[/list]

Методы:
[list][*][b]Источник[/b] (Source)  Устанавливает источник событий.
  параметры:
  [list][*]Источник - собственно источник событий.
  [*]ProgID - ProgID источника (По этому ProgID определяются DISPID и имена событий)
  [*]ИмяИсточника - имя источника событий, как оно будет передано в процедуру ОбработкаВнешнегоСобытия[/list]
[*][b]ПолучитьОбъект[/b] (GetObject)
  передает свой единственный параметр в ф-ю CoGetObject и возвращает полученный объект
  (аналог GetObject в VB)
[*][b]Сериализовать[/b]
  сериализует переданный параметр при помощи ObjRefMoniker[/list]

При вызове метода "Источник", EventProxy подписывается на события источника.
При получении события оно передается в 1С через IAsyncEvent.
В процедуре [i]ОбработкаВнешнегоСобытия(Источник, Событие, Данные)[/i]
аргумент [i]"Данные"[/i] содержит сериализованный список значений с параметрами события.
Для десериализации параметров события необходимо вызвать функцию ЗначениеИзСтрокиВнутр(Данные).
Параметры с типом VT_DISPATCH сериализуются при помощи ObjRefMoniker и могут быть десериализованы
методом [i]"ПолучитьОбъект"[/i].

Пример использования:[code]Перем Аутлук,ОбработчикСобытий;

Процедура ПриОткрытии()
     ЗагрузитьВнешнююКомпоненту("EventProxy.dll");
     Аутлук=СоздатьОбъект("Outlook.Application");
     ОбработчикСобытий=СоздатьОбъект("Addin.EventProxy");
     ОбработчикСобытий.ГлубинаБуфераСобытий=200;
     ОбработчикСобытий.Источник(Аутлук,"Outlook.Application","Аутглюк");
КонецПроцедуры      // ПриОткрытии

Процедура ОбработкаВнешнегоСобытия(Источник, Событие, Данные)
     Если (Источник="Аутглюк") и (Событие="ItemSend") Тогда
           Письмо=ОбработчикСобытий.ПолучитьОбъект(Лев(Данные,СтрДлина(Данные)-3));
           Сообщить(Письмо.Subject);
     КонецЕсли;
КонецПроцедуры      // ОбработкаВнешнегоСобытия[/code]
« Последняя редакция: 17. Марта 2008 :: 13:34 - steban »  

EventProxy_001.rar ( 16 KB | Загрузки )

int getRandomNumber()&&{&&  return 4; //chosen by fair dice roll&&         //guaranteed to be random&&}
Наверх
 
IP записан
 
Arta
1c++ power user
Отсутствует



Сообщений: 2537
Местоположение: Нижний Новгород
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: ВК для асинхронной обработки событий COM-объек
Ответ #1 - 12. Июля 2006 :: 06:26
Печать  
Иес! Спасибочки, сейчас запробую!


А что в не состав в 1cpp?
  
Наверх
 
IP записан
 
steban
1c++ developer
Отсутствует


#define sizeof(x) rand()

Сообщений: 787
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: ВК для асинхронной обработки событий COM-объек
Ответ #2 - 12. Июля 2006 :: 06:27
Печать  
Принимаются предложения как покрасИвше реализовать сериализацию параметров (чтобы было легко разбирать строку).
А также чтобы обойти грабли с параметрами типа строка, в которой встречается разделитель "|"
« Последняя редакция: 12. Июля 2006 :: 09:46 - steban »  

int getRandomNumber()&&{&&  return 4; //chosen by fair dice roll&&         //guaranteed to be random&&}
Наверх
 
IP записан
 
steban
1c++ developer
Отсутствует


#define sizeof(x) rand()

Сообщений: 787
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: ВК для асинхронной обработки событий COM-объек
Ответ #3 - 12. Июля 2006 :: 06:32
Печать  
Arta писал(а) 12. Июля 2006 :: 06:26:
А что в не состав в 1cpp?

Если очень надо, можно и в 1С++.
Я там использовал реализацию ILanguageExtender а-ля CMyContextBase : CBLContext   в 1С++ (карты методов и свойств).
Так что технически это делается просто.
  

int getRandomNumber()&&{&&  return 4; //chosen by fair dice roll&&         //guaranteed to be random&&}
Наверх
 
IP записан
 
steban
1c++ developer
Отсутствует


#define sizeof(x) rand()

Сообщений: 787
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: ВК для асинхронной обработки событий COM-объек
Ответ #4 - 12. Июля 2006 :: 06:45
Печать  
Кстати, метод ПолучитьОбъект можно использовать и не по назначению Улыбка.
Например так:
Код
Выбрать все
Док=ОбработчикСобытий.ПолучитьОбъект("ПрайсЛист.xls") 


или так:
Код
Выбрать все
6:") 


или даже так:
Код
Выбрать все
Стек=ОбработчикСобытий.ПолучитьОбъект("dm.net:['mscorlib']System.Collections.Stack") 


последний вариант заработает если установить dm.net COM Moniker
  

int getRandomNumber()&&{&&  return 4; //chosen by fair dice roll&&         //guaranteed to be random&&}
Наверх
 
IP записан
 
steban
1c++ developer
Отсутствует


#define sizeof(x) rand()

Сообщений: 787
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: ВК для асинхронной обработки событий COM-объек
Ответ #5 - 12. Июля 2006 :: 07:58
Печать  
Добавлю: поскольку обработка событий в 1С идет в асинхронном режиме, следует соблюдать осторожность при использовании параметров, восстановленных из ссылки ObjRef, т.к. к тому времени, когда у 1С появится время обработать внешнее событие, объект может прекратить свое существование.

Кстати ObjRef-ссылку можно передать каким-либо образом на другую машину и провести там десериализацию Улыбка.
При этом будет создано RPC-соединение к объекту Класс.

ЗЫ: Я вот думаю, может добавить метод сериализовать для создания ObjRef-ссылок на произвольные объекты?
  

int getRandomNumber()&&{&&  return 4; //chosen by fair dice roll&&         //guaranteed to be random&&}
Наверх
 
IP записан
 
jbond
Full Member
***
Отсутствует


1С++ Programmer

Сообщений: 140
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: ВК для асинхронной обработки событий COM-объек
Ответ #6 - 12. Июля 2006 :: 08:07
Печать  
Т.е. можно обрабатывать события WMI в в 1С коде?
  
Наверх
 
IP записан
 
steban
1c++ developer
Отсутствует


#define sizeof(x) rand()

Сообщений: 787
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: ВК для асинхронной обработки событий COM-объек
Ответ #7 - 12. Июля 2006 :: 08:14
Печать  
steban писал(а) 12. Июля 2006 :: 07:58:
может добавить метод сериализовать для создания ObjRef-ссылок на произвольные объекты?

Сделал. Изменил 1-й пост. Качать там-же.
  

int getRandomNumber()&&{&&  return 4; //chosen by fair dice roll&&         //guaranteed to be random&&}
Наверх
 
IP записан
 
steban
1c++ developer
Отсутствует


#define sizeof(x) rand()

Сообщений: 787
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: ВК для асинхронной обработки событий COM-объек
Ответ #8 - 12. Июля 2006 :: 08:15
Печать  
jbond писал(а) 12. Июля 2006 :: 08:07:
Т.е. можно обрабатывать события WMI в в 1С коде?

Наверное..... покажи как это делается в нормальных языках....
  

int getRandomNumber()&&{&&  return 4; //chosen by fair dice roll&&         //guaranteed to be random&&}
Наверх
 
IP записан
 
jbond
Full Member
***
Отсутствует


1С++ Programmer

Сообщений: 140
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: ВК для асинхронной обработки событий COM-объек
Ответ #9 - 12. Июля 2006 :: 08:37
Печать  
Взято из admscript.chm

Const POPUP_DURATION = 10
Const OK_BUTTON = 0
Set objWSHShell = Wscript.CreateObject("Wscript.Shell")
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
    & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set objSink = WScript.CreateObject("WbemScripting.SWbemSink","SINK_")
objWMIService.InstancesOfAsync objSink, "Win32_NTLogEvent"
Error = objWshShell.Popup("Starting event retrieval", POPUP_DURATION, _
    "Event Retrieval", OK_BUTTON)
Sub SINK_OnCompleted(iHResult, objErrorObject, objAsyncContext)
    WScript.Echo "Asynchronous operation is done."
End Sub
Sub SINK_OnObjectReady(objEvent, objAsyncContext)
    Wscript.Echo "Category: " & objEvent.Category
    Wscript.Echo "Computer Name: " & objEvent.ComputerName
    Wscript.Echo "Event Code: " & objEvent.EventCode
    Wscript.Echo "Message: " & objEvent.Message
    Wscript.Echo "Record Number: " & objEvent.RecordNumber
    Wscript.Echo "Source Name: " & objEvent.SourceName
    Wscript.Echo "Time Written: " & objEvent.TimeWritten
    Wscript.Echo "Event Type: " & objEvent.Type
    Wscript.Echo "User: " & objEvent.User
End Sub
  
Наверх
 
IP записан
 
jbond
Full Member
***
Отсутствует


1С++ Programmer

Сообщений: 140
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: ВК для асинхронной обработки событий COM-объек
Ответ #10 - 12. Июля 2006 :: 08:39
Печать  
Const POPUP_DURATION = 120
Const OK_BUTTON = 0
Set objWSHShell = Wscript.CreateObject("Wscript.Shell")
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
    & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set objSink = WScript.CreateObject("WbemScripting.SWbemSink","SINK_")
objWMIService.ExecQueryAsync objSink, "Select * from CIM_DataFile"
objPopup = objWshShell.Popup("Starting event retrieval", _
    POPUP_DURATION, "Event Retrieval", OK_BUTTON)
Sub SINK_OnObjectReady(objEvent, objAsyncContext)
    Wscript.Echo objEvent.Name
End Sub

     
  
Наверх
 
IP записан
 
steban
1c++ developer
Отсутствует


#define sizeof(x) rand()

Сообщений: 787
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: ВК для асинхронной обработки событий COM-объек
Ответ #11 - 12. Июля 2006 :: 08:51
Печать  
Попробовал отлавливать события изменения реестра - получилось.
[code]Перем Обработчик, ОбработчикСобытий;

Процедура ПриОткрытии()
     ЗагрузитьВнешнююКомпоненту("EventProxy.dll");
     ОбработчикСобытий=СоздатьОбъект("Addin.EventProxy");
     ОбработчикСобытий.ГлубинаБуфераСобытий=200;
     Обработчик=СоздатьОбъект("WbemScripting.SWbemSink");
     ОбработчикСобытий.Источник(Обработчик,"WbemScripting.SWbemSink","WMISink");
     personate}!\\.\root\default");
     objWMIServices.ExecNotificationQueryAsync(Обработчик,
     "Select * from RegistryValueChangeEvent Where
     |Hive = 'HKEY_LOCAL_MACHINE' and
     |KeyPath = 'SYSTEM\\ControlSet001\\Control' and
     |ValueName = 'CurrentUser'");
КонецПроцедуры      // ПриОткрытии

Процедура ОбработкаВнешнегоСобытия(Источник, Событие, Данные)
     Если (Источник="WMISink") и (Событие="OnObjectReady") Тогда
           Д=ЗначениеИзСтрокиВнутр(Данные);
           WMIObj=ОбработчикСобытий.ПолучитьОбъект(Д.ПолучитьЗначение(1));
           Сообщить(WMIObj.GetObjectText_());
     КонецЕсли;
КонецПроцедуры      // ОбработкаВнешнегоСобытия[/code]
« Последняя редакция: 07. Декабря 2006 :: 18:09 - steban »  

RegistryChangeEvent_001.ert ( 7 KB | Загрузки )

int getRandomNumber()&&{&&  return 4; //chosen by fair dice roll&&         //guaranteed to be random&&}
Наверх
 
IP записан
 
steban
1c++ developer
Отсутствует


#define sizeof(x) rand()

Сообщений: 787
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: ВК для асинхронной обработки событий COM-объек
Ответ #12 - 12. Июля 2006 :: 09:14
Печать  
steban писал(а) 12. Июля 2006 :: 06:27:
Принимаются предложения как покрасИвше реализовать сериализацию параметров (чтобы было легко разбирать строку).
А также чтобы обойти грабли с параметрами типа строка, в которой встречается разделитель "|"

Ну что никаких идей?
Может что-нибудь типа MIME?
  

int getRandomNumber()&&{&&  return 4; //chosen by fair dice roll&&         //guaranteed to be random&&}
Наверх
 
IP записан
 
Arta
1c++ power user
Отсутствует



Сообщений: 2537
Местоположение: Нижний Новгород
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: ВК для асинхронной обработки событий COM-объек
Ответ #13 - 12. Июля 2006 :: 10:02
Печать  
А может параметры передавать Структурой/СЗ или еще каким вариантом?
Уж очень не хочется парсить строку, к ошибкам в итоге может приведет...
  
Наверх
 
IP записан
 
steban
1c++ developer
Отсутствует


#define sizeof(x) rand()

Сообщений: 787
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: ВК для асинхронной обработки событий COM-объек
Ответ #14 - 12. Июля 2006 :: 10:21
Печать  
Arta писал(а) 12. Июля 2006 :: 10:02:
А может параметры передавать Структурой/СЗ
Код
Выбрать все
HRESULT ExternalEvent(BSTR bstrWho, BSTR bstrWhat, BSTR bstrData) 


Так определен интерфейс IAsyncEvent и я тут ничего поделать не могу.
Все параметры нужно утрамбовать в одну строку с возможностью получить их значения из этой строки (а возможно и имена). Так что структура не подойдет.

Может попробовать в таком формате, чтобы потом можно было сделать
Код
Выбрать все
СписокПараметров=ЗначениеИзСтрокиВнутр(Данные) 

?
  

int getRandomNumber()&&{&&  return 4; //chosen by fair dice roll&&         //guaranteed to be random&&}
Наверх
 
IP записан
 
Переключение на Главную Страницу Страницы: [1] 2 3 ... 5
ОтправитьПечать