Office Needs A Better Managed API

Monday, July 5, 2004
A few days ago, I decided I wanted a new button on my Outlook toolbar. When I click the button I want highlighted items redirected to a web mail account with the ‘From’ address intact. I’m sure this already exists somewhere, but I wanted to learn how to do it myself.

With the Shared Add-In extensibility project wizard and code from “An Introduction to Programming Outlook 2003 Using C#”, I thought I was 90% of the way there, except it didn’t work. Specifically, the following line of code from the article would never return:

CommandBars commandBars = applicationObject.ActiveExplorer().CommandBars;

The call would literally disappear in the opaque goo of COM interop. No exceptions, no error dialogs, no abnormal behavior as Outlook continued to work. I thought I must have a configuration problem and began double-checking primary interop assembly versions and looking for updates. I happened to run across a knowledge base article using the following code:

activeExplorer = applicationObject.GetType().InvokeMember("ActiveExplorer",BindingFlags.GetProperty,null,applicationObject,null);
commandBars= (CommandBars)activeExplorer.GetType().InvokeMember("CommandBars",BindingFlags.GetProperty,null,activeExplorer,null);

The above code, using reflection, worked perfectly. I managed to finish the code for my button click event, but not without some irritation.

The base class library in .NET spoils developers, and I think if Microsoft wants people to develop for Office they should provide a higher level of abstraction on top of the runtime callable wrappers. The interface should be subject to the same design rules and usability testing as the rest of the .NET libraries. Let me give you a couple examples about why I am griping.

Selected items are kept in a Selection collection. Indexing into the collection gives me a plain object reference. It would be nice if there was a base class representing any type of item in Outlook which I could perform some operations on. As it stands, I had to dig through the documentation to find the types of Items I am interested in: MailItem and PostItem objects. I had to find these items in the object browser of the IDE as the documentation I used (VBAOF11.chm – the Microsoft Office Object Model) make no mention of them.

Without documentation I decided the best way to get to know these classes was by inspecting them in the debugger. Unfortunately, if I cast an object reference to type MailItem, all I see in the debugger quick watch is a System.__ComObject, which gives me nothing to go on. If, however, I cast the reference to the interface type of _MailItem (notice the underscore), then I can see all the properties and values I am interested in.

The fact that there are three types available to work with (MailItem, _MailItem, and MailItemClass) only adds to the confusion. My fading COM memories tell me these types probably exist because of the difference is dispatch and vtable binding, but when I just want to get something done in Outlook I don’t really care to learn the differences. I just wish it was easier, and with integrated documentation, like the rest of the .NET development experience. Whine, whine, whine.

P.S. I found the easiest way to debug an add-in which is loaded by Outlook when Outlook starts is to invoke System.Diagnostics.Debugger.Launch(), and let's not talk about the number of times you need to put in System.Reflection.Missing.Value as a parameter to a method. Complain, complain, complain.


Comments
Bill Tuesday, July 6, 2004
Amen to every damned word!
Chris Wednesday, August 25, 2004
"Selected items are kept in a Selection collection. Indexing into the collection gives me a plain object reference. It would be nice if there was a base class representing any type of item in Outlook which I could perform some operations on." --
<br>
<br>Thanks for mentioning this, I thought I was alone with this request.
Argus Friday, September 10, 2004
I am fighting Outlook, too: trying to add a shortcut to a context menu. But it's seems a waste of time. Well, someday I just stop trying.. That's very annoying when you have to &quot;guess how to do this or that&quot; and not to give up after dozens of failures.
Mathias Tuesday, September 21, 2004
You can get
<br>CommandBars commandBars = applicationObject.ActiveExplorer().CommandBars;
<br>
<br>to work by removing the reference to the ActiveX &quot;Outlook&quot; reference that the Project Wizard has added, and instead adding the Assembly &quot;Microsoft.Office.Interop.Outlook&quot; located in &quot;Add Reference/.NET&quot;.
<br>
<br>I have yet to test if this has further implications though.
<br>
Clifford Monday, December 6, 2004
[Matthias] You can get
<br>CommandBars commandBars = applicationObject.ActiveExplorer().CommandBars;
<br>
<br>It does not always work. That's the point. And to agree with the other posts, I cannot believe the outlook items do not implement a common interface!! Object orientated programming. Will it never arrive!?!
Comments are now closed.
by K. Scott Allen K.Scott Allen
My Pluralsight Courses
The Podcast!