Deploying COM Add-ins for 64-bit Office using Visual Studio (Saaid Khan for Nathan Halstead)

Nathan Halstead is a Program Manager on the Visual Studio Team. He is responsible for various aspects of Visual Studio extensibility, and is an avid ice hockey enthusiast. On occasion, he’s been known to guest author technical articles on various Microsoft blogs and forums. My only contribution to this blog is posting it here :). Here is what Nathan has to say:

Later this year, Microsoft will release the next version of its Office productivity suite – Office 2010. The 2010 release will be offered in both 32 and 64-bit flavors. The new 64-bit flavor of Office is especially useful for enabling computationally rich applications requiring larger amounts of system resources. However, the move to 64-bit poses some additional challenges for add-in developers who want to target both the 32 and 64-bit versions of Office.

For the past few releases, Visual Studio has shipped with several templates for creating add-ins for Office. If you are planning to build extensions for Office, and have not already done so, I strongly encourage you to take a look at the Visual Studio Tools for Office (VSTO) templates, which offer visual designers and managed APIs for developing and testing your Microsoft Office extensions.

If you can’t or don’t want to use the VSTO templates, Visual Studio also offers a bare-bones template for developing COM-based add-ins for Office called the “Shared Add-in” template. This template generates a solution which includes a basic implementation Office’s IDTExtensibility2 interface, and a lightweight MSI project for deploying the add-in. For the past several years, this bare-bones template has been sufficient for getting started with Office extensibility. If, however, you want to use it to target 64-bit Office, there are a few issues you might encounter that you should be aware of. This article will briefly walk you through these issues and explain how to work around them.

Creating a new Shared Add-in

To create a new Shared Add-in, select the project template from the new project dialog. For the purposes of this example, we will be creating a globally registered C# based add-in using Visual Studio 2008. To do this, launch Visual Studio with Administrator privileges (to ensure the build process has permissions to the HKCR registry hive) and select a new Shared Add-in under “Other Project Types -> Extensibility”:

clip_image002[4]

A wizard will appear to guide you through the creation of your Add-in. Note that if you did not launch Visual Studio with Administrator privileges, the option to globally register your add-in will be disabled:

clip_image004[4]

When you’ve finished the wizard, your solution will be generated, and configured for proper x86 deployment.

Registering the add-in with 64-bit Office for debugging

When the Shared Add-In Wizard finishes generating the solution, it automatically registers your add-in with the Office applications specified in the wizard. This ensures that debugging can work without running your setup application. If you selected the “My add-in should be available to all users…” option in the wizard, it registers your add-in to the 32-bit global registry location viewable in Regedit as [HKLM\Software\Wow6432Node\Microsoft\Office\<App>\AddIns\<AddInName>].

However, 64-bit Office cannot see registration information in this location. To load your add-in automatically, this registration information will need to be copied to 64 bit registry locations for 64-bit Office to see. To do this, copy all of the registry keys under [HKLM\Software\Wow6432Node\Microsoft\Office\<App>\AddIns\<AddInName>] to [HKLM\Software\Microsoft\Office\<App>\AddIns\<AddInName>].

For example, you would copy the following keys for Word registration:

From

To

[HKLM\SOFTWARE\Wow6432Node\

Microsoft\Office\Word\Addins\MyAddin1.Connect]

"FriendlyName"="Name"

"Description"="Description"

"LoadBehavior"=dword:00000003

[HKLM\SOFTWARE\Microsoft\Office\Word\

Addins\MyAddin1.Connect]

"FriendlyName"="Name"

"Description"="Description"

"LoadBehavior"=dword:00000003

Retargeting for x64 deployment

clip_image006[4]

With your new solution in hand, the next step is to update its installer to follow 64-bit Windows deployment conventions. To do this, select the Setup project in the Solution Explorer, and update the project’s TargetPlatform property to x64 in the Properties window.

If you are using Visual Studio 2010, this is the only change that should be needed for your deployment project. Your installer will now be able to properly register your add-in with 64-bit versions of Office!

However, if you are using Visual Studio 2008, a bug in the deployment project system prevents the proper registration of 64-bit COM components. To work around this limitation, follow the instructions listed in the listed in the Troubleshooting Windows Installer Deployments topic on MSDN. See the Cannot load 64-bit self-registering DLL’s section, which describes in detail how to work around this for your Shared-Add-in assemblies by manually writing the 64-bit registry keys that register your COM assemblies.

Making your entire solution 64-bit

While native C++ applications will need to be updated to explicitly target 64-bit machines, in most cases Office will happily load your.NET add-ins without requiring you to explicitly target an x64 platform. However, there are situations where you will have to update your .NET assembly to be explicitly 64-bit. For example, Misha Shneerson highlights a situation on his blog where you may choose to use unsafe code to preserve icon transparency when rendering Office icons. If you use unsafe code, then you will need to recompile your assembly for the x64 platform.

Before doing this, you should familiarize yourself with some of the work that may be involved to ensure your add-in works properly when running 64-bit. There are a large number of resources available on this topic, but this MSDN article does a good job covering some of the fundamental considerations for .NET applications, and this vintage MSDN Magazine article does a fantastic job for native C++ applications.

If you need to build a 64-bit assembly, you will need to update your project’s build properties to do so. You may do this from within the properties editor for your project. For example, in a C# project, right click, and select properties to open the properties editor:

clip_image008[4]

Navigate to the build tab, and change the Platform Target to x64:

clip_image010[4]

For most Visual Studio projects, a 64-bit binary would be generated when you save and build. However, there is a bug in the VB and C# project systems that causes a build error for Shared Add-in projects. When you attempt to build, you will receive an error that states that your dll “is not a valid assembly.”

The culprit is the “Register for COM interop” project setting on the build tab:

clip_image012[4]

By selecting this checkbox, a build task is automatically generated to register the COM assembly. This is used by the template to make it easier to test your add-in by automatically deploying your assembly on your machine. However, this task uses the 32-bit version of the regasm tool, which throws a “is not a valid assembly” error when run against 64-bit assemblies. The workaround for this issue is described in KB Article 956933, and involves unchecking this option, and creating your own build event to do the 64-bit registration.

A best practice for COM add-ins

With your setup project and your add-in assemblies updated, you will now be able to install and run your COM addin inside 64-bit Office applications! However, if you decide to build your add-in for Office without using VSTO, I would highly recommend using the COM Shim wizard, which will help you isolate your add-in ino a separate app-domain for better resiliency:

· VS 2008 COM Shim Wizard

· VS 2010 COM Shim wizard

· COM Shims and x64 Office

 

If you have additional recommendations and best-practices you think would be helpful to share, please include these in the comments! Have fun extending Office 2010!

Saaid Khan, Program Manager