2007
04.24

Target machine is a clean install, Windows XP Tablet PC edition, never had any development tools on it. After doing XCopy deploy of .exe and associated .dlls, trying to run the application gives error Message Box:
“The application failed to initialize properly (0xc0150002). Click on OK to terminate the application.”
From the Microsoft posting “How to: Deploy using XCopy” http://msdn2.microsoft.com/en-us/library/ms235291(VS.80).aspx, you might think that running vcredist_x86.exe (comes with Visual Studio setup) would solve the problem. It doesn’t.
Going to try the dependency walker tool to see if I can determine what else might be needed.

It turns out that the dependency walker (“Depends”) tool was very informative and pointed out missing dependencies msvcr80.dll, msvcp80.dll and winmm.dll. However, that was only half of the story.
My .exe still wouldn’t run – it kept giving the same “The application failed to initialize properly (0xc0150002).” error. Hmmmm.

Time to pull out the File system monitor, otherwise known as Filemon (http://www.microsoft.com/technet/sysinternals/FileAndDisk/
Filemon.mspx). This is a truly amazing tool that monitors all file system activity. It has saved my rear more than once.
After working with it for a while, I kept noticing a NOT FOUND result in Filemon when csrss.exe was trying to access C:\WINDOWS\WinSxS\Policies\x86_policy.8.0.
Microsoft.VC80.DebugCRT…. Suddenly a light bulb came on – Policies…Debug…Hmmm. Sure enough, recompile in release and redeploy the app – now it runs fine on the target machine.
Looks like there are policies that need to get set up in order to run debug code on a machine.
Live and learn.

2007
04.18

Outlook Add-in Deployment issues

So after you’ve built your new whiz-bang Outlook Add-in, you will want to deploy it to your user’s machines. It runs fine on your development machine, but when you copy it (or use the installer to install it) to another box, it doesn’t run so fine. Here are some deployment issues I ran into that weren’t really documented very well. Hopefully they will save you some time.

Outlook recognizes your Add-in and shows it in the COM Add-ins dialog, but won’t load it. The COM Add-ins dialog will say something like “error in loading.” This is a perplexing one and it was quite a problem to solve. I ended up downloading a file system sniffer and discovered that Outlook was trying to load something called “Extensibility.dll.” What in the world is that?
Technically speaking: “This assembly is necessary for referencing the IDTExtensibility2 interface that shared add-ins must implement, as well as creating command bars and command bar controls that provide the primary interface for users of the managed COM add-in in the application.”
In other words, it is a Microsoft file that Outlook needs to talk to plug-ins. It is also, apparently, not on the list of redistributable components. This is quite an unfortunate circumstance.
From what I have read on the Microsoft team forums (e.g.
http://forums.microsoft.com/MSDN/ShowPost.aspx
?PostID=1436656&SiteID=1
)
there isn’t a really good solution.
The best one I saw was to install the “VS SDK” which contains an MSI that contains Extensibility.dll. Are you kidding? Install the VS SDK on a user’s machine so an Outlook Add-in will load????
If anyone else has better ideas please post them. (See “The Answer” below)
– Does the Outlook Add-in have to be in the GAC? As best as I can tell, the answer is No. I never had to put it there to get it to load and run. I did, however, strong sign the Add-in because of the additional security that provides, and it will need to be strong-signed if you are going to put it in the GAC.
– A dependency I noticed only on Vista was msvcr80.dll. I suspect it will be needed on other OSes as well, however.

Development Issues

Here are some issues I ran into when developing the Outlook Add-in.

– When you add a reference to Microsoft forms (fm20.dll) (if you are going to place an Active-X control on your new Contact tab), make sure it is the reference that creates the Microsoft.VBE.Interop entry in the Object Browser (View/Object Browser). There was another Microsoft forms to choose from when I added it in the “Add Reference” dialog and apparently I picked the wrong one because it did not work until I took out the incorrect reference and added the other one that creates the Microsoft.VBE.Interop reference in the Object Browser.
– To debug your Add-in with Visual Studio, go to Project/Properties/Debug tab and under “Start Action” choose “Start external program” and put the path to Outlook on your machine in the edit box there. This will make your life much easier in fixing problems.
If your Add-in suddenly stops working it is possible that Outlook unloaded it (Outlook will mercilessly unload any Add-in it thinks has misbehaved). In Outlook, go to Tools/Options then “Other” tab, choose the “Advanced Options” button, then the COM Add-Ins button which will bring up the COM Add-ins dialog. Make sure your Add-in is still checked.
– If Outlook really thinks your Add-in has been bad, it will totally disable the Add-in. In this case (this was a hard one to figure out because of the lack of docs) go to Help/”About Microsoft Office Outlook” and click on the “Disabled Items” button there. If your Add-in was very naughty it might end up here in the Disabled Items list. Click on it and then the Enable button to reenable.
– I did NOT need to use caspol to set code access security policies. Not to say that it won’t be needed at all, but I don’t think it is as critical to getting your app running as some of the discussions would lead you to believe.
– In Outlook 2007, in order to get your Add-in recognized, you have to go to Tools/Trust Center…, then click on Add-ins and make sure your Add-in is in the “Active Application Add-ins.” If not, pick “COM Add-ins” from the drop down at the bottom, then click on the “Go” button. This will bring up the familiar “COM Add-ins” dialog. Pick your Add-in from the “Add-Ins available” list and you should be good to go.

Security Issues

– Under the Outlook dialog found at Tools/Macro/Security on the “Security Level” tab, if “High” is checked and on the “Trusted Publishers” tab, if “Trust all installed add-ins and templates” is NOT checked, Outlook will prompt the user on startup to see if they want to run the add-in. This is a pain, but just the way Office security works.

Vista-specific issues

– When you try to register (with regsvr32.exe) your unmanaged C++ shim (if you wrote one) in Vista with UAC on, you will have permission issues and it will not register. According to Microsoft, this is “expected” with UAC on. They suggest changing the way your component registers (presumably not trying to write to HKLM), or to run regsvr32.exe from an “elevated command prompt” which you get by right-clicking on command prompt icon and choosing “Run as Administrator.”
They also suggest running Visual Studio in “admin mode” which you can do by right-clicking on Visual Studio icon and choose “Run as administrator” from the context menu. (More info here:
http://blogs.msdn.com/vcblog/archive/
2006/09/06/742187.aspx
).

General Info

– Registry key where Outlook tries to find add-ins:
HKEY_CURRENT_USER\SOFTWARE\Microsoft\Office\
Outlook\Addins

The Answer:

How to redistribute Extensibility.dll
After looking long and hard for the answer as to how to redistribute Extensibility.dll (which shared Office add-ins need in order to reference IDTExtensibility2), I decided to give in, grit my teeth, and submit the question to Microsoft support. After spending 2 hours on the phone and getting transferred no fewer than 5 times, someone that was reasonably intelligent-sounding promised to get right on the problem and get back to me.
After a day I got another e-mail from someone else in Microsoft support asking again what the problem was, to which I replied “Is Extensibility.dll redistributable or not” and, “If so, is there an install for it?”
After being sent yet again to another support engineer, it began to look like we might get a real answer. Another couple of days went by trading e-mails with this new person, and I finally got the answer.

Here it is, in case you are trying to solve the same problem.

MSFT support claims extensibility.dll is redistributable, but you have to do it through a specific .msi (no explanation as to why we need the .msi as opposed to just distributing the .dll).

The KB fix (VS2005-KB908002-ENU-x86.EXE) at the following address provides a copy of the needed .msi along with some other Office fixes:
http://support.microsoft.com/kb/908002/en-us

The fix is called “Shared Add-in Support Update for the Microsoft .NET Framework 2.0 (KB908002),” and Microsoft says that it provides the required fixes in Office and the .NET Framework together with the solutions that you write in Visual Studio 2005.

When you run the .exe there as instructed, it gives you an .msi (extensibilityMSM.msi), as expected, in C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\BootStrapper\Packages\KB908002. According to my support contact, this .msi is distributable (There is a eula.txt there in the “en” directory underneath the .msi with the legal details).

So the answer is to let your install kick off extensibilityMSM.msi and then Extensibility.dll should be in place on the user’s machine.

What an ordeal just to find out such a simple answer from Microsoft support.
Microsoft
: Is a week’s response time the best you can do to support engineers that pay a premium for your services — especially on such an easy question? Also, would it be too much to ask to bring some of the support back to native English speaking countries so we are not trying to communicate with ESL people in India? I will certainly be advising my organization against buying Microsoft “support incidents” for all our developers in the future. Better to pay for the incidents on an emergency, last-ditch basis.

midniteblogger

2007
04.17

In the last 3 sessions, we have developed an Outlook Add-in that adds a tab to a Contact window when it is opened. We began to discuss some further issues with which we must grapple.

Problem #1. There is a Microsoft documented problem with Outlook hanging in memory after closing it even if an Outlook Add-in is properly written. It doesn’t always happen, but it is a known issue and can really be annoying. The answer here is to implement a manual “disposer” class. More on this later.

Problem #2. Because our Add-in is in C# Outlook doesn’t load it directly (discussed earlier). Outlook really loads mscoree.dll instead of our Add-in, and mscoree.dll loads our Add-in. Why is this a problem? As noted before, if Outlook thinks our Add-in misbehaved, it will unload mscoree.dll (our Add-in loader).

What is worse, Outlook will then refuse to load ANY other .NET Add-in. This also means that another managed Add-in that misbehaves could also cause our Add-in not to get loaded. (Supposedly this has been remedied in Outlook 2007). The answer here is not exactly easy. The only real solution I found was to write a shim in unmanaged C++ that would be registered with Outlook, and it would, in turn, load our managed Add-in. It does work well. I can post on this if anyone is interested.

So let’s look at Problem #1 – Outlook hangs in memory.  Amazing but true.  There is a problem with Outlook and the way it handles unloading Add-ins.  What makes it worse, is that it doesn’t always happen.  Yuck.   You just have to deal with it.  So what do we do?

This is a problem that Microsoft has documented, and this is the solution I have come up with (with the assistance of the Microsoft Office site).  So if you have been following along, you may have been wondering why we registered for
ExplorerEvents_10_Event_Close in the first place. Your patience is about to be rewarded. In the event handler
Explorer_ExplorerEvents_10_Event_Close we need to do the following. First, tell the explorer class we don’t want any more callbacks like so:

m_explorerclass.ExplorerEvents_10_Event_Close
-= new Outlook.ExplorerEvents_10_CloseEventHandler(
Explorer_ExplorerEvents_10_Event_Close);

We also have to unregister for “NewInspector” events:

m_inspectors.NewInspector -= new
Outlook.InspectorsEvents_NewInspectorEventHandler(Inspectors_NewInspector);

Then, in the part that really hails back to the days of COM, we have to manually dispose of any object that has registered as an event listener. You heard me right. So much for the glories of managed code. It’s time to get your hands dirty! For all you who have never had the pleasure of releasing a COM object, your time has come!

What we need to do next is, in the same
Explorer_ExplorerEvents_10_Event_Close callback, manually release the m_explorerclass and m_inspectors objects. They were the objects that originally registered as event listeners .
Here’s how we release the objects:
Make sure you have a “using” statement for System.Runtime.InteropServices and then put in the following code.

try
{
  if (m_explorerclass != null)
  {
    int iCount = Marshal.ReleaseComObject(m_explorerclass);
    while (iCount > 0)
    {
     iCount = Marshal.ReleaseComObject(m_explorerclass);
    }
  }
}
catch (SystemException ex)
{
}
finally
{
  GC.Collect();
  GC.WaitForPendingFinalizers();
}

You have to do this for the m_explorerclass and m_inspectors objects. What we are doing here is performing an old-time COM Release(), then telling the managed garbage collector to do its thing and waiting on it.  This is actually the solution Microsoft proposes as the answer to the problem of Outlook hanging in memory when it is supposed to exit.

If you don’t believe me you can read more about it on the MSDN technical articles site (http://msdn2.microsoft.com/en-us/library/aa155703(office.10).aspx).  Just look for Calling UnInitHandler and Disposing of Objects. Even though this Microsoft article is about Outlook 2002, I don’t see any indication that it is different for Outlook 2007.  If so, someone please correct me.

There were a few other strange things about this manual disposing business.  I ended up putting the above code in a routine and calling it both from Explorer_ExplorerEvents_10_Event_Close and Connect.OnDisconnection just to make sure it always happened.

See the epilogue  for final issues and comments.

2007
04.14

To this point we have an Outlook Add-in shell written.  We have verified that Outlook sees it and that Outlook loads it when it starts up.  (See Part 1 and Part 2 if you missed them). Now we are going to make it do something interesting inside Outlook.

To start with, let’s add a tab to the Outlook dialog when someone brings up a Contact.
First, you have to add a reference to the Outlook COM object so the C# compiler knows what Outlook is. Open your MyAddin project in Dev Studio and choose Project/Add Reference from the menu. On the “Add Reference” dialog, pick the COM tab and scroll down to Microsoft Office 11.0 Object library. (It should be there if Outlook is correctly installed on your computer). Pick it and click OK.
Put the following declaration in your “using” section of Connect.cs:


using Outlook = Microsoft.Office.Interop.Outlook;
using System.Diagnostics;
using System.Reflection;

Just under your class declaration:

public class Connect: Object, Extensibility.IDTExtensibility2

add the following class member declarations:


Outlook.Application m_outlook;
Outlook.ExplorerClass m_explorerclass;
Outlook.Inspectors m_inspectors;

Then create a new method with the following signature:

private void InitializeAddIn().

Call InitializeAddIn from the OnConnection() function that the wizard created for you and assign m_Outlook as Outlook.Application to the application object that was passed in OnConnection().

So now you have an OnConnection function that looks like this (you can take out the applicationObject and addInInstance the wizard added):

public void OnConnection(object application, ...)
{
m_outlook = application as Outlook.Application;
InitializeAddIn();
}

Also add another class method with the following signature (no implementation for now):

public void Explorer_ExplorerEvents_10_Event_Close()

And another class method with the following signature (no implementation for now):

public void Inspectors_NewInspector(Outlook.Inspector inspector)

In InitializeAddIn() put the following code:

try

{
  m_explorerclass =
  m_outlook.ActiveExplorer() as Outlook.ExplorerClass;

  if (m_explorerclass != null)
  {
    m_explorerclass.ExplorerEvents_10_Event_Close += new
    Outlook.ExplorerEvents_10_CloseEventHandler
    (Explorer_ExplorerEvents_10_Event_Close);

    m_inspectors = m_outlook.Inspectors;
    m_inspectors.NewInspector += new
    Outlook.InspectorsEvents_NewInspectorEventHandler
    (Inspectors_NewInspector);
  }
  catch (Exception ex)
  {
  MessageBox.Show("Error in Connect.InitializeAddIn: " + ex.Message);
  }

Now let’s build our Add-in and make sure everything is OK. Builds? Good. Outlook still recognizes it? Better!

So what’s going on here?  C# is quite verbose in its syntax, so it helps if you like to read when you look at the method and event names!  A bit hard to get used to if you come from a C/C++ background – but I digress…

What we are doing here is getting a reference to the “ActiveExplorer” (which at this time is the main Outlook window).   We are also “registering” as a listener to the Close Event of the Active Explorer (main Outlook window).  This means that Outlook will notify us in the function

Explorer_ExplorerEvents_10_Event_Close

when it closes (more about why later).
Also we are telling Outlook to notify us when a new “Inspector” window opens in Inspectors_NewInspector.
An “Inspector” window is what Outlook calls the windows it brings up for the user to “inspect” things. So when the user opens a contact, for example, that is an “inspector” window. It is in that notification function that we will add our tab to the inspector window.

Here’s where the fun starts.  To get a new tab/page on an Outlook “inspector” window we have to use interop.

Put this code in the Inspectors_NewInspector body:

String strMyTab = "My New Outlook Tab";
((Microsoft.Office.Interop.Outlook.Pages)(inspector.ModifiedFormPages))
.Add(strMyTab);
inspector.ShowFormPage(strMyTab);

Compile MyAddin and then open Outlook. Create a new contact, save it and close it. Now reopen the contact you just created. Voila! Your new tab should be there (for some reason I don’t understand the tabs don’t always show up on existing or new contacts before they are saved).

You now have a basic Outlook Add-in that creates and adds a tab to Outlook inspector windows as they open up.   Congratulations!  The next question might be “What do I do with the tab?”  A good question.  You can design the tab page as a form to your own liking, using the built in fm20.dll common controls.  You can also host Active-X controls (your own or those of a third party) on the tab which would allow for a great deal of customization and integration.

Problems remain with our implementation, however.  None of them are of our doing, but alas, we must deal with them.

More on that next time…

2007
04.13

So far we have created an Add-in for Outlook with the Visual Studio wizard.  If you missed that, you can go back to Part 1

Go ahead and build it and make sure there is no problem there.  If all is well, you should have a bin\Debug directory underneath your MyAddin directory and a MyAddin.dll in it.  If not, you probably set something up wrong.  Try it again from the start.

By default, building with Visual Studio will make the Add-in available from Outlook.  (For this example, I am using Outlook 2003, but other versions are similar).  Just to make sure all is well, after you have built MyAddin, open up Outlook (close and reopen it if it was already open) and choose Tools/Options…  menu item.

In the ensuing dialog, go to the “Other” tab, “Advanced Options…” button.  This brings up another dialog.  Choose the “COM Add-Ins…” button from here which brings up yet another dialog which should be titled something like “COM Add-Ins.”

If all is OK to this point, your shiny new Outlook Add-in should show up in the “Add-Ins available” check list box.  It should also be checked (check it if it is not).  If your Add-in did not show up, something probably went wrong with the build.  I would suggest starting over with the wizard process in Step 1.

Note also that when you highlight your Add-in, the “Location” text at the bottom of the dialog should indicate “mscoree.dll.”  This is the .NET runtime .dll.  Why is mscoree.dll there instead of MyAddin.dll?  What this means is that Outlook is going to load mscoree.dll which will load MyAddin.dll.   Through a bit of registry hocus pocus, .NET basically lies to Outlook and gets it to load .NET first instead of MyAddin.dll.

We will come back to this topic later and discuss why it may not be a good idea to let Outlook do this, and some ways to get around it.

Before we leave the “COM Add-ins” dialog, make sure the “Load Behavior” label says “Load at Startup.”  If not you did something wrong in the wizard set-up.

So where we are now is that when Outlook starts up, it will load your MyAddin.dll (through mscoree.dll) and start talking to it through interop (remember, Outlook is still COM based).  How does it talk to your Add-in?  Through the IDTExtensibility2 interface we learned about in Part 1 of our discussion.

If you are interested in the timing of the loading, you can put a Message Box in OnConnection ( ) and see that your Add-in is loaded just as Outlook is coming up.   (You will have to add a reference to System.Windows.Forms to be able to show a MessageBox)

Before we get on to customizing Outlook, let’s note one further item that has been created for us by Visual Studio.  Look at your project Solution Explorer and there should be a “MyAddinSetup” project there.  If you right click on it and choose “Build,” it will create a setup .msi under the “MyAddinSetup” directory that you can use to install your Outlook Add-in on other machines.

This comes in very handy when it comes time to redistribute your Add-in.  Also, if you right click on the MyAddinSetup project and choose “Properties,” a property page will come up that will allow you to specify Prerequisites for your install.  Click on the “Prerequisites” button and in the ensuing dialog, you can specify what your project needs in order to run.  Make sure the .NET framework is selected here.  Remember, however, that this install will tie your Add-in specifically to mscoree.dll as its Outlook loader.  As noted above, this is not always a good idea.  More about this later.

In Part 3, as promised, we will begin customizing Outlook.  Stay tuned…

2007
04.12

An Outlook Add-in is a .dll that Outlook loads (typically when it starts up).  It can do almost anything you want it to do, including creating custom tabs that show up in places such as Contacts and e-mail message dialogs.  Nifty way to customize Outlook and make it look like your product integrates natively with it!

2007
04.12

One of the more fun things to do as a developer is to interface with Microsoft Office.  That “fun” word is a little bit tongue-in-cheek, because sometimes it is anything but fun to write apps that talk to Office.

I had a recent experience writing an Outlook add-in that hopefully will save you a lot of time and hair pulling (perhaps a bit of head banging also).

I’m also choosing NOT to use VSTO tools for Office, because there are quite a few docs on how to do that already.  This tutorial will be about writing an Outlook Add-in with “raw” C#.  Contrary to what the Microsoft docs might lead you to believe, it is possible!

First, fire up Visual Studio (I’m using 2005) and choose File/New Project…  In the ensuing dialog,  find “Other Project Types” in the tree control and open it up.  Pick “Extensibility” in the tree and “Shared Add-in” from the list on the right.

Give your project a name (“MyAddin” is good enough) and hit OK.  This will bring up the Add-in Wizard.  Hit “Next” and on the next dialog, pick “Create an Add-in  using Visual C#.”   Hit “Next.”

The next step in the wizard allows you to select what applications you want to target.  In this case, un-select all except Microsoft Outlook.  Click “Next.”

In the next dialog give your Add-in a name and a description.  The name is what will show up in the Outlook Add-in page (described later) so you can pick your Add-in to load.

In the next dialog you can choose whether or not to load your Add-in when the host application (Outlook) loads.  Check this box.  The other check box on this screen asks whether this Add-in should be available to all users of the computer it was installed on.   Important: DO NOT check this box. Even though the Microsoft docs say to do so.   The Add-in will NOT work right if you check this box.   The reason has to do with where your Add-in gets put in the Windows registry and where Outlook tries to find Add-ins to load.

Click “Next” then “Finish” on the last dialog.

Visual Studio will create a project for you with several files, the most important of which is “connect.cs”   This is an interop class (yes, Office is still COM based) that implements an interface called IDTExtensibility2, which is the interface Outlook talks to in its Add-ins.

There are several methods here that get called at various times by Outlook.   Just briefly they are:

OnConnection( )

This gets called when the Add-in is being loaded by Outlook.  It is passed several parameters – The interesting ones are: The Application object, and an instance of the Add-in (as objects).

OnDisconnection( )

Called when the Add-in is being unloaded.

OnAddInsUpdate ( )

Not particularly interesting unless you care when the collection of Outlook Add-ins is changing.

OnStartupComplete ( )

Notification that Outlook has completed loading.  Might be useful in some cases.

OnBeginShutdown ( )

Notification that Outlook is being unloaded.  Might also be useful in some cases.

The most interesting of the methods is OnConnection and it is where we will begin our customization of Outlook.

More in Part 2….

2007
04.08

Welcome

Welcome to Midniteblog.com.  Here you will find ideas and ruminations about life in general and more specific topics about computers and programming.  I love to write code and I do it both for a living and as a hobby (kinda nerdy, huh?). 

Hopefully something you find here will be of use and I also hope you will leave your constructive thoughts and ideas behind for the benefit of others.

-MidniteBlogger