Friday, June 10, 2005

Redemption still needed with Outlook VSTO 2005

One of the things that I had hoped would be improved in the VSTO 2005 Outlook toolkit was that several central MAPI fields should become exposed in the object model. These fields includes being able to change the sender (from) of an e-mail, getting the SMTP address of an Exchange user, getting the URL name of a message, etc.

These things are exactly as before, Microsoft has not added any new functionality to the toolkit, just made it .NET managed code and more reliable. This is 'by design' according to Microsoft, this was the default reply to my wishes during the alpha programme: "VSTO-O does not add any additional functionality to the object model".

During the testing I wanted to set the mail sender without using Redemption. After a suggestion by Sue Mosher I tried by granting a user 'send as' permissions on department mailboxes and changing the sender using the standard SentOnBehalfOfName in the ItemSend event handler, but this never worked. Ken Laws [MSFT] has confirmed that using SentOnBehalfOfName in the ItemSend event is too late, thus you still need Redemption to set this through extended MAPI. This property only works e.g. when set on a Outlook.MailItem created by code.

Changing the sender of an Outlook.MailItem object in ItemSend:

Redemption.SafeMailItem safeMail = new Redemption.SafeMailItemClass();
//Select the item to be modified
safeMail.Item = mailItem;
//fill in the e-mail address in 'From'
int tag = safeMail.GetIDsFromNames("{00020386-0000-0000-C000-000000000046}", "From");
tag = tag 0x1E; //the type is PT_STRING8
safeMail.set_Fields(tag, address);


Getting the SMTP address of an Exchange user from an Outlook.AddressEntry object:

//check if Exchange address
if (mailAddress.StartsWith("/o="))
{
//get SMTP address from MAPI
Redemption.MAPIUtils mapiUtils = new Redemption.MAPIUtils();
int PR_EMAIL = 0x39FE001E;
mailAddress = mapiUtils.HrGetOneProp(entry.MAPIOBJECT, PR_EMAIL).ToString();
mapiUtils.Cleanup();
}

The Outlook toolkit should be reviewed before RTM to add more of the most needed MAPI fields to the list of properties exposed in the object model. Please Microsoft VSTO-O team!

Tuesday, June 07, 2005

Outlook 2003 .NET add-ins with VSTO 2005

[UPDATE] Updated programming advice for VSTO and Outlook 2003/2007.

Now that it is official that VSTO 2005 will provide support for writing .NET add-ins for Outlook 2003 (formerly known as 'Project Elixir'), I can blog some experiences about this new toolkit that is currently in beta.

I have participated in the alpha program for Outlook support in VSTO 2005, and I can tell you that this stuff makes developing add-ins with .NET easier than before. You do not need to bother with superfluous interface methods, COM shims, calling InvokeMember(), shaky event handlers, the Outlook shutdown bug, MSCorEE.DLL, etc. The Outlook add-in template for Visual Studio 2005 is also much better than the one available for VS.NET 2003. E.g. the template is preconfigured to start Outlook when debugging, and some other improvements.

Short intro article on MSDN
Long add-in architecture article on MSDN

Developing and debugging Office 2003 add-ins with VSTO 2005 is a breeze, there are several sample projects with the toolkit that will get you started. You just need to ensure that you keep a reference for all objects you add (menus, toolbars, buttons, etc) for the lifetime of the add-in. If you do not, your event handlers for these object will work for some time, until the garbage collector frees the object reference and thus your event handler. The toolkit samples contain some bugs of this kind.

What you will find out the hard way, is that testing your add-in on another PC is not straightforward as the setup project template still has a way to go until RTM. The generated .MSI package will install the .NET Framework 2.0, the detected dependencies and your component. But it will not install the VSTO 2005 runtime or the Office 2003 PIAs. Refer to these pre-release guidelines for what you need to install on a client/test PC.

This is what I had to do to get my add-in to load (i.e. to make the add-in visible and checked in the Outlook "COM Add-ins" dialog box):
  • Copy the VSTAddin.DLL assembly to the .\VSTO\8.0\ folder (this assembly replaces the MSCorEE.DLL used in the COM shim era; referred to as AddinLoader.DLL on MSDN, but it is not named so in beta 2)
  • Deploy the .manifest file of my add-in .DLL to the install directory of my add-in
  • The setup project did not include any of the required registry settings for Outlook, so I had to export the Outlook add-in registry settings, plus the class ID and prog ID settings of the DLL; and then import them on the test PC
  • Modify the "ManifestLocation" path to point to the install directory (note that the "CodeBase" stuff for COM shims have been replaced by the deployment manifest file)

Even after installing all of these components, my add-in would be listed in Outlook, but not loaded, with the standard error message "A runtime error occurred during the loading of the COM add-in". This was caused by another change for .NET add-ins, they are now treated as .NET components and code access security must be configured on the target PC:

  • Run the .NET FW 2.0 CASPOL.EXE to grant full trust to the install directory of the add-in (see the end of this MSDN article)
These things has improved a lot in the current VSTO beta (see 'Creating Visual Studio Add-in Projects' details on MSDN) and will surely be improved further in coming betas and RTM.

Note that you might not find the "Microsoft .NET Framework 2.0 Configuration" tool in Control Panel-Administrative Tools after installing the .NET FW 2.0 beta 2. Neither will you find the MMC snap-in, which is installed with VS2005.