[Exchange]ISMTPOnArrival_OnArrival 이벤트에 대해서

2004. 12. 17. 08:56일 이야기

일반적으로 Transport Event는 메세지가 전달(in, out)될때 익스체인지 서버에서 발생하는 이벤트입니다.

메일서버로 들어오는 메일이 있을때 여기다 특정한 단어를 붙이거나,
나가는 메일에 특정한 문장을 붙이는 경우에 사용을 많이 한다고 하더군요.

자료를 보면 이렇게 설명이 되어 있습니다.

A transport event occurs when some form of message data is transported into or out of the services.

특히, 이벤트에 대해서는 http://msdn.microsoft.com/library/techart/transportevents.htm 에 잘 설명이 되어 있습니다.

SMTP service event는 OnArrival 이벤트를 지원합니다.

이것은 메세지가 성공적으로 SMTP service에 도착하였고, drop directory나 store에 쓰여지기 전에 발생하는 이벤트 입니다.(제가 번역이 서툴러 원문을 실으면)

Occurs when a message has been successfully received by the SMTP service and before the messge has been written to the drop directory or Microsoft Exchange Server store. Message can be received either through the network(SMTP protocol) or through the SMTP service local pickup directory.

즉, 메일이 익스체인지 서버를 통과할때 이 이벤트가 발생하고, 이 이벤트가 발생할 때

어떤 특정한 작업( 예를 들면, 바이러스 검사나, 정크메일, 다른메일계정으로 전달, 메일내용중 특정 내용이 있는지 검사, 사용자의 메일검사등등)을 할 수가 있죠....메세지도 변경할 수 있고, 특정내용을 메일에 붙일수도 있고, 삭제할 수도 있고, (아마 삭제도 가능한걸로.....)

특히, 이 이벤트가 발생할 때 인수로써 ISMTPOnArrival_OnArrival(ByVal Msg As CDO.IMessage, EventStatus As CDO.CdoEventStatus)
메일 메세지의 내용(Msg)과 상태(EventStatus)를 이용해서 다양한 작업을 할 수가 있습니다.

그리고 이것에 관한 내용은 비교적 msdn에 자세하게 나와있습니다.
참고할 만한 곳은
http://msdn.microsoft.com/library/psdk/cdosys/_cdosys_ismtponarrival_interface.htm
http://msdn.microsoft.com/library/psdk/cdosys/_cdosys_sink_example_using_c_and_atl.htm
http://msdn.microsoft.com/library/psdk/cdosys/_cdosys_using_the_smtp_message_envelope_fields.htm
등등으로 많이 있는 편입니다.

저도 이때까지는 정말 별로 어렵지 않게 공부를 했었지요.
그런데, 막상 프로그램을 짜고 실행을 시켜 보니 여러가지 어려운 점이 많더군요.
특히, COM이니 IDL이니 처음듣는 말들이 많이 나왔고...
사실 저는 C++로 프로그램을 짜기 때문에 그런 부분은 상당히 이해하기 어려운 부분이 많았습니다.

특히, 프로그램을 다 짜고, 실행을 시켰는데도 전혀 이벤트가 발생하지 않는 것이 처음으로 격는 가장 큰 난관이지요....
문제를 해결하는 방법을 간단히 적어보면

1) 프로젝트를 ActiveXDll로 만들었는지를 확인한다.  (사실 다른거로 해봤는데 안되더라구요.... 다른 내용을 아시는 분은 리플달아 주시길.....^^)
2) 프로젝트 - 참조 에서 CDO를 참조했는지확인해 보세요
3) Implements CDO.ISMTPOnArrival 가 빠지지는 않았는지 확인해 보세요
4) ***.dll 화일을 만들었는지 확인해 본다. (메뉴 - 파일 - ***.dll만들기 를 이용하여 dll화일을 만듭니다.)
5) .dll화일을 등록한다. (regsvr32 화일의 전체경로***.dll 이렇게 등록하면 됩니다. 화일경로 다음의 내용은 여러분의 dll화일의 경로를 적어 줍니다.)
등록된 dll을 없애고 싶으면 전체경로 앞에 /u를 붙이면 됩니다.
6) cscript smtpreg.vbs /add 1 OnArrival 인스턴스이름 등록시킨프로젝트이름 프로퍼티 이렇게 하여 바인드를 등록하여 줍니다. ( 내용이 너무 빈약하군요.....)

바인드 등록과 싱크(Sink)에 대한 자세한 설명은 http://msdn.microsoft.com/library/psdk/cdosys/_cdosys_registering_bindings.htm 을 참고하세요... 자세한 설명이 나와있어요.....^^
unregistering binding에 대한 내용은
http://msdn.microsoft.com/library/psdk/cdosys/_cdosys_unregistering_bindings.htm 에 나와 있습니다.

저도 잘 모르는 내용을 아는체 하며 쓰자니 내용도 너무 빈약하고 횡설수설이군요...
참고로 제가 익스체인지를 공부하면서 참고로 한 책인
"Programming Collaborative Web Application with microsoft Exchange 2000 Server " 의 내용중 제가 번역(?)한 내용을 올려드리니 참고하시기 바랍니다.

그리고, 제가 적은 내용 중에서 틀린 내용이 있다면 메일 주시면 감사하겠습니다.
저도 시작한지가 얼마되지 않아 너무나 아는 부분이 없습니다.
제가 이 글을 올리는 이유는 저같이 두달동안 회사 눈치밥 먹으며 맨땅에 해딩하는 분이 없기를 바라는 마음입니다.
자료를 가지고 계시거나, 저에게 가르침을 주실분은 언제나 환영이며, 제 메일 주소는 karma95@shinbiro.com 입니다.

Event Sink는 Event가 발생할 때 동작하는 코드를 포함하는 Microsoft Active DLL과 같은 Component Object Model(COM) component이다. Event Sink는 synchronous, asynchronous, system event와 상호동작(react)하는 실제 프로시져(procedures)로 구성된다. Visual Basic, Visual C++, script를 이용하여 event sink를 만들 수 있으며, event sink는 반드시 server에서 동작하여야 하므로, sink내에서 Exchange를 위한 ActiveX Data Object(ADO)와 collaboration Data Object(CDO) 모두를 사용할 수 있다.

Event에 반응하기 위해서, event가 발생할 때마다 실행되는 코드를 포함하는 event sink를 만들어야 한다.
Visual Basic으로 event sink를 만들기 위해서, ActiveX DLL project를 생성하고, class module내에 event procedure를 작성하고, event sink를 서버상의 COM+ application으로 등록해 주어야 한다. 단지 ActiveX DLL을 server상에서 COM+ component로 사용하기 때문에 ActiveX EXE보다는 ActiveX DLL을 사용한다.

1) Creating the Dynamic-Link Library
Event sink를 Visual Basic에서 생성하기 위해서, 새로운 ActiveX DLL project를 생성

2) Setting the References
새로운 DLL을 생성한 이후, Project 메뉴의 References(참조)를 선택하여 ExOLEDB Type Library(exoledb.dll)을 선택한다.
ExOLEDB library를 선택함으로써, event procedure를 생성할 수 있다.
Event sink가 어떤 작업을 할 것인지에 따라, 다음과 같은 object library를 일부 혹은 전부 사용할 수 있다.
- Microsoft ActiveX Data Objects 2.5 Library(adodb.dll).
event를 발생시키는 item에 대한 property 값을 읽어오거나 설정
- Microsoft CDO for Exchange 2000 Library(codex.dll) .
확인메시지(notification message)를 보내거나, contacts, messages, appointment와 같은 현재 collaboration object와 상호작용(interact)
- Microsoft CDO for Exchange Management Library(cdoexm.dll)
User’s mailbox에 대한 정보를 받기를 원할 때 사용
- Active DS Type Library(activeds.tlb)
Domain, server, user에 대한 동적할당을 위한 코드를 작성하고자 할 때 사용

3) Building the Event Procedures
적합한 Interface를 실행(implement)함으로써 event procedures를 생성하고, 적합한 event method를 호출한다. event method를 사용하기 위해서, 먼저 class module에서 event interface를 실행하여야 한다. class module의 선언부에서, 실행될 event interface를 Implements 구문으로 지정해 준다. 예를 들면
Implements Exoledb.IexStoreSyncEvents
Implements CDO.ISMTPOnArrival
Event가 제공되면 Object combo box에 interface의 이름이 나타나고, Procedure combo box에 제공된 interface의 event method들의 이름이 나타난다.
Visual Basic에서 DLL파일을 성공적으로 만들기 위해서는 제공된 interface상의 각각의 method에 대하여 event procedure를 만들어 주어야 한다. 그렇지 않으면, DLL이 정확하게 compile되지 않을 수 있다.

Installing the Event Sink as a COM+ Application[1]

Event sink procedure를 생성함으로써, event sink를 server 상의 COM+ application으로 설치할 준비가 된 것이다. event sink를 install하기 위해서는 다음 3과정을 거친다.
1) .dll파일을 만든다( making the .dll files)
2) 서버상에 .dll파일을 등록한다.(registering the .dll file on the server)
3) DLL interface와 method에 대한 COM component를 생성한다.
( creating the COM components for the DLL interfaces and methods)

1) Making the .DLL file
Event sink를 access가 가능하도록 하기위해서, Exchange server computer상에 .dll 파일을 생성하고, 등록(register)해 주어야 한다.

Visual Basic상의 event sink project에서 .dll파일을 만들기 위해서는 다음과정을 거친다.
① File 메뉴에서 Make [프로젝트이름].dll 을 클릭한다.
② Make Project 대화상자가 나타나면, file path와 .dll파일의 이름을 선택한다.
③ 임의의 폴더에 만들 수 있으나, 물리적으로 server machine과 동일한 위치가 아니어야 한다.(it must physically reside on the server machine)

2) Registering the .DLL file
.dll file을 생성한 이후에, server에 등록할 수 있다. Regsvr32 Tool(Regsvr32.exe)를 이용하여 .dll파일을 등록하거나 등록해지 할 수 있다. RegSvr32.exe는 다음과 같은 command-line option을 가진다.

Regsvr32 [/u] [/n] [/i[:cmdline]] dllname
/u - Unregister server
/i - Call DllInstall passing it an optional [cmdline];
when used with /u calls dll uninstall
/n - do not call DllRegisterServer; this option must
be used with /i
Regsvr32.exe를 실행하기 위해서는 command prompt(명령창)을 이용하거나, 시작의 실행을 클릭한 후 다음과 같이 쓴다.
Regsvr32.exe “[full dll path]”
Full dll path는 폴더의 경로와 파일의 이름이 모두 들어가야 한다. 예를 들면
Regsvr32.exe “D:oo ManagementEvent SinkooMgtEventSink.dll”
하면 되고, .dll파일을 unregister하기 위해서는 /u옵션을 포함하면 된다.
Regsvr32.exe /u “D:oo ManagementEvent SinkooMgtEventSink.dll”

--------------------------------------------------------------------------------

[1] “Programming Collaborative Web Applications with Microsoft Exchange 2000 Server” Mindy Martin, Microsoft Press, 2000, p448-457