Geeks With Blogs
The Quandary Phase This code was generated by a tool.

I have recently completed work on a WPF application which required a reasonable amount of interaction with Microsoft Outlook. Specifically, we needed to implement two operations: firstly, we needed the ability to generate a new email and open it in Outlook (without sending it); and secondly, we needed to send an email via Outlook behind the scenes, without any user interaction.

There were a couple of additional requirements affecting how this functionality could be implemented. One of these was a technical issue, and the other was mandated by the business for whom the application is intended.

The first stipulation was that whatever code we used to communicate with Outlook needed to support multiple versions of Office. Our end-users run a mix of Office 2003 and 2007, and the requirement was that those currently running Office 2003 should be able to upgrade to Office 2007 without having to install a new version of the WPF client application.

The second restriction was that all emails should be sent using the standard company branding; in particular, all emails needed to use their standard email signature.

In order to solve the first problem, we wanted to avoid adding a reference to the Outlook COM interop assembly. Each version of Office has its own Outlook COM interface implementation (and therefore its own version of the Primary Interop Assembly, which stores the assembly metadata which allows .NET to marshal the calls to and from the COM interface), and backwards compatibility is by no means guaranteed.

Normally, when developing for a specific Outlook version, a reference is added to the COM interface via the COM Components tab of the ‘Add Reference’ dialog in Visual Studio like so:

Outlook_COM_reference

This gives you strongly typed access to the properties and methods of the Outlook interface classes. The alternative to this is late binding, and in C#, this means but one thing: reflection, and lots of it (until C# 4.0, anyways).

Of course, the first problem you have when attempting to use reflection alone for Office automation is how to get an instance of the relevant Office application interface without directly instantiating one. One easy way to do this is using the application’s registry ProgID, and the Type.GetTypeFromProgID() method. Here’s an example of how to do this for Outlook:

   1: Type outlookAppType = Type.GetTypeFromProgID("Outlook.Application");
   2: object appInstance = Activator.CreateInstance(outlookAppType);

Once you have a new instance of the interface, from there on in, it’s just a case of calling Type.InvokeMember() against the relevant object instance to invoke the operations by name. To illustrate, here’s how you create a new mail message using the above application instance:

   1: object message = appInstance.GetType().InvokeMember("CreateItem", (BindingFlags.InvokeMethod), 
   2:     null, appInstance, new object[] { 0 });

The above code results in a new Microsoft.Office.Interop.Outlook.MailItem instance, which is the COM interface class used to represent a mail message.

There were plenty of examples around on the web of how to use the Outlook Interface to send or open a message, so once I had discovered how to get a reference to an interface instance indirectly, converting the rest of the code to perform the functionality using reflection was relatively trivial.

The next problem was slightly more complex to solve. The email body content produced by the WPF application is all formatted as HTML, however when we attempted to send or open the email, we found that the company-specific email signature footer content was not appearing as part of the generated email body.

The solution to this consisted of two parts: firstly, there is a rather obscure (and entirely unhelpfully named) property on the MailItemClass named GetInspector. For some reason, presumably known only to those who designed it, the act of calling this property and getting the resulting value (even if you don’t use the returned value for anything) seems to make the difference between the email signature being incorporated into the email body or not.

Yes, that’s right: GetInspector. It’s all so obvious now- I can’t believe I missed it. smile_sarcastic

However, there was one final hoop to jump though. The GetInspector() method loads the signature into the message body, however the signature is itself an HTML document. So now I had 2 HTML documents: the one produced by the application which needed to be sent, and the one containing the email signature which needed to be included.

The only sensible solution was to merge the two HTML documents. However you can’t simply append one to the other, otherwise you end up with a second opening HTML tag, after the first document’s closing HTML tag, which is not valid markup.

You need to ensure the HTML is well-formatted: the body contents of one document needs to be appended/prepended to the other to ensure we end up with valid HTML. I accomplished this by once again using the invaluable HTML Agility Pack’s HTML Parser. For anyone looking for a good .NET HTML Parser- this one comes highly recommended. Using this component, locating the body node of the HTML document produced by the WPF app, copying all of its child nodes to the HTML document produced by Outlook, then taking all the content of this combined document and using it as the email content was a breeze.

So now I had a class able to open/send messages via Outlook, without any COM references, which included the company-specific email signature- just the ticket! I also constructed the code to make it fairly generic, in order to leave open the option of adding support for other email clients at a future date.

As I mentioned earlier, each new version of Microsoft Office results in new COM interface versions for all of the Office applications, which may or may not be compatible with the old ones. So, whilst I am not claiming this solution is future proof, it does work with both Office 2003 and 2007, which was the intended aim.

The code, along with a test application, can be downloaded using the link at the top of the article.

Posted on Friday, August 7, 2009 11:56 AM | Back to top


Comments on this post: Outlook Automation Without COM References

# re: Outlook Automation Without COM References
Requesting Gravatar...
A lot of people get curious on how to add an e-mail signature to their e-mail messages, and there's a lot of talk that it's impossible to do for people who use Gmail. It's easy to create and use an e-mail signature in Gmail. First, you have to enable the Insert Images and Canned Responses features under Labs, which is part of Gmail Settings. Then, click compose message, and paste or create the signature you want. Click on Canned Responses and save it. To add it to messages, simply click on Canned Responses, and click on insert to add the e-mail signature – easy, and you don't have to front fast cash for the know how.
Left by e-mail signature on Aug 28, 2009 12:37 AM

# re: Outlook Automation Without COM References
Requesting Gravatar...
Excelent, great article.
Left by Juan Irigoyen on Jun 16, 2010 7:25 AM

# re: Outlook Automation Without COM References
Requesting Gravatar...
nice for me
Left by bailey button triplet 1873 grey on Nov 17, 2010 6:39 PM

# re: Outlook Automation Without COM References
Requesting Gravatar...
Thanks for your helpful content....
Indonesian Furniture | Indonesian Teak Furniture.
Left by John Agung Vanderbilt on Dec 07, 2010 5:03 AM

# re: Outlook Automation Without COM References
Requesting Gravatar...
I really learn a lot of good things in this blog and I am sharing it with my friends who are searching similar type of information from a lot of days. Hope so this post will be very helpful for everyone.
Left by buy lock pick on Jan 26, 2011 12:49 AM

# re: Outlook Automation Without COM References
Requesting Gravatar...
It’s my great pleasure to visit your blog and to enjoy your awesome posts here. I like that a lot. I know that you put much attention for these articles, as all of them make sense and are very useful. Thanks.
Over 50s Insurance
Left by Over 50s Insurance on Feb 07, 2011 8:14 PM

# re: Outlook Automation Without COM References
Requesting Gravatar...
I have only recently started to play around with WPF and XAML and how to build applications in this format. I like it, but I have a lot to still learn so nice to read about what others are doing.
Left by Life Insurance on Feb 07, 2011 10:37 PM

# re: Outlook Automation Without COM References
Requesting Gravatar...
I am visiting this blog for first time. I am proud to say that I’ve become a great fan of this blog officially. A good blog always comes-up with new and exciting information like this one. Anyone who really wants to read a article with full of information, should read this.
best paper
Left by best paper on Feb 10, 2011 11:15 AM

# re: Outlook Automation Without COM References
Requesting Gravatar...
I am really enjoying reading your well written articles. I think you spend numerous effort and time updating your blog. I have bookmarked it and I am taking a look ahead to reading new articles. Please keep up the good articles!
write my essay
Left by Fox Martin on Feb 16, 2011 9:53 AM

# re: Outlook Automation Without COM References
Requesting Gravatar...
Substantially, the article is in reality the sweetest on this precious topic. I harmonies with your conclusions and will thirstily look forward to your upcoming updates. Saying thanks will not just be sufficient, for the phenomenal clarity in your writing. I will directly grab your rss feed to stay abreast of any updates. Pleasant work and much success in your business efforts!
online dating
Left by Jessica Jain on Feb 18, 2011 12:07 AM

# Mr
Requesting Gravatar...
Thanks for taking the time to discuss this, I feel strongly about it and love learning more on this topic. If possible, as you gain expertise, would you mind updating your blog with more information? It is extremely helpful for me.
buy tea
Left by Namur 111 on Feb 19, 2011 9:00 PM

# re: Outlook Automation Without COM References
Requesting Gravatar...
I read your whole blog & all the comments. The work you did is really really great. I think I am going to try the method you described about Outlook Automation without COM reference. Thanks a lot!
student accomodation nottingham
Left by Johnson Junior on Feb 21, 2011 5:20 AM

# re: Outlook Automation Without COM References
Requesting Gravatar...
I must say, as a lot as I enjoyed reading what you had to say, I couldnt help but lose interest after a while. Its as if you had a terrific grasp to the topic matter, but you forgot to include your readers. Perhaps you should think about this from far more than one angle. Or maybe you shouldnt generalise so significantly. Its better if you think about what others may have to say instead of just going for a gut reaction to the topic. Think about adjusting your very own believed process and giving others who may read this the benefit of the doubt.

voucher codes
Left by roberlong 616 on Feb 24, 2011 9:41 PM

# re: Outlook Automation Without COM References
Requesting Gravatar...
hey it is very nice post. It is awesome. Thank you.
Left by Link building services on Mar 13, 2011 9:44 PM

# re:
Requesting Gravatar...
Hi,think you've made some truly interesting points. Not too many people would actually think about this the way you just did. I'm really impressed that there's so much about this subject that's been uncovered and you did it so well, with so much class. Good one you, man! Really great stuff here.
Left by Medical Negligence Claims on Mar 14, 2011 10:17 PM

# re: Outlook Automation Without COM References
Requesting Gravatar...
Thanks for sharing this. This is really helpful as you so clearly describe everything. Please keep us updating with more information.
Shopper Reviews
Left by Chris 3244 on Mar 19, 2011 12:00 PM

# re: Outlook Automation Without COM References
Requesting Gravatar...
Nice find with GetInspector. Not an easy solution to figure out. Thanks for sharing!
Left by free dating on Mar 24, 2011 7:43 PM

Comments have been closed on this topic.
Copyright © Adam Pooler | Powered by: GeeksWithBlogs.net | Join free