When writing an email add-in for Outlook with Visual Studio, it’s really quite easy to get the email message object while the send event is in progress using the Application.ItemSend event. However this event happens before the email is sent, so although it can be useful, the Application.ItemSend event is often not the correct event handler to be used when working with Outlook email messages programmatically.
In my case, what I want to be able to do is to get and copy an email object when it is added to the sent items folder, but so far this has been difficult to figure out. Until a few minutes ago, that is. After a bit of research and investigation I’ve got it working.
The trick is to register a custom event handler when Outlook is opened using the Me.Startup event on the ThisAddIn class.
Specifically, in the Me.Startup event, assign the Outlook.OlDefaultFolders.olFolderSentMail folder to a member variable and manually set an event handler to the folder consisting of the folder’s Items.ItemAdd trigger and point it to a custom method passing the item as an object argument.
Sound complicated? It’s actually not really. Here’s the code:
Imports System.IO Imports System.Security.Principal Imports System.Windows.Forms Public Class ThisAddIn Dim sentItems As Outlook.Items Dim sentFolder As Outlook.Folder Private Sub ThisAddIn_Startup(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Startup ' Executes When Outlook is opened sentFolder = Application.Session.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderSentMail) sentItems = sentFolder.Items AddHandler sentItems.ItemAdd, AddressOf itemadd End Sub Sub itemadd(ByVal NewEmailItem As Object) Dim sentMessageItem As Outlook.MailItem = CType(NewEmailItem, Outlook.MailItem) If Not sentMessageItem Is Nothing Then ' Add your code here End If End Sub
Things to Keep in Mind:
As you can see, the above way of accessing newly added email messages in Outlook ‘s sent items folder is straightforward and exactly what one needs when working with Outlook email messages.
This is especially useful since an email message is only assigned a unique Id by Outlook when it is saved or sent. This means if you do processing of the message in the Application.ItemSend email message event, you will not be able to retrieve a unique Id for the email.
Another interesting caveat is that if you want to back up an email message into a separate Outlook folder, you should not do so in the Application.ItemSend event. There are two good reasons for this:
- You will be copying and backing up the unsent email, which can be confusing to users since they will think that the message was not sent.
- The copied and unsent message will be permanently kept in Outlook’s Outbox. This will make it look like the add-in that you have written is breaking Outlook and will cause confusion to users since they will see their Outbox full of unsent messages.
However it is often impossible to completely code for the Sent Items folder Items.ItemAdd event handling method, since for example custom form information is no longer available at that point. Basically one needs a way to interact with an email message across the message’s life-cycle stages. This can be done by splitting the code for handling Outlook messages between the Application.ItemSend event and the custom Sent Items folder Items.ItemAdd event handling method.
Because an email message is only given a unique Id when it is in the sent status, there is no clean way of tracking the email from the Application.ItemSend event to the custom Sent Items folder Items.ItemAdd event handling method.
In this case I found that the cleanest way to correct for this is to generate and store my own unique email Id. Since Outlook allows custom user properties, I add the unique Id as a custom user property in the Application.ItemSend event. Alternately one can add the form information directly as a series of custom user properties.
Then, in the Sent Items folder Items.ItemAdd event I can tell if a message requires special handling by retrieving that Unique Id custom user property. This is especially useful when storing and retrieving Outlook email information from a custom database.
Outlook custom add-in components are a powerful tool that Microsoft has made available with Visual Studio and .NET 4. I intend to continue exploring the features and functionality available to programmers, and would appreciate your feedback or suggestions in the comments section below.
8 thoughts on “VS2010 Outlook ThisAddIn – How to Get the Sent Email Message”
Hi Justin, please pardon me to ask, is it really safe to use custom add in property to be unique ID?
I was being told that custom property might be remove in certain email provider which means once it gets out, the fate is uncertain. Is this info right?
Hi, what you are saying is definitely true, and is an important point to keep in mind. The Unique ID as well as any unique custom fields should be considered lost once the email arrives at a destination server. These fields are also removed if you save the email to your database as a Outlook Message Format .msg file.
In the case of this article I am generating my own unique Ids so that I can stamp the email to save form values to a database in the Application.ItemSend event and then to identify and save a copy of the same email in .msg format once it triggers the sent folder’s Items.ItemAdd event. This works quite nicely and there are no problems if/when the receiving server removes all of the custom fields.
Can I get this code in C#
Hi i am using outlook 2013. for me ItemAdd event getting outlook mailitem object is null what would be the reason for that.
private void sentItems_ItemAdd(Object Item)
// try to get the “UserProperties” from outlook mailitem giving target invocation exception.
please help me.
I would also look at the Application.NewMailEx event these days, there are some good examples out there, and it appears to collect sent items (once sent, and with their ID) as well.
Thanks for your site – been interesting reading. I’d love to see you revisit the idea of Outlook add-ins in 2015.
have a great day
Thanks Don, I will take a look into the Application.NewMailEx event. Cheers!
Sadly I may have misspoken. The emails I was seeing are sent to myself, and NewMailEx appears to be only firing on the receiving side. Still a cool function, but not what you were talking about.
have a great day
Hi, i need copy all mails sended in other folder. I use this code
Dim copyMessageItem As Outlook.MailItem
copyMessageItem = sentMessageItem.Copy()
But this create a cycle and a exception error, i think at copy mail this call again itemadd sub.
How you do the mail copy to other folder?