Using the COM Add-in Shim Solution to Deploy Managed COM Add-ins in Office XP

Click here to download sample - odc_comshim.exe. This content is no longer actively maintained. It is provided as is, for anyone who may still be using these technologies, with no warranties or claims of accuracy with regard to the most recent product version or service release.

 

Misha Shneerson and Siew-Moi Khor
Microsoft Corporation

May 2002

Applies to:
     Microsoft® Office XP

Summary: How to use the COM add-in shim solution template to enable secure managed COM add-in deployment in Microsoft Office XP. (14 printed pages)

Download Odc_comshim.exe.

Contents

Introduction
Download the COM Add-in Shim Solution and Managed COM Add-in Sample
Test the Managed COM Add-in DLL
Procedure for Incorporating the Unmanaged COM Add-in Shim into a Managed COM Add-in Project
Insert the Correct Assembly, Public Key Token, and Connect Class Values
Checklist and Notes
Conclusion

Introduction

Deploying and installing a managed COM add-in securely in Microsoft® Office XP currently requires the assembly be hosted in an unmanaged COM add-in proxy component called a shim. The explanation on what a shim is and why it is currently needed to deploy COM add-in DLLs has been discussed in detail in the Deployment of Managed COM Add-Ins in Office XP article on MSDN and therefore won't be repeated here. This article will concentrate on how to use the COM add-in shim solution template so that you can successfully deploy your managed COM add-in under the highest Office XP security setting.

It's assumed that the reader:

  • Has read Deployment of Managed COM Add-Ins in Office XP.
  • Knows what a COM add-in is, and how to build, deploy and install one. For more information about COM add-ins, What is a COM Add-in? is a good place to start.
  • Knows how to build managed COM add-ins using Microsoft Visual Studio® .NET. This article does not include a tutorial on how to build one.
  • Knows how to strong name an assembly.
  • Knows what code signing is and how to code sign. For information on how to code sign, Digital Code Signing Step-by-Step Guide has detailed step-by-step instructions and explains how to code sign using Microsoft Authenticode® technology.
  • Is familiar with Microsoft .NET security, and .NET and COM Interop.

Download the COM Add-in Shim Solution and Managed COM Add-in Sample

The first thing you need to do is to download the COM add-in shim solution and managed COM add-in sample on a machine that has the .NET Framework, Visual Studio .NET, and Office XP installed:

  1. Download odc_comshim.exe and run this self-extracting archive to save the odc_comshim.msi and comshimChecklist.xls files on your local computer.
    • The comshimChecklist.xls file is a checklist to help you keep track of the tasks that need to be accomplished when using the COM add-in shim solution.
    • The odc_comshim.msi file contains the smart tag shim solution template and a sample managed smart tag.
  2. Install the odc_comshim.msi and save the download in a folder named COMAddinShimTutorial, that is, C:\COMAddInShimTutorial.

If you examine the C:\COMAddinShimTutorial folder after you have installed the MSI, you should find two subfolders in that folder: COMAddInShim and HelloCOMAddInVB. The HelloCOMAddInVB folder contains another subfolder with the name HelloCOMAddInVBSetup.

  • The COMAddInShim folder contains the COM add-in shim solution project written in unmanaged Microsoft Visual C++®. To view this project, open COMAddIn.sln and the project will open up in Visual Studio .NET.
  • The HelloCOMAddInVB folder contains a simple managed COM add-in Microsoft Visual Basic® .NET project. The name of the COM add-in assembly is HelloCOMAddInVB. This project will be used to demonstrate how to add the COM add-in shim to a managed COM add-in project. To view this project, open HelloCOMAddInVB.sln located in C:\COMAddInShimTutorial\HelloCOMAddInVB\. This folder also contains a subfolder with the name HelloCOMAddInVBSetup.
  • The HelloCOMAddInVBSetup folder contains the managed HelloCOMAddInVB COM add-in installer project.

Test the Managed COM Add-in DLL

Before incorporating the COM add-in shim into the managed COM add-in project, let's first test the managed HelloCOMAddInVB COM add-in in Microsoft Word. The managed HelloCOMAddInVB COM add-in is a very simple COM add-in sample that displays a dialog box when the first instance of Word is activated. The dialog box is shown in Figure 1.

Aa140200.odc_comshim01(en-us,office.10).gif

Figure 1. The HelloComAddInVB DLL displays a dialog box.

Prepare Office XP Security Settings

Before installing the managed HelloCOMAddInVB DLL, the security settings in Microsoft Word need to be set to Medium, with the Trust all installed add-ins and templates settings disabled.

Note   After you are done testing, reset these security settings to whatever level they were at prior to testing by making the appropriate changes in the Security dialog box as shown in the steps below.

To change the security settings:

  1. Start Microsoft Word.
  2. On the Tools menu, point to Macro, and then click Security. This displays the Security dialog box.
  3. On the Security Level tab, click Medium.
  4. Click the Trusted Sources tab. Uncheck the Trust all installed add-ins and templates box.
  5. Quit Word.

Install the Managed HelloCOMAddInVB DLL

Before installing the managed HelloCOMAddInVB COM add-in DLL, close all instances of Word that are currently open. To install the COM add-in, do the following:

  1. To open the HelloCOMAddInVB project in Visual Studio .NET, open the HelloCOMAddInVB.sln file located at C:\COMAddInShimTutorial\HelloCOMAddInVB.
    You should find two projects in the Solution Explorer of the Visual Studio .NET IDE: HelloCOMAddInVB and HelloCOMAddInVBSetup.
  2. First, rebuild the managed COM add-in by right-clicking on the HelloCOMAddInVB project and then clicking Rebuild.
  3. Next build the managed COM add-in setup project by right-clicking on the HelloCOMAddInVBSetup project and then clicking Build.
  4. You can now install the COM add-in by right-clicking on the HelloCOMAddInVBSetup project and then clicking Install. This will launch the HelloCOMAddInVBSetup setup wizard.
  5. Click Next.
  6. In the Select InstallationFolder dialog box, type C:\COMAddInShimTutorial\ in the Folder edit field.
  7. Click Next.
  8. Click Next. This installs the managed HelloCOMAddInVB COM add-in.

Test the Managed HelloCOMAddInVB DLL

  1. Open Word. You should see a security warning dialog box like the one shown in Figure 2. This security warning is displayed because mscoree.dll—the main entry point of the common language runtime engine—is not signed.
    If in the Prepare Office XP Security Settings section above you had set the security level to High with the Trust all installed add-ins and templates box unchecked, you wouldn't get this security warning at all. This is because Office XP automatically disables all unsigned components when security is set at its highest.

    Aa140200.odc_comshim02(en-us,office.10).gif

    Figure 2. Security dialog box warning that mscoree.DLL is not signed.

  2. Click Enable Macros.

  3. You should then see the dialog box shown in Figure 1 displayed.

  4. Click OK.

Uninstall the Managed HelloCOMAddInVB COM Add-in DLL

  1. Close all instances of Word that are open.
  2. In the Solution Explorer of the Visual Studio .NET IDE, uninstall the HelloCOMAddInVB COM add-in by right-clicking on the HelloCOMAddInVBSetup project and then clicking Uninstall.

This will uninstall the HelloCOMAddInVB DLL. Double check this by opening Word. You should not get a prompt similar to Figure 2 (assuming you don't have any other managed COM add-ins installed).

Remove the HelloCOMAddInVBSetup Project

The HelloCOMAddInVBSetup project was included to make it easy for you to install and test the managed HelloCOMAddInVB DLL. Before incorporating the unmanaged COM add-in shim into the managed HelloCOMAddInVB project, remove the HelloCOMAddInVBSetup project.

  1. To do this, in the Solution Explorer, right-click on the HelloCOMAddInVBSetup project and then click Remove.
  2. Click OK.

Procedure for Incorporating the Unmanaged COM Add-in Shim into a Managed COM Add-in Project

We have broken down the procedure to ten main steps as listed below:

  1. Add the COMAddInShim project to your managed COM add-in project.
  2. Set the COM add-in shim properties.
  3. Incorporate the correct assembly name, public key token value, and Connect class value.
  4. Generate GUIDs for the COMAddInShim Type Library and Connect class.
  5. Change the sample COMAddInShim and Connect class names.
  6. Add ProgID registration details.
  7. Rebuild the solution.
  8. Sign the modified unmanaged COM add-in shim DLL, and if you are doing delay signing, the managed COM add-in DLL.
  9. Create an MSI using the setup and deployment project.
  10. Test the MSI.

Add the COMAddInShim Project to Your Managed COM Add-in Project

The first thing you need to do is add the COM add-in shim to your managed COM add-in project in Visual Studio .NET. As an illustration, we will be using the HelloCOMAddInVB assembly as an example. If you have your own COM add-in assembly handy, you may use that instead if you feel inclined to.

Note   You can still continue to make changes to your managed COM add-in code even after you have added the COM add-in shim to the project. Development on your COM add-in assembly doesn't have to be frozen; it can continue in parallel.

  1. In the Solution Explorer of the Visual Studio .NET IDE, right-click on Solution "HelloCOMAddInVB" (1 project).
  2. Point to Add.
  3. Click Existing Project.
  4. Locate C:\COMAddInShimTutorial\COMAddInShim\COMAddInShim.vcproj.
  5. Click Open. This will add a project which contains the unmanaged COM add-in shim to your solution in Visual Studio .NET.

Set the COM Add-in Shim Properties

Since the COM add-in shim is a template, you will need to change certain COM add-in shim properties, for example the name of the shim, to avoid name collision. The properties that you need to change are as follows:

  1. In the Solution Explorer, right-click on the COMAddInShim project.

  2. Click Properties. This will display the COMAddInShim Property Pages dialog box.

  3. Under General configuration properties, change the Output Directory so that the COM add-in shim DLL will be created in the same folder as the HelloCOMAddInVB assembly. Type the following value in the Output Directory edit box:
    ..\HelloCOMAddInVB\Bin.

    Note   Make sure there are only two dots preceding \HelloCOMAddinVB\Bin. If, for example, you accidentally put three dots instead, compiling the solution will return an error.

  4. Rename the COMAddInShim.dll to avoid name collision. In this example, we will rename it to HelloCOMAddInVBShim.dll. To do this, in the Linker configuration properties, under Output File, type the following value:
    $(OutDir)/HelloCOMAddInVBShim.dll.

  5. Click OK.

  6. In the Solution Explorer, open the Resource Files folder of the COMAddInShim project.

  7. Double-click on COMAddInShim.rc to display the Resource ViewCOMAddInShim window.

  8. Open the COMAddInShim.rc folder, and then open the Version folder.

  9. Double-click on VS_VERSION_INFO to display the version information.

  10. Double-click InternalName and change the shim name from COMAddInShim.dll to its new name: HelloCOMAddInVBShim.dll.

  11. Do the same for OriginalFileName. Change it from COMAddInShim.dll to HelloCOMAddInVBShim.dll.

Insert the Correct Assembly, Public Key Token, and Connect Class Values

Again, because the COM add-in shim is a template, the assembly name, public key token value, and Connect proxy class name are only samples. They need to be changed to correctly match the real names and value.

Assembly Name

  1. In the Solution Explorer, open the Source Files folder of the COMAddInShim project.

  2. Double-click on the ShimConfig.cpp file.

  3. Replace the sample assembly name ManagedAddIn in

    static LPCWSTR szAddInAssemblyName = L"ManagedAddIn,
      PublicKeyToken=6c96c7507b8e2be8";
    

    with the correct COM add-in assembly name. For this particular tutorial, the assembly name is HelloCOMAddInVB.

Public Key Token

  1. First, retrieve the HelloCOMAddInVB.dll assembly public key token. To do this, click Start, point to Programs, point to Microsoft Visual Studio .NET, point to Visual Studio .NET Tools, and click Visual Studio .NET Command Prompt.

  2. In the Visual Studio .NET Command Prompt window, go into the HelloCOMAddInVB\bin folder by typing cd C:\COMAddInShimTutorial\HelloCOMAddInVB\bin as shown in Figure 3.

  3. Retrieve the public key token of the HelloCOMAddInVB assembly using the sn-T command line option. To do this, after
    C:\COMAddInShimTutorial\HelloCOMAddInVB\bin>
    type sn-T HelloCOMAddInVB.dll as shown in Figure 3.

    Click here for larger image

    Figure 3. Command line options to retrieve the public key token (click thumbnail for larger image)

  4. Copy the public key token, which in this case is 1a9f13915390d0a4.

    Note   To be able to copy quickly, make sure the command prompt properties are set correctly. To check this, right-click the Visual Studio .NET Command Prompt title bar, and then click Properties. In the Options tab, make sure both the QuickEdit Mode and Insert Mode boxes are checked.

    To copy, press and hold the primary mouse button to highlight the GUID value you want to copy. Then click the secondary mouse button to copy the selected text to the Clipboard.

  5. Replace the sample public key token value6c96c7507b8e2be8in the ShimConfig.cpp file with 1a9f13915390d0a4 in

    static LPCWSTR szAddInAssemblyName = L"HelloCOMAddInVB, 
      PublicKeyToken=6c96c7507b8e2be8";
    

    It should now read:

    static LPCWSTR szAddInAssemblyName = L"HelloCOMAddInVB,
      PublicKeyToken=1a9f13915390d0a4";
    

Connect Class Name

In the ShimConfig.cpp file, replace the sample Connect class name in

static LPCWSTR szConnectClassName = L"ManagedAddIn.Connect";

with the correct full Connect class name. For this particular tutorial, it is HelloCOMAddInVB.Connect. After you have done that it should look as follows:

static LPCWSTR szConnectClassName = L"HelloCOMAddInVB.Connect";

Generate GUIDs for the COM Add-in Shim 1.0 Type Library Unmanaged COM Add-in Connect Proxy Class

The GUIDs for the COM add-in shim type library and the Connect class in the shim template are samples. To avoid possible GUID collision, the sample GUIDs must be replaced with newly created ones. To generate GUIDs, you can use the uuidgen utility.

Generate GUID for the unmanaged COM add-in Shim Type Library:

  1. In the Visual Studio .NET Command Prompt window again, after C:\COMAddInShimTutorial\HelloCOMAddInVB\bin>, type uuidgen as shown in Figure 4. This generates a GUID.

    Click here for larger image

    Figure 4. Generating a GUID using the uuidgen utility (click thumbnail for larger image)

  2. Copy the GUID to the Clipboard.

  3. In the Solution Explorer, open the COMAddInShim project Source Files folder. Double-click on the COMAddInShim.idl file.

  4. Replace the sample unmanaged COM add-in Shim 1.0 Type Library CLSID highlighted below with the GUID you just generated in step 1 at:

         [
            uuid(837A3F0C-7C1D-46C0-B487-B7846228B062),
            version(1.0),
            helpstring("COMAddInShim 1.0 Type Library")
         ]
    

Generate GUID for the unmanaged connect proxy class

  1. In the Visual Studio .NET Command Prompt window, after C:\COMAddInShimTutorial\HelloCOMAddInVB\bin>
    type uuidgen to generate a GUID.

  2. Copy the GUID to the Clipboard.

  3. In the Solution Explorer, open the COMAddInShim project Source Files folder. Double click on COMAddInShim.idl. Replace the sample Connect proxy class CLSID highlighted below with the GUID you just generated in step 1 at:

         [
            uuid(74F31DDE-5215-4436-BBF6-233AD1C707D2),
            helpstring("ConnectProxy Class")
         ]
    
  4. Open the COMAddInShim project Resource Files folder, and then double-click on the ConnectProxy.rgs file. Replace the sample Connect proxy class CLSID highlighted below with the GUID you just generated in step 1 in three places.
    First at:

         {
            CLSID = s '{74F31DDE-5215-4436-BBF6-233AD1C707D2}'
         }
    

    Second at:

         {
            CLSID = s '{74F31DDE-5215-4436-BBF6-233AD1C707D2}'
            CurVer = s 'ComAddInShim.ConnectProxy.1'
         }
    

    And lastly at:

    ForceRemove '{74F31DDE-5215-4436-BBF6-233AD1C707D2}' = s 'ConnectProxy Class'
    

Change the Sample COMAddInShim and Connect Class Names

The sample COMAddInShim and Connect proxy class names must be changed to correctly match the real names. To make the changes, open the Resource Files folder and double-click on the ConnectProxy.rgs file.

  1. Using the Ctrl + H short cut key, find and replace the two instances ofComAddInShim.ConnectProxywith the correct full class name, which in this case isHelloComAddInVBShim.Connectand three instances of ComAddInShim.ConnectProxy.1 with HelloComAddInVBShim.Connect.1.
  2. Using the Ctrl + H short cut key, find and replace the three instances of ConnectProxy Class with Connect Class.

Add ProgID Registration Details

The unmanaged COM add-in ProgID needs to be registered into the HKEY_CURRENT_USER (HKCU) hive. For this example, we will only register it for Word. To do this, double click on the ConnectProxy.rgs file. Add the following code at the end of the ConnectProxy.rgs file.

HKCU
{
    NoRemove Software
    {
        NoRemove Microsoft
        {
            NoRemove Office
            {
                NoRemove Word
                {
                    NoRemove Addins
                    {
                        ForceRemove HelloComAddInVBShim.Connect 
                                {
                                     val 'Description' = s 'My Desc'
                                     val 'FriendlyName' = s 'My Name'
                                     val 'LoadBehavior' = d 3
                                }
                    }

                }

            }

        }

    }

}

Note   If you want your COM add-in to work in other Office XP applications like Microsoft Excel or Microsoft Access, you will have to add the above code for each application to the ConnectProxy.rgs file. Be sure to change

NoRemove Word

to

NoRemove Excel

or whatever application you want the COM add-in to run.

Rebuild the Solution

  1. Close all instances of Word that are open.
  2. In the Solution Explorer, right-click on the COMAddInShim project, then click Rebuild.

Sign the Unmanaged COM Add-in Shim DLL and Managed COM Add-in DLL (If You Are Doing Delay Signing)

  1. Authenticode sign the COM add-in shim DLL. You have renamed the shim to HelloCOMAddInVBShim.dll in step 4 of the Set COM add-in Shim Properties procedure, so HelloCOMAddInVBShim.dll would be the DLL you want to Authenticode sign.
  2. If you are doing delay signing on your assembly, now is the time to complete the signing.

Create an MSI Using the Setup and Deployment Project

It is highly recommended that you build an MSI to install the managed COM add-in along with the COM add-in shim you intend to deploy to the public. In Visual Studio .NET, it is very easy to build one.

Create setup and deployment project

  1. In the Solution Explorer, right-click on Solution "HelloCOMAddInVB" (2 projects).
  2. Point to Add.
  3. Click New Project. This will display the Add New Project dialog box.
  4. In the Project Types frame, click Setup and Deployment Project.
  5. In the Templates frame, select Setup Project.
  6. In the Name edit field, rename the project to HelloCOMAddInVBwShimSetup.
  7. Click OK.

Add assembly to the setup and deployment project

The managed COM add-in DLL is one of the files that needs to be included in the setup and deployment project. To do this:

  1. In the Solution Explorer, right-click on the newly created HelloCOMAddInVBwShimSetup project.
  2. Point to Add. Click Assembly. This displays the Component Selector dialog box.
  3. Click Browse and locate C:\COMAddInShimTutorial\HelloCOMAddInVB\bin.
  4. Select HelloCOMAddInVB.dll. Click Open.

HelloCOMAddInVB.dll is now added to the Selected Components edit box in the Component Selector dialog box. Click OK.

Add project output to the setup and deployment project

Make the COM add-in shim the primary output of the setup and deployment project. The shim will be the signed unmanaged component that will be registered.

  1. In the Solution Explorer, right-click the HelloCOMAddInVBwShimSetup project.
  2. Point to Add. Click Project Output. This displays the Add Project Output Group dialog box.
  3. In the Project drop-down menu, select COMAddInShim.
  4. In the list box, click Primary Output.
  5. Click OK.

Set the primary output registration property

The signed COM add-in shim registration details need to be added to the registry. The keys and values that need to be registered are specified in the ConnectProxy.rgs files. These keys and values are then compiled into the DLL file to enable a process known as self registration to be performed, which is usually handled by the regsvr32 utility. To enable self registration to be performed from within the installation package, the Register property of the smart tag shim must be set to vsdrpCOMSelfReg.

  1. In the Solution Explorer, under the HelloCOMAddInVBwShimSetup project node, right-click Primary Output from COMAddInShim and then click Properties to view its property details.
  2. In the Properties box, in the Register drop-down menu, select vsdrpCOMSelfReg.

Set the assembly registration property

The managed COM add-in doesn't need to be registered for COM interop since it will be called from within the shim.

  1. Under the HelloCOMAddInVBwShim project node, right-click HelloCOMAddInVB.dll and then click Properties to view its property details.
  2. In the Properties box, under the Register drop down menu, make sure vsdraDoNotRegister is selected.

Build the MSI

Now that you are done including all the needed files, excluding the unneeded files, and resetting properties for the setup project, you are ready to build an MSI. To do this, right-click the HelloCOMAddInVBwShimSetup project, and then click Build. This creates a HelloCOMAddInVBwShimSetup.msi.

Test the MSI

In this example, the HelloCOMAddInVBwShimSetup.msi you have just created will be in the C:\COMAddInShimTutorial\HelloCOMAddInVBwShim\Debug folder. Test the MSI thoroughly before deploying it.

Checklist and Notes

For your convenience, a table check list has been created for you to help you keep track of the tasks that need to be accomplished when using the COM add-in shim solution template. To reference the checklist, open the comshimchecklist.xls file included in the download discussed in the Download the COM Add-in Shim Solution and Managed COM Add-in Sample section.

A few important points to remember and note:

  1. It is important for security reasons to never fail to include the public key token in the ShimConfig.cpp file. By specifying the assembly strong name and, especially, its public key token (while keeping the corresponding private key secret) will ensure that the assembly to be loaded is the intended one.
  2. Your COM add-in assembly should not register for COM Interop. This is because the assembly will be called from the shim and as such does not need to be registered for COM Interop. To disable register for COM Interop property, in the assembly property pages dialog box, open the Configuration Properties folder and click on Build. Uncheck the Register for COM Interop box.
  3. Even after adding the COM add-in shim to your assembly project, you can still continue developing your COM add-in assembly. The content of your assembly doesn't have to be frozen. Development can continue in parallel.
  4. The shim DLL must be signed with Authenticode.
  5. Your COM add-in assembly must be signed with a strong name.
  6. Strongly name other private assemblies that the COM add-in assembly might depend on.
  7. It should be noted that the security model for Microsoft Outlook® 2002 differs from other Office XP applications. In Outlook 2002, whether an Outlook COM add-in will be loaded or not is not determined by a user's security settings described in Table 1 of the Deployment of Managed COM Add-Ins in Office XParticle. In addition to a user’s security settings, COM add-ins (regardless of whether they are signed or not) are subjected to the restrictions on certain Outlook 2002 object model property and method calls imposed by the Outlook E-mail Security Update that is an integral component of Outlook 2002.
    For an Office COM add-in to have unrestricted access to the Outlook 2002 object model, the COM add-in must also be added to the Trusted Code page of the Administrative Form. To add an Outlook COM add-in developed with Visual Studio .NET to the Trusted Code page of the Administrative Form, you must develop your Outlook managed COM add-in with the COM add-in shim discussed in this article. You then add the shim DLL to the Trusted Code list. Do not add mscoree.dll to the Trusted Code page in the Administrative Form.
    For more information on the Outlook E-mail Security Update and the Administrative Form in the Outlook Security Settings Public Folder, see the following whitepapers and KB articles:

Conclusion

By incorporating the COM add-in shim solution template to your managed COM add-in project, you will be able to deploy your COM add-in assembly to end users even when their Office XP security is set at High with Trust all installed add-ins and templates disabled. You will be able to digitally sign the shim DLL and therefore comply with the Office XP security signature checking mechanism. In addition, you will have some level of control over what the common language runtime does.

Acknowledgement

We would like to thank Randy Byrne for his contribution to the Outlook 2002 security note in the article.