|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
|
Announcements
Want a new Job?
Chapters
Services
Feature Zones
|
IntroductionWhen I had a project to develop a Managed Event Sink for Exchange Server Store, I hunted for some information over the web; surprisingly I could not get links that would really help me to get started immediately! Later, it took some time to get an outline on how to create managed event sinks, and at last, when I cracked it, I thought I shall share it :-) Hence, this article. This article is targeted at intermediate users who have already developed event sinks in the COM World using VB/VC++ and others. If you are new to developing Event Sinks, I suggest that you read “Event Sinks” in the Exchange SDK documentation. The Exchange SDK has an excellent description on Event sinks. Anyways, I shall give a basic introduction to the Event Sinks. So, what does an Event Sink Really mean? Event Sink is a piece of code that gets triggered on predetermined events. A more classic jargon I can give as an example is “Hooks”, i.e. we hook and eye to an event [e.g.: a keyboard or event or a mouse event], and when the event occurs our custom code executes first and later the control is passed back to the original event if required. Exchange Store EventsA similar concept is provided by Exchange Server, where in you can hook[!] or create event sinks for the events occurring at Exchange Server. Some of the events that can be hooked to are 1. Synchronous Events – Events that get triggered before an item [Mail, appointments, documents, tasks etc] is committed to the exchange server. These events pauses the exchange store thread until the event sink finishes executing. No other process can access the item during this event sink execution period as, event sink has the exclusive control over the items. Following are the events that are classified as Synchronous events.
2.Asynchronous Events – Events that get fired after an item is committed to the exchange server. These Async events do not block the exchange store thread. Following are the Asynchronous events.
3.System Events– Events that get fired based on some system wide actions on exchange server, the following are the system events.
Synchronous and Asynchronous events are tied to a specific item or folder in the exchange store. All these events are exposed in the Exchange CDOEX library [cdoex.dll] as interfaces. Fig 1.1 shows the object browser window of the CDOEX library.
So What? What Can I Build?Some of the applications that can be developed using Event Sink are,
Let's Code Now...Fire up your VS.NET and choose new C# Class library project and name the project, hmm... let’s call it as “MyEventSink”. On the Solution explorer, right click the project name and choose Properties, on the Project Properties page choose configuration properties choose build and set Register for COM Interop to
Now, Copy the below files to the MyEventSink bin directory
Open up the VS.NET Command Prompt and navigate to MyEventSink bin folder, and create strong name keys for the above libraries. Key-in the following commands
We need to create interop assemblies of the above library, in order to, create the interop assemblies we shall use the tlbimp tool. Key-in the following commands to create 3 interop assemblies.
Copy these interop dll files to the debug folder. Switch back to VS.NET and add references to the above created interop DLL files. Modify the following attributes on the AssemblyInfo.cs Under General Information section, modify [assembly: AssemblyTitle("MyEventSink")] [assembly: AssemblyDescription("My Event Sink - Logu")] at version information section, create a new GUID and add [assembly: Guid("44E6847A-0012-42af-A317-1E1A9F0C853D")] at sign information section, modify [assembly: AssemblyDelaySign(false)]
[assembly: AssemblyKeyFile("MyEventSink.key")]
[assembly: AssemblyKeyName("MyEventSink")]
Now, Choose Project Properties and set the “Wrapper assembly key file” to MyEventSink.key and “Wrapper assembly Key Name” to “My Event Sink”
Start the VS.NET Command Prompt and change directory to your project directory, and create a key, key-in the following, > sn –k MyEventSink.key Switch back to VS.NET IDE, and change the file name of class1.cs to a new name like “ExchEventSink.cs”, double click the .cs file to open. Add, using CDO;
using ADODB;
modify the class definition code to resemble like below, [Guid("16369924-5F32-4E26-AE89-8308B5C162E2")]
public class ExchEventSink: ServicedComponent , IExStoreAsyncEvents
{
public string ClassID = "F92EFC3A-FDD8-4225-B005-13FD3D5D54D1";
public string InterfaceId = "704A413F-F8FE-476B-9206-69AB6300D752";
public string EventsId = "DCC71BD5-6627-4FBF-BB5A-DB8FEA1EB177";
if you observe the above code, you can notice that we are implementing the public void OnSave(IExStoreEventInfo pEventInfo,
string bstrURLItem, int lFlags)
{
try
{
if(System.Convert.ToBoolean(lFlags))
{
CDO.Message iMessage=new
CDO.MessageClass();
string sFrom; string sDate;
try
{
iMessage.DataSource.Open(bstrURLItem,null,
ADODB.ConnectModeEnum.adModeRead,
ADODB.RecordCreateOptionsEnum.adFailIfNotExists,
ADODB.RecordOpenOptionsEnum.adOpenSource,"","");
FileStream fs = new FileStream(
@"c:\temp\MyEventSink.log",FileMode.OpenOrCreate);
fs.Write(Encoding.ASCII.GetBytes(bstrURLItem),0,
bstrURLItem.Length);
sFrom = iMessage.From;
sDate = iMessage.ReceivedTime.ToString();
fs.Write(Encoding.ASCII.GetBytes(sFrom),0,sFrom.Length);
fs.Write(Encoding.ASCII.GetBytes(sDate),0,sDate.Length);
fs.Close();
}
catch (Exception ex)
{
throw (ex);
}
}
}
catch (Exception ex)
{
throw (ex);
}
}
public void OnDelete(IExStoreEventInfo pEventInfo, string bstrURLItem, int lFlags) { try { } catch(Exception ex) {throw (ex);} } #endregion In the above code, we are processing an exchange item on onsave method, and we create a LOG file. This is a simple code example; modify it to your requirements. [Check Exchange SDK on the lflags as this is very important, www.microsoft.com/exchange ] Compile the class, you have your event sink component ready. Now, Open Component Services, under COM+ applications create new empty application and name it as “MyEventSink”, then, expand, components under MyEventSink and click “import components that are already registered” And choose “MyEventSink.ExchEventSink” from the populated list.
Now, the event sink component is registered to the server.
We are done on our development part. Now, you can bind the component to any folder of exchange store, there are multiple ways to do this, I prefer the following, RegEvent.vbs - I’ve attached the VBS file along with the download zip, this script creates the event registration for the specified folder. The following command binds the event sink to my inbox folder,
I’ve included the vbs file along with the zip file, you can also get more information about this at [ www.microsoft.com/exchange ] Exchange Explorer – this is a tool you get with Exchange SDK [check www.microsoft.com/exchange ] Alternatively, you can build your own event registration [that’s a separate article by itself :-) ] At last, we are done... We have created our own Managed Exchange Store Event Sink. You can also implement the Synchronous Events and the System Events as same as we have implemented the Asynchronous events.
|
||||||||||||||||||||||