How To: Create a new Outlook message based on a template
In my previous article, where I demonstrated how to create and show an Outlook message programmatically, a mail item object was created from scratch. Now I want to show you the way to create a new mail item based on a template. So, here goes!
The Application class in Outlook provides you the CreateItemFromTemplate method. It creates a new Outlook item based on the specified template and returns the newly created Outlook item. The CreateItemFromTemplate method accepts two parameters:
- Path to a template (a .oft file) – a string showing the path (including its name) to the template on which you will base your new Outlook item.
- Folder object – the folder into which a newly created item will be placed. This parameter is optional. If it is omitted, the default folder for the item type will be used (for instance, the Drafts folder is used if you create a new item based on the mail item template).
As you probably noticed, you need to have a .oft file saved somewhere on your hard drive to get the CreateItemFromTemplate method running correctly. For example, I saved it on drive D. Note that you can save an existing e-mail item as a template using the File | Save As… command in Outlook. You just need to choose the "Outlook Template" in the “Save as type” list box of the “Save As” dialog. Alternatively, you can do the same programmatically by specifying the Outlook.OlSaveAsType.olTemplate value in the SaveAs method of Outlook items.
Note. In my tests against Outlook 2010, I tried to pass the path to a .msg file to the CreateItemFromTemplate method and it worked like a charm. So, you can use .msg and .oft files as templates.
I want to draw your attention to the following fact: when you create a new item based on the Mail template and specify any folder other than Drafts, the Drafts folder will be used anyway. So, in the code of this sample I move a newly created item to the Inbox folder even when I specify the Inbox folder as the parent folder in the CreateItemFromTemplate method.
Below you can find the code that creates Outlook items as described above. For illustration purposes I create a MailItem object and then display it to the user. You just need to pass an instance of the Application class to the CreateItemBasedOnTemplate method to get the code running.
C# and Add-in Express:
private void CreateItemBasedOnTemplate(Outlook._Application OutlookApp) { Outlook.NameSpace ns = null; Outlook.MAPIFolder containerFolder = null; Outlook.MailItem item = null; Outlook.MailItem movedItem = null; try { ns = OutlookApp.GetNamespace("MAPI"); containerFolder = ns.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox); item = OutlookApp.CreateItemFromTemplate(@"D:\MyTemplate.oft", containerFolder) as Outlook.MailItem; // the item was created in the Drafts folder regardless // that is why we move it to the Inbox folder movedItem = item.Move(containerFolder) as Outlook.MailItem; movedItem.Save(); movedItem.Display(); } catch (COMException ex) { if (ex.ErrorCode == -2147287038) System.Windows.Forms.MessageBox.Show(ex.Message, "Can't find the template..."); else System.Windows.Forms.MessageBox.Show(ex.Message, "An error was occurred when creating a new item from template..."); } finally { if (movedItem != null) Marshal.ReleaseComObject(movedItem); if (item != null) Marshal.ReleaseComObject(item); if (containerFolder != null) Marshal.ReleaseComObject(containerFolder); if (ns != null) Marshal.ReleaseComObject(ns); } }
VB.NET and Add-in Express:
Private Sub CreateItemBasedOnTemplate(OutlookApp As Outlook._Application) Dim ns As Outlook.NameSpace = Nothing Dim containerFolder As Outlook.MAPIFolder = Nothing Dim item As Outlook.MailItem = Nothing Dim movedItem As Outlook.MailItem = Nothing Try ns = OutlookApp.GetNamespace("MAPI") containerFolder = ns.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox) item = OutlookApp.CreateItemFromTemplate("D:\MyTemplate.oft", containerFolder) ' the item was created in the Drafts folder regardless ' that is why we move it to the Inbox folder movedItem = item.Move(containerFolder) movedItem.Save() movedItem.Display() Catch ex As COMException If (ex.ErrorCode = -2147287038) Then System.Windows.Forms.MessageBox.Show(ex.Message, "Can't find the template...") Else System.Windows.Forms.MessageBox.Show(ex.Message, "An error was occurred when creating a new item from template...") End If Finally If Not IsNothing(movedItem) Then Marshal.ReleaseComObject(movedItem) If Not IsNothing(item) Then Marshal.ReleaseComObject(item) If Not IsNothing(containerFolder) Then Marshal.ReleaseComObject(containerFolder) If Not IsNothing(ns) Then Marshal.ReleaseComObject(ns) End Try End Sub
C# and VSTO:
using System.Runtime.InteropServices; // ... private void CreateItemBasedOnTemplate(Outlook.Application Application) { Outlook.NameSpace ns = null; Outlook.MAPIFolder containerFolder = null; Outlook.MailItem item = null; Outlook.MailItem movedItem = null; try { ns = Application.GetNamespace("MAPI"); containerFolder = ns.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox); item = Application.CreateItemFromTemplate(@"D:\MyTemplate.oft", containerFolder) as Outlook.MailItem; // the item was created in the Drafts folder regardless // that is why we move it to the Inbox folder movedItem = item.Move(containerFolder) as Outlook.MailItem; movedItem.Save(); movedItem.Display(); } catch (COMException ex) { if (ex.ErrorCode == -2147287038) System.Windows.Forms.MessageBox.Show(ex.Message, "Can't find the template..."); else System.Windows.Forms.MessageBox.Show(ex.Message, "An error was occurred when creating a new item from template..."); } finally { if (movedItem != null) Marshal.ReleaseComObject(movedItem); if (item != null) Marshal.ReleaseComObject(item); if (containerFolder != null) Marshal.ReleaseComObject(containerFolder); if (ns != null) Marshal.ReleaseComObject(ns); } }
VB.NET and VSTO:
Imports System.Runtime.InteropServices ' ... Private Sub CreateItemBasedOnTemplate(Application As Outlook.Application) Dim ns As Outlook.NameSpace = Nothing Dim containerFolder As Outlook.MAPIFolder = Nothing Dim item As Outlook.MailItem = Nothing Dim movedItem As Outlook.MailItem = Nothing Try ns = Application.GetNamespace("MAPI") containerFolder = ns.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox) item = Application.CreateItemFromTemplate("D:\MyTemplate.oft", containerFolder) ' the item was created in the Drafts folder regardless ' that is why we move it to the Inbox folder movedItem = item.Move(containerFolder) movedItem.Save() movedItem.Display() Catch ex As COMException If (ex.ErrorCode = -2147287038) Then System.Windows.Forms.MessageBox.Show(ex.Message, "Can't find the template...") Else System.Windows.Forms.MessageBox.Show(ex.Message, "An error was occurred when creating a new item from template...") End If Finally If Not IsNothing(movedItem) Then Marshal.ReleaseComObject(movedItem) If Not IsNothing(item) Then Marshal.ReleaseComObject(item) If Not IsNothing(containerFolder) Then Marshal.ReleaseComObject(containerFolder) If Not IsNothing(ns) Then Marshal.ReleaseComObject(ns) End Try End Sub
See you on our forums and in the e-mail support!
8 Comments
Hi, great article!
I had the same issue with the drafts folder, I explicitly have to move the mailitem to another folder with the move method.
I have a question: If I use the Display-method and want to access some properties after the modal window is closed from the user, every object is lost and I get an exception: RPC Server is unavailable.
Is there any workaround for this type of problem?
I’m using outlook 2010 and c# 4.0 with Interop
Thanks henrik
Hello Henrik,
“RPC Server is unavailable” usually occurs when the application providing the corresponding COM object is closed. Is this the case? Anyway, you need to access any properties of the movedItem object BEFORE movedItem is released. The best place to invoke your code is right after the line calling movedItem.Display().
HTH
This was useful post. thanks for the same.
I am searching for the following requirement, could u please work and share the same.
Requirement :- MSG file place in explorer path, need a coding to reply from that msg file and also to forward from the path.
Public sub checking()
Dim myOlApp As Outlook.Application
Dim myuitem As Object
Set myOlApp = CreateObject(“Outlook.Application”)
Set myuitem = myOlApp.CreateItemFromTemplate(“C:\Apps\MAILS\1_1.msg”)
myuitem.Subject = myuitem.Subject & ” – ADDED”
myuitem.Display
End
Hello Lakshminarayanan,
Now, when you have the MailItem created, you can call MailItem.Reply (or MailItem.Forward). This creates a MailItem representing the reply (forward). You can add attachments to the reply and send it. Please see the following pages:
https://msdn.microsoft.com/en-us/library/office/ff868875%28v=office.15%29.aspx
https://msdn.microsoft.com/en-us/library/office/ff865399(v=office.15).aspx
https://msdn.microsoft.com/en-us/library/office/ff866779%28v=office.15%29.aspx
https://msdn.microsoft.com/en-us/library/office/ff864730%28v=office.15%29.aspx
You may also find useful these pages:
https://msdn.microsoft.com/en-us/library/office/ff868025(v=office.15).aspx
https://msdn.microsoft.com/en-us/library/office/ff866465(v=office.15).aspx
Once the email is displayed with .Display, can I tell if the user sends the email?
Hello Les,
You can intercept the Application.ItemSend event; see https://docs.microsoft.com/en-us/office/vba/api/outlook.application.itemsend. In Add-in Express, this event is mapped to the ItemSend event of the ADXOutlookAppEvents component; you should put it onto the add-in module. The event handler allows you to check every item before it is sent and cancel the send.
Hello Andrei,
Do you also have a coding example in VBA for Add-in?
Many thanks in advance,
Hello Sjoerd,
Sorry, I don’t understand. A coding example of what?