Article ID: 894286
Article Last Modified on 11/16/2007
APPLIES TO
- Microsoft Exchange Server 2003 Standard Edition
- Microsoft Windows Server 2003, Standard Edition (32-bit x86)
- Microsoft Visual Studio .NET 2003 Professional Edition
Microsoft provides programming examples for illustration only, without warranty either expressed or implied. This includes, but is not limited to, the implied warranties of merchantability or fitness for a particular purpose. This article assumes that you are familiar with the programming language that is being demonstrated and with the tools that are used to create and to debug procedures. Microsoft support engineers can help explain the functionality of a particular procedure, but they will not modify these examples to provide added functionality or construct procedures to meet your specific requirements.
INTRODUCTION
This article contains an overview of how to write event sinks for SMTP events in managed code by using wrappers that obscure some of the details of communicating with the unmanaged server.
MORE INFORMATION
The following example illustrates how to write a managed OnArrival-type SMTP event sink that handles incoming commands in Microsoft Visual C# .NET and Microsoft Visual Basic .NET. Use this kind of event sink to handle incoming SMTP commands and messages and to process them as needed.
Generate unmanaged code to tie into the Event sink architecure in Microsoft Exchange
- Download and then extract the sample code from the following Microsoft Developer Network (MSDN) article: Note This MSDN article contains sample code for two libraries that you must have to connect to the unmanaged events that Exchange makes available.
- At a command prompt, run the following command:
Drive
:\\Program Files\Microsoft Visual Studio .NET\Common7\Tools\vsvars32.bat - From the folder of the interop, run Nmake.exe. Typically, this folder is \ManagedSinksWP\Interop.
- The interop DLL is Microsoft.Exchange.Transport.EventInterop.dll. Copy this file to the \ManagedSinksWP\Wrappers folder.
- Generate a new strong-named pair by using the following command:
SN.exe -k c:\key_wrapper.snk
Create a new AssemblyInfo file (AssemblyInfo.cs) in the wrappers folder by using the following code.
using System.Reflection; using System.Runtime.CompilerServices; [assembly: AssemblyTitle("")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("")] [assembly: AssemblyCopyright("")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyDelaySign(false)] [assembly: AssemblyKeyFile("c:\\key_wrapper.snk")] [assembly: AssemblyKeyName("")]
- In the same environment as the interop, run the following command from the wrappers folder:
csc /t:library /out:Microsoft.Exchange.Transport.EventWrappers.dll /r:Microsoft.Exchange.Transport.EventInterop.dll *.cs /unsafe
Generate and then compile the managed class to handle the event sink
- Start Microsoft Visual Studio .NET 2003.
- On the File menu, point to New, and then click Project.
- Under Project Types, click Visual C# Projects. Under Templates, click Class Library. Name the project "ManSMTPLib".
- In Solution Explorer, right-click the project, and then click Properties.
- In
Project
Property Pages dialog box, click the Configuration Properties folder. - Click Build, and then set the Register for COM interop setting to True. Click OK to close the
Project
Property Pages dialog box. - In Solution Explorer, right-click References, and then click Add Reference. Add references to the following two assemblies to your project:
- Microsoft.Exchange.Transport.EventInterop.dll
- Microsoft.Exchange.Transport.EventWrappers.dll
In Solution Explorer, right-click Class1.cs, click View Code, and then replace the generated code for the class by using the following code example.
Visual C# .NET codeusing System; using System.Diagnostics; using System.Runtime.InteropServices; using Microsoft.Exchange.Transport.EventInterop; using Microsoft.Exchange.Transport.EventWrappers; namespace SampleManagedSink { [Guid("XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX")] //For more information, see step 10. public class ExchSinkClass : IMailTransportSubmission, IEventIsCacheable { void IEventIsCacheable.IsCacheable() { } void IMailTransportSubmission.OnMessageSubmission( Microsoft.Exchange.Transport.EventInterop.MailMsg pIMailMsg , Microsoft.Exchange.Transport.EventInterop.IMailTransportNotify pINotify , System.IntPtr pvNotifyContext ) { try { string sSource = "dotNET Sample App"; string sLog = "Application"; string sEvent = "Sample Event"; if (!EventLog.SourceExists(sSource)) EventLog.CreateEventSource(sSource,sLog); EventLog.WriteEntry(sSource,sEvent); } finally { } } } }
Visual Basic .NET code
Imports System Imports System.Diagnostics Imports System.Runtime.InteropServices Imports Microsoft.Exchange.Transport.EventInterop Imports Microsoft.Exchange.Transport.EventWrappers Namespace SampleManagedSink ' For more information about the GUID, see step 10. <Guid("XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX")>Public Class ExchSinkClass Implements IMailTransportSubmission, IEventIsCacheable Public Sub IsCacheable() _ Implements IEventIsCacheable.IsCacheable End Sub Public Sub OnMessageSubmission(ByVal pIMailMsg As Microsoft.Exchange.Transport.EventInterop.MailMsg, ByVal pINotify As Microsoft.Exchange.Transport.EventInterop.IMailTransportNotify, ByVal pvNotifyContext As System.IntPtr) _ Implements IMailTransportSubmission.OnMessageSubmission Try Dim sSource As String = "Sample dotNET Exchange Sink Library" Dim sLog As String = "Application" Dim sEvent As String = "Sample dotNET Exchange Sink was triggered." If (Not EventLog.SourceExists(sSource)) Then EventLog.CreateEventSource(sSource, sLog) EventLog.WriteEntry(sSource, sEvent) Catch ' Put some code here to handle errors. ' Currently, any error will just be ignored. Finally End Try End Sub End Class End Namespace
- Generate a new GUID. To generate a new GUID, click Create GUID on the Tools menu.
- Click Registry Format, click New GUID, and then click Copy to copy the new GUID to the Clipboard. You will paste this new GUID into your code that you pasted in step 8. Make sure that you exclude the enclosing braces ({ }).
- Generate another strong-named key pair by using the following command:
SN.exe -k c:\key_sink.snk
In Solution Explorer, click AssemblyInfo.cs, right-click View Code, and then set the AssemblyKeyFile attribute with the following code:
Visual C# .NET code[assembly: AssemblyKeyFile("c:\\key_sink.snk")]
Visual Basic .NET code
<Assembly: AssemblyKeyFile("c:\key_sink.snk")>
- On the Build menu, click Build Solution. If the object is built on a non-production server, copy the event sink object to the production server, and then use the RegAsm.exe tool to register the event sink object on the server.
Implement the event sink and then register it into Exchange
- On the production server, open a Command Prompt window, and then type the following commands:
RegAsm.exe ManSMTPLib.dll /tlb: ManSMTPLib.tlb /codebase
RegAsm.exe Microsoft.Exchange.Transport.EventWrappers.dll /codebase
RegAsmexe Microsoft.Exchange.Transport.EventInterop.dll /codebase
Register the object on your production server as an event sink by using the Smtpreg.vbs script. To do this, use the following code example.
Visual C# .NET codecscript smtpreg.vbs /add 1 OnTransportSubmission "Sample managed sink" SampleManagedSink.ExchSinkClass "MAIL FROM=*" 28001
Visual Basic .NET code
cscript smtpreg.vbs /add 1 OnTransportSubmission "Sample managed sink" ManSMTPLib.SampleManagedSink.ExchSinkClass "MAIL FROM=*" 28001
To obtain the Smtpreg.vbs script, visit the following MSDN Web site:
REFERENCES
For more information, visit the following MSDN Web site:
Keywords: kbhowtomaster kbhowto kbinfo KB894286