OUTBOX: Introduction to Exchange Store Event Sinks Part 1

This is the first part of a two part series on getting started with and understanding Exchange Store Event Sinks. This is especially important for all of those people moving from Exchange 5.5 to Exchange 2003, there is a lot to learn with store events versus Exchange Event Service Scripts.


Building Applications Using Web Storage System Events: Overview

This is a must read to understand the basics of the web store, what events are available, and how registration items are created.



Types of Events


The above article talks about synchronous and asynchronous event sinks, these are two of the three types of event sinks: synchronous, asynchronous, and system event sinks. It is important to drive home the impact of deciding between synchronous and synchronous event sinks, this is one of the first things you should consider when you start planning your event sink solution. 


Synchronous sinks (OnSyncSave, OnSyncDelete) can be very draining on your Exchange server resources as they block until finished (hence synchronous), you want to keep these sinks as quick and simple as possible. They are typically used in cases where you want to validate an item before a save or prevent a delete. You can access items before they are actually committed to a folder using these sinks. You can also abort save and delete operations initiated from other clients and code using these sinks.


Asynchronous sinks (OnSave, OnDelete) don't block any Exchange threads and impact the server far less. The trade off here is that you are given read-only access to the item, this is more for a reactionary type of solution. If an item is saved to this folder with a certain set of criteria, then do something. Many logging or archiving sinks are implementing asynchronously because they don't need to happen before a commit or happen in real time.


System sinks (OnTimer, OnMdbStartup, OnMdbShutdown), the most common being OnTimer, are used for non-item related firing. Timer events are typically used for processing items that may have aged out. If you are doing a workflow application and want to sent notification on expired items you could use an OnTimer event sink to fire every so often and check a folder. You also have events for OnMdbStartup and OnMdbShutdown which fire when the store is started and stopped. Typically you will see these to check the integrity of an items on start up. Note that these events are fired asynchronously as well.


Store Event Sink Bit Flags


Whenever you are processing events (especially the Save events) you will want to know why the event fired. Is this a new item? Is the item being updated? Was the item moved? You can determine this by doing a bitwise comparison on the event sink bit flags which are passed to each of the event sink interfaces. This is especially important to OnSyncSave which is an event that can get fired a lot so you want to make sure you do processing when you need to and do a minimum about to determine whether the event is important or not. Below is a description of the bit masks and what they mean.




Registering Event Sinks


Understanding how and where to register your event sink is also very important. Again this is especially noteworthy for synchronous events. With the bit flags once an event has fired you can determine in your event sink code whether or not that event is meaningful to you, however making this determination requires the event to fire which has some expense on the Exchange. You will want to leverage registration scope, priority, and criteria to ensure that your event sink has the least impact possible on your Exchange server. Regevent.vbs is a very helpful VBScript that encapsulates the code behind creating, deleting, and enumerating event registrations, you interact with it through command line parameters.


Event Registration Overview



Event Registration Items



Managing Event Registrations with RegEvent.vbs



Step By Step Guides


Creating a COM+ Event Sink Application



Building Managed Event Sink DLLs





288156 How To Create an Exchange 2000 Store Event Sink in Visual C++

There are examples of implementing each of the event sinks on MSDN. Below are links to the OnSave event implemented in managed and unmanaged VB code. Look in the navigation in the left pane for more implementations of the other events.


Implementing a Managed OnSave Event Sink



Implementing an OnSave Event Sink



Exchange Store Event Sink Criteria

This article provides some quick notes about Exchange Event Sinks, the technologies that they support and their limitations. This is a very good quick reference for a lot of different implementation questions.


> Note development criteria, sinks can be developed in nearly any Microsoft programming language including VBScript, VB6, C/C++, and managed (.NET) code.

> Note security criteria, sinks must run within a COM+ application and always run in the context of the user specified in the COM+ configuration. The user running the event sink must have permission to read and write to the folders where the sink will run.

> Note deployment criteria, event sink are deployed by setting up the COM+ application and creating a registration item that resides hidden in the folder that the sink is to run. Sinks cannot be run across servers.


Unsupported Exchange Store Event Interfaces


Looking through our libraries shipped with the Exchange SDK you might come across some event interfaces not discussed here. They are listed in the link below and are not supported or recommended to be implemented.



This information should give you a good start towards understanding Exchange Store Event Sinks and be a good reference for the useful links on MSDN. The key is to start playing with it in a test environment to understand how all this works together.  I will follow up with a part two tomorrow which will include information on CDOEX, ADO, and working calendaring items.

Updated 1/22/2009 – Fixed and removed some broken links.