<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>mstehle: The CDOs and CDONTS of Messaging Development : Transport Agents</title><link>http://blogs.msdn.com/mstehle/archive/tags/Transport+Agents/default.aspx</link><description>Tags: Transport Agents</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>HOWTO: Sample Transport Agent – Add Headers, Categories, MAPI Props, Even Uses a Fork!</title><link>http://blogs.msdn.com/mstehle/archive/2009/01/13/howto-sample-transport-agent-add-headers-categories-mapi-props-even-uses-a-fork.aspx</link><pubDate>Wed, 14 Jan 2009 00:50:33 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9317264</guid><dc:creator>mstehle</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/mstehle/comments/9317264.aspx</comments><wfw:commentRss>http://blogs.msdn.com/mstehle/commentrss.aspx?PostID=9317264</wfw:commentRss><wfw:comment>http://blogs.msdn.com/mstehle/rsscomments.aspx?PostID=9317264</wfw:comment><description>&lt;p&gt;&lt;span style="color: blue"&gt;&lt;font color="#000000" size="2" face="Arial"&gt;Welcome to my first in depth Exchange Transport Agent sample!&amp;#160; If you are not familiar with Exchange Transport Agents &lt;a href="http://msexchangeteam.com/archive/2006/12/04/431755.aspx"&gt;this&lt;/a&gt; blog post is a great place to start.&amp;#160; I created a sample Transport Agent for a customer a while ago that I recently added commenting to and cleaned up so it could serve as a general demo &lt;/font&gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&lt;font color="#000000" size="2" face="Arial"&gt;suitable for this blog. The focus of this sample is to illustrate a several techniques but no necessarily serve as a template or best practice for writing transport agents in general.&amp;#160; The key techniques illustrated are:&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&lt;span style="color: blue"&gt;&lt;font color="#000000" size="2" face="Arial"&gt;Forking a message in the “OnSubmittedMessage” event to process a messages individually for each recipient.&lt;/font&gt;&lt;/span&gt;&lt;/li&gt;    &lt;li&gt;&lt;span style="color: blue"&gt;&lt;font color="#000000" size="2" face="Arial"&gt;Adding a custom header to a message.&lt;/font&gt;&lt;/span&gt;&lt;/li&gt;    &lt;li&gt;&lt;span style="color: blue"&gt;&lt;font color="#000000" size="2" face="Arial"&gt;Adding a Keywords (also known as Category) header to a message&lt;/font&gt;&lt;/span&gt;&lt;/li&gt;    &lt;li&gt;&lt;span style="color: blue"&gt;&lt;font color="#000000" size="2" face="Arial"&gt;Adding a custom named property to a MAPI message&lt;/font&gt;&lt;/span&gt;&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;&lt;span style="color: blue"&gt;&lt;font color="#000000" size="2" face="Arial"&gt;The comments in the code speak for themselves so I won’t walk through it all.&amp;#160; There are two very important notes regarding the Keyword header and adding MAPI properties that I want to emphasize though.&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="color: blue"&gt;&lt;strong&gt;&lt;font color="#000000" size="2" face="Arial"&gt;The Keywords Header is Removed By Default&lt;/font&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="color: blue"&gt;&lt;font color="#000000" size="2" face="Arial"&gt;If you are you trying to add the Keywords header in a transport agent or even just when sending MIME messages to Exchange 2007 keep in mind that this header is translated into Categories which are removed by default during content conversion.&amp;#160; If you really need this functionality though, you can turn this off using the Set-TransportConfig cmdlet and setting ClearCategories to $false.&amp;#160; Click &lt;a href="http://technet.microsoft.com/en-us/library/bb124151.aspx"&gt;here&lt;/a&gt; to read more.&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="color: blue"&gt;&lt;strong&gt;&lt;font color="#000000" size="2" face="Arial"&gt;If You Don’t Get TNEF, You Don’t Have TNEF&lt;/font&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="color: blue"&gt;&lt;font color="#000000" size="2" face="Arial"&gt;There is no API to convert MIME messages to TNEF within a transport agent.&amp;#160; The TNEF body part must be a full representation of the message being submitted to Exchange.&amp;#160; You can’t have a complex MIME message with a TNEF body part that simply adds a MAPI property or two.&amp;#160; Messages that are submitted from outside the organization will mostly like not have TNEF, there is no mechanism to create a representative TNEF body part for these messages and then append properties.&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="color: blue"&gt;&lt;font color="#000000" size="2" face="Arial"&gt;One final note is that this sample logs information out to a text file on the system.&amp;#160; Keep in mind that transport agents run in the context of the Exchange Transport Service which is typically Network Service.&amp;#160; In this case, the Network Service account would need write permissions to whatever folder the log file is configured to write to.&amp;#160; &lt;/font&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="color: blue"&gt;&lt;font color="#000000" size="2" face="Arial"&gt;Enjoy…&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;  &lt;ol&gt;   &lt;p&gt;&lt;span style="color: blue"&gt;&lt;font color="#000000" size="2" face="Arial"&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt; &lt;/ol&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;using &lt;/span&gt;System;
&lt;span style="color: blue"&gt;using &lt;/span&gt;System.Collections.Generic;
&lt;span style="color: blue"&gt;using &lt;/span&gt;System.Text;
&lt;span style="color: blue"&gt;using &lt;/span&gt;System.IO;
&lt;span style="color: blue"&gt;using &lt;/span&gt;Microsoft.Exchange.Data.Transport;
&lt;span style="color: blue"&gt;using &lt;/span&gt;Microsoft.Exchange.Data.Transport.Routing;
&lt;span style="color: blue"&gt;using &lt;/span&gt;Microsoft.Exchange.Data.Common;
&lt;span style="color: blue"&gt;using &lt;/span&gt;Microsoft.Exchange.Data.Mime;
&lt;span style="color: blue"&gt;using &lt;/span&gt;Microsoft.Exchange.Data.ContentTypes.Tnef;

&lt;span style="color: blue"&gt;namespace &lt;/span&gt;MyRoutingAgent
{

    &lt;span style="color: blue"&gt;public sealed class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;MyRoutingAgentFactory &lt;/span&gt;: &lt;span style="color: #2b91af"&gt;RoutingAgentFactory
    &lt;/span&gt;{
        &lt;span style="color: blue"&gt;public override &lt;/span&gt;&lt;span style="color: #2b91af"&gt;RoutingAgent &lt;/span&gt;CreateAgent(&lt;span style="color: #2b91af"&gt;SmtpServer &lt;/span&gt;server)
        {
            &lt;span style="color: blue"&gt;return new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;MyRoutingAgent&lt;/span&gt;();
        }
    }

    &lt;span style="color: blue"&gt;public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;MyRoutingAgent &lt;/span&gt;: &lt;span style="color: #2b91af"&gt;RoutingAgent
    &lt;/span&gt;{
        &lt;span style="color: green"&gt;// Place this text in the subject to test the agent
        &lt;/span&gt;&lt;span style="color: blue"&gt;public const string &lt;/span&gt;TEST_TOKEN = &lt;span style="color: #a31515"&gt;&amp;quot;[TEST]&amp;quot;&lt;/span&gt;;
        &lt;span style="color: blue"&gt;public const string &lt;/span&gt;LOG_FILE_PATH = &lt;span style="color: #a31515"&gt;@&amp;quot;C:\Users\Administrator\Desktop\MyRoutingAgent\MyRoutingAgent.log&amp;quot;&lt;/span&gt;;

        &lt;span style="color: blue"&gt;public &lt;/span&gt;MyRoutingAgent()
        {
            &lt;span style="color: blue"&gt;this&lt;/span&gt;.OnRoutedMessage += &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;RoutedMessageEventHandler&lt;/span&gt;(MyRoutingAgent_OnRoutedMessage);
            &lt;span style="color: blue"&gt;this&lt;/span&gt;.OnSubmittedMessage += &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;SubmittedMessageEventHandler&lt;/span&gt;(MyRoutingAgent_OnSubmittedMessage);
            &lt;span style="color: blue"&gt;this&lt;/span&gt;.OnResolvedMessage += &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ResolvedMessageEventHandler&lt;/span&gt;(MyRoutingAgent_OnResolvedMessage);
        }

        &lt;span style="color: blue"&gt;void &lt;/span&gt;MyRoutingAgent_OnSubmittedMessage(&lt;span style="color: #2b91af"&gt;SubmittedMessageEventSource &lt;/span&gt;source, &lt;span style="color: #2b91af"&gt;QueuedMessageEventArgs &lt;/span&gt;e)
        {
            &lt;span style="color: green"&gt;// Don't process EVERY message...
            &lt;/span&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(e.MailItem.Message.Subject.Contains(TEST_TOKEN))
            {
                &lt;span style="color: green"&gt;// If we have multiple recipients, fork the message to process each recipient seperately...
                &lt;/span&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(e.MailItem.Recipients.Count &amp;gt; 1)
                {
                    LogMessage(&lt;span style="color: #a31515"&gt;&amp;quot;OnSubmittedMessage&amp;quot;&lt;/span&gt;, e.MailItem, &lt;span style="color: #a31515"&gt;&amp;quot;Forking message with &amp;quot; &lt;/span&gt;+ e.MailItem.Recipients.Count + &lt;span style="color: #a31515"&gt;&amp;quot; recipients.&amp;quot;&lt;/span&gt;);

                    &lt;span style="color: blue"&gt;int &lt;/span&gt;count = 0;
                    &lt;span style="color: blue"&gt;while &lt;/span&gt;(e.MailItem.Recipients.Count &amp;gt; 1)
                    {
                        &lt;span style="color: green"&gt;// Create an individual forked message for each recipient...
                        &lt;/span&gt;&lt;span style="color: #2b91af"&gt;EnvelopeRecipient &lt;/span&gt;recip = e.MailItem.Recipients[e.MailItem.Recipients.Count - 1];
                        &lt;span style="color: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;EnvelopeRecipient&lt;/span&gt;&amp;gt; recips = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;EnvelopeRecipient&lt;/span&gt;&amp;gt;();
                        recips.Add(recip);
                        source.Fork(recips);
                        count++;
                    }

                    &lt;span style="color: green"&gt;// This should always be one.
                    &lt;/span&gt;LogMessage(&lt;span style="color: #a31515"&gt;&amp;quot;OnSubmittedMessage&amp;quot;&lt;/span&gt;, e.MailItem, &lt;span style="color: #a31515"&gt;&amp;quot;Forked &amp;quot; &lt;/span&gt;+ count + &lt;span style="color: #a31515"&gt;&amp;quot; messages.&amp;quot;&lt;/span&gt;);
                }
                &lt;span style="color: blue"&gt;else
                &lt;/span&gt;{
                    LogMessage(&lt;span style="color: #a31515"&gt;&amp;quot;OnSubmittedMessage&amp;quot;&lt;/span&gt;, e.MailItem, &lt;span style="color: #a31515"&gt;&amp;quot;Single recipient, no forking needed.&amp;quot;&lt;/span&gt;);
                }
            }
        }

        &lt;span style="color: blue"&gt;void &lt;/span&gt;MyRoutingAgent_OnResolvedMessage(&lt;span style="color: #2b91af"&gt;ResolvedMessageEventSource &lt;/span&gt;source, &lt;span style="color: #2b91af"&gt;QueuedMessageEventArgs &lt;/span&gt;e)
        {
            &lt;span style="color: green"&gt;// Don't process EVERY message...
            &lt;/span&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(e.MailItem.Message.Subject.Contains(TEST_TOKEN))
            {
                &lt;span style="color: #2b91af"&gt;MimePart &lt;/span&gt;tnefPart = e.MailItem.Message.TnefPart;
                &lt;span style="color: blue"&gt;if &lt;/span&gt;(tnefPart != &lt;span style="color: blue"&gt;null&lt;/span&gt;)
                {
                    LogMessage(&lt;span style="color: #a31515"&gt;&amp;quot;OnResolvedMessage&amp;quot;&lt;/span&gt;, e.MailItem, &lt;span style="color: #a31515"&gt;&amp;quot;TNEF&amp;quot;&lt;/span&gt;);
                }
                &lt;span style="color: blue"&gt;else
                &lt;/span&gt;{
                    LogMessage(&lt;span style="color: #a31515"&gt;&amp;quot;OnResolvedMessage&amp;quot;&lt;/span&gt;, e.MailItem, &lt;span style="color: #a31515"&gt;&amp;quot;No TNEF&amp;quot;&lt;/span&gt;);
                }
            }
        }
        
        &lt;span style="color: blue"&gt;void &lt;/span&gt;MyRoutingAgent_OnRoutedMessage(&lt;span style="color: #2b91af"&gt;RoutedMessageEventSource &lt;/span&gt;source, &lt;span style="color: #2b91af"&gt;QueuedMessageEventArgs &lt;/span&gt;e)
        {
            &lt;span style="color: green"&gt;// Don't process EVERY message...
            &lt;/span&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(e.MailItem.Message.Subject.Contains(TEST_TOKEN))
            {
                &lt;span style="color: blue"&gt;if &lt;/span&gt;(e.MailItem.Recipients.Count == 1)
                {
                    LogMessage(&lt;span style="color: #a31515"&gt;&amp;quot;OnRoutedMessage&amp;quot;&lt;/span&gt;, e.MailItem, &lt;span style="color: #a31515"&gt;&amp;quot;Processing message sent to &amp;quot; &lt;/span&gt;+ e.MailItem.Recipients[0].Address.LocalPart + &lt;span style="color: #a31515"&gt;&amp;quot;.&amp;quot;&lt;/span&gt;);

                    &lt;span style="color: green"&gt;// If we haven't already processed this message...
                    &lt;/span&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(e.MailItem.Message.MimeDocument.RootPart.Headers.FindFirst(&lt;span style="color: #a31515"&gt;&amp;quot;MyHeader&amp;quot;&lt;/span&gt;) == &lt;span style="color: blue"&gt;null&lt;/span&gt;)
                    {
                        ProcessMailItem(e.MailItem);
                    }
                    &lt;span style="color: blue"&gt;else
                    &lt;/span&gt;{
                        LogMessage(&lt;span style="color: #a31515"&gt;&amp;quot;OnRoutedMessage&amp;quot;&lt;/span&gt;, e.MailItem, &lt;span style="color: #a31515"&gt;&amp;quot;Already processed this message, skipping.&amp;quot;&lt;/span&gt;);
                    }
                }
                &lt;span style="color: blue"&gt;else
                &lt;/span&gt;{
                    LogMessage(&lt;span style="color: #a31515"&gt;&amp;quot;OnRoutedMessage&amp;quot;&lt;/span&gt;, e.MailItem, &lt;span style="color: #a31515"&gt;&amp;quot;Unexpected number of recipients, &amp;quot; &lt;/span&gt;+ e.MailItem.Recipients.Count.ToString() + &lt;span style="color: #a31515"&gt;&amp;quot;.&amp;quot;&lt;/span&gt;);
                }
            }
        }

        &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
        /// &lt;/span&gt;&lt;span style="color: green"&gt;Add a custom header, keyword header, and MAPI
        &lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;named property into PS_PUBLIC_STRINGS if there
        &lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;is a TNEF body part.
        &lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
        &lt;/span&gt;&lt;span style="color: blue"&gt;private void &lt;/span&gt;ProcessMailItem(&lt;span style="color: #2b91af"&gt;MailItem &lt;/span&gt;item)
        {
            &lt;span style="color: green"&gt;// Modify the subject of this message to ensure the
            // fork worked.  Append the first recipient name to the 
            // subject.  This should match the mailbox name the
            // message is delivered to.
            &lt;/span&gt;item.Message.Subject = item.Message.Subject + &lt;span style="color: #a31515"&gt;&amp;quot;| To: &amp;quot; &lt;/span&gt;+ item.Recipients[0].Address.LocalPart;

            &lt;span style="color: #2b91af"&gt;MimeDocument &lt;/span&gt;mdMimeDoc = item.Message.MimeDocument;
            &lt;span style="color: #2b91af"&gt;HeaderList &lt;/span&gt;hlHeaderlist = mdMimeDoc.RootPart.Headers;
            &lt;span style="color: #2b91af"&gt;MimeNode &lt;/span&gt;lhLasterHeader = hlHeaderlist.LastChild;

            &lt;span style="color: green"&gt;// Add a custom header
            &lt;/span&gt;&lt;span style="color: #2b91af"&gt;TextHeader &lt;/span&gt;nhNewHeader = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;TextHeader&lt;/span&gt;(&lt;span style="color: #a31515"&gt;&amp;quot;MyHeader&amp;quot;&lt;/span&gt;, &lt;span style="color: #a31515"&gt;&amp;quot;MyHeaderValue&amp;quot;&lt;/span&gt;);
            hlHeaderlist.InsertBefore(nhNewHeader, lhLasterHeader);

            &lt;span style="color: green"&gt;// Add the Keywords header to set a Category in Outlook/OWA.
            // *** INFO ***
            // Keywords (also known as Categories) are stripped from
            // message by default.  This can be disabled using the 
            // &amp;quot;Set-TransportConfig –ClearCategories $false&amp;quot; cmdlet.
            // (http://technet.microsoft.com/en-us/library/bb124151.aspx)
            &lt;/span&gt;&lt;span style="color: #2b91af"&gt;TextHeader &lt;/span&gt;nhNewKeywords = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;TextHeader&lt;/span&gt;(&lt;span style="color: #a31515"&gt;&amp;quot;Keywords&amp;quot;&lt;/span&gt;, &lt;span style="color: #a31515"&gt;&amp;quot;1&amp;quot;&lt;/span&gt;);
            hlHeaderlist.InsertBefore(nhNewKeywords, lhLasterHeader);

            &lt;span style="color: #2b91af"&gt;MimePart &lt;/span&gt;tnefPart = item.Message.TnefPart;

            &lt;span style="color: green"&gt;// Without a TNEF body part, we can't do this step.
            // There is no way to create a TNEF body part from
            // scratch if Exchange isn't giving us one.  Most
            // mail that comes from the internet won't have TNEF.
            &lt;/span&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(tnefPart != &lt;span style="color: blue"&gt;null&lt;/span&gt;)
            {
                &lt;span style="color: #2b91af"&gt;TnefReader &lt;/span&gt;reader = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;TnefReader&lt;/span&gt;(tnefPart.GetContentReadStream());
                &lt;span style="color: #2b91af"&gt;TnefWriter &lt;/span&gt;writer = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;TnefWriter&lt;/span&gt;(
                    tnefPart.GetContentWriteStream(tnefPart.ContentTransferEncoding),
                    reader.AttachmentKey,
                    0,
                    &lt;span style="color: #2b91af"&gt;TnefWriterFlags&lt;/span&gt;.NoStandardAttributes);

                &lt;span style="color: blue"&gt;while &lt;/span&gt;(reader.ReadNextAttribute())
                {
                    &lt;span style="color: blue"&gt;if &lt;/span&gt;(reader.AttributeTag == &lt;span style="color: #2b91af"&gt;TnefAttributeTag&lt;/span&gt;.MapiProperties)
                    {
                        writer.StartAttribute(&lt;span style="color: #2b91af"&gt;TnefAttributeTag&lt;/span&gt;.MapiProperties, &lt;span style="color: #2b91af"&gt;TnefAttributeLevel&lt;/span&gt;.Message);
                        writer.WriteAllProperties(reader.PropertyReader);

                        &lt;span style="color: blue"&gt;int &lt;/span&gt;tag;
                        &lt;span style="color: blue"&gt;unchecked
                        &lt;/span&gt;{
                            &lt;span style="color: green"&gt;// The first four bytes of the tag is must be at least 0x8000 
                            // when setting a named property, the second determines the type. 
                            // http://www.cdolive.com/cdo10.htm
                            &lt;/span&gt;tag = (&lt;span style="color: blue"&gt;int&lt;/span&gt;)0x8000001E;
                        }

                        &lt;span style="color: #2b91af"&gt;Guid &lt;/span&gt;PS_PUBLIC_STRINGS = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Guid&lt;/span&gt;(&lt;span style="color: #a31515"&gt;&amp;quot;00020329-0000-0000-C000-000000000046&amp;quot;&lt;/span&gt;);

                        writer.StartProperty(
                            &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;TnefPropertyTag&lt;/span&gt;(tag),
                            PS_PUBLIC_STRINGS,
                            &lt;span style="color: #a31515"&gt;&amp;quot;MyProp&amp;quot;&lt;/span&gt;);
                        writer.WritePropertyValue(&lt;span style="color: #a31515"&gt;&amp;quot;Hello!&amp;quot;&lt;/span&gt;);
                    }
                    &lt;span style="color: blue"&gt;else
                    &lt;/span&gt;{
                        writer.WriteAttribute(reader);
                    }
                }

                &lt;span style="color: green"&gt;//  Close writer
                &lt;/span&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(&lt;span style="color: blue"&gt;null &lt;/span&gt;!= writer)
                {
                    writer.Close();
                }

                LogMessage(&lt;span style="color: #a31515"&gt;&amp;quot;ProcessMailItem&amp;quot;&lt;/span&gt;, item, &lt;span style="color: #a31515"&gt;&amp;quot;Added 'MyProp' to PS_PUBLIC_STRINGS.&amp;quot;&lt;/span&gt;);
            }
            &lt;span style="color: blue"&gt;else
            &lt;/span&gt;{
                LogMessage(&lt;span style="color: #a31515"&gt;&amp;quot;ProcessMailItem&amp;quot;&lt;/span&gt;, item, &lt;span style="color: #a31515"&gt;&amp;quot;No TNEF, not adding property&amp;quot;&lt;/span&gt;);
            }
        }

        &lt;span style="color: blue"&gt;private void &lt;/span&gt;LogMessage(&lt;span style="color: blue"&gt;string &lt;/span&gt;eventName, &lt;span style="color: #2b91af"&gt;MailItem &lt;/span&gt;item, &lt;span style="color: blue"&gt;string &lt;/span&gt;message)
        {
            &lt;span style="color: #2b91af"&gt;TextWriter &lt;/span&gt;tw = System.IO.&lt;span style="color: #2b91af"&gt;File&lt;/span&gt;.AppendText(LOG_FILE_PATH);
            tw.WriteLine(&lt;span style="color: #2b91af"&gt;DateTime&lt;/span&gt;.Now.Ticks + &lt;span style="color: #a31515"&gt;&amp;quot;\t&amp;quot; &lt;/span&gt;+ eventName + &lt;span style="color: #a31515"&gt;&amp;quot; - &amp;quot; &lt;/span&gt;+ item.Message.Subject + &lt;span style="color: #a31515"&gt;&amp;quot; - &amp;quot; &lt;/span&gt;+ message);
            tw.Close();
        }
    }

}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9317264" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/mstehle/archive/tags/HOWTO/default.aspx">HOWTO</category><category domain="http://blogs.msdn.com/mstehle/archive/tags/Exchange+Eventing/default.aspx">Exchange Eventing</category><category domain="http://blogs.msdn.com/mstehle/archive/tags/DevMsgTeam/default.aspx">DevMsgTeam</category><category domain="http://blogs.msdn.com/mstehle/archive/tags/Transport+Agents/default.aspx">Transport Agents</category></item></channel></rss>