Article Options
Premium Sponsor
Premium Sponsor

 »  Home  »  .NET Framework  »  Achieving Backward Compatibility with .NET Interop: Excel as Case Study
 »  Home  »  Windows Development  »  Interop  »  Achieving Backward Compatibility with .NET Interop: Excel as Case Study
Achieving Backward Compatibility with .NET Interop: Excel as Case Study
by Scott Rutherford | Published  07/23/2005 | .NET Framework Interop | Rating:
Scott Rutherford
Scott Rutherford is a consultant and .NET developer who has developed Enterprise business applications in many fields including Restaurant, Market Research, Automotive, and Analytical Chemistry. He is an Microsoft Certified Professional with the .NET Platform. 

View all articles by Scott Rutherford...
Using the Type Library

Problem: COM Automation across multiple COM versions

Microsoft Visual Studio .NET makes linking to COM components extremely easy. You simply right click "References" in the Project Explorer, and Add New Reference. You can then browse through the available .NET Assemblies and COM components to find the code library you wish to automate. Every COM interface available on the machine is described by a Type Library (commonly held in a TLB file, and referenced by a CLASSID in the Registry). When you add this reference to your project, the type library is wrapped with a .NET Interop assembly that allows you to use the COM interface at design-time, and then handles the calls to COM at run-time. When type libraries exist with multiple versions, this can complicate your life significantly.

Case: Microsoft Excel


The Add Reference dialog shows Excel 11.0 Object Library when Excel 2003 installed

As an example, we will look at Microsoft Excel. Depending on which version of MS Excel is loaded on the machine on which your project is compiled, you will get a different Interop created. If the project is then deployed to a machine with a different version of Excel, you can expect to run into problems. Microsoft has kept Office backward compatible for a few generations so you can expect most previous functionality to be available still in Office 2003 (aka 11.0). In a Production environment that spans multiple versions of office, however, you may still run into errors, because the structure of type libraries and how they are linked in the registry has changed. The PIA (Primary Interop Assembly) concept further complicates .NET deployment where backward compatibility is concerned.

[Visual Basic]
    Sub FillRange(ByRef rng As Excel.Range, ByVal iLength As Integer, ByVal iWidth As Integer)
        Dim saRet(iLength, iWidth) As Object
        ' ... fill array with values
        rng = rng.Resize(iLength, iWidth)
        rng.Value = saRet
    End Sub
VB code assigns a 2-dim String array to the Value property of an Excel.Range object

[System.Runtime.InteropServices.COMException] -2147352559 (80020011) Does not support a collection.
The above code produces this error when compiled on an Excel 2003 machine and run on Excel 2000

Generally, you can only install a single version of Office on a particular PC; various CLASSIDs that represent objects in the application are thus "installed", or "registered" to trigger this version. When a subsequent version is installed on the machine, previous versions are overwritten. Hence, Visual Studio will always only find one version to which it can link. In the case of PIAs, VS.NET will find a copy with a strong name, in the GAC, and hence will not even make an Interop assembly. Surprisingly, even if you explicitly link to a particular Type Library, VS.NET will override your reference and use the registered version.

Solution

You will find three distinct methods suggested to work around these problems:

  1. Build your project on different machines for compatibility with each respective version of Office.
  2. Install different versions of Office on your build machine (How-to).
  3. Use "Late Binding" to call whatever version of Office is available at run-time

Here, I suggest a fourth method: build to the lowest common denominator.

NOTE: Although this strategy was suggested by MS Support in Writing Automation Clients for Multiple Office Versions, it does not work with VS.NET 2003/5 and Excel 2003. VS.NET now updates all Interop references to match ActiveX libraries installed in the Registry--any manually created reference to an unregistered version is overwritten at compile time (except by the steps outlined below). MS Support now recommends one of the above 3 approaches. In fact, when I suggested this as a feature for the VS 2005 Beta version, it was deemed too complicated and excluded "By Design". The steps outlined below are surprisingly simple.

Find the lowest version with which the project will need to work in the Production environment and build to this. For advanced functionality only available on later versions this method can be extended--providing multiple Interop assemblies that will work in parallel. Additionally, this does not rely on having a particular version of the type library installed on the build machine--nor any version at all, for that matter. It does, however, require that you have access to the Type Library files in the version against which your project will build.

Step-By-Step

In order to build my project against Excel 2000, on a machine that has only Excel 2003 installed, I performed the following steps:

  1. Locate the Excel 9 (2000) Type Library
    • Normally, type libraries are named *.TLB
    • After a little googling, however, I found that the Excel 9 type library is called EXCEL9.OLB
    • I quickly found the EXCEL.OLB file on my (fully licensed and registered!!!) Office 2000 installation CD.
  2. Copy the Excel 9 Type Library to the build machine
  3. Create an Interop Assembly from the Excel9 Type Library
    • Choose a unique name that will distinguish YOUR Interop DLL from others that may be found
    • Use the .NET SDK Tool called TLBIMP.exe to build your Interop Assembly from the command line

     @echo off
     SET prog="C:\Program Files\Microsoft Visual Studio .NET 2003\SDK\v1.1\Bin\TlbImp.exe"
     %prog% EXCEL9.OLB /out=My.Excel9.Interop.dll
     pause
    
    DOS Batch commands to create the explicit Interop DLL using the TlbImp tool provided with the .NET SDK

  4. Link this new Interop Assembly to the VS.NET project, and build
    • Set the "Private" (aka "CopyLocal") property to True


    Browse... to the new Interop DLL in the Add Reference dialog

  5. Update code to reference the new Interop Library
    [Visual Basic]
        Sub FillRange(ByRef rng As My.Excel9.Interop.Range, ByVal iLength As Integer, ByVal iWidth As Integer)
    
  6. Deploy this Interop Assembly in the \bin directory along with the project
    • Your project will now work on any machine with Office 2000 or higher

References

.NET Framework Tools : Type Library Importer (Tlbimp.exe)
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cptools/html/cpgrftypelibraryimportertlbimpexe.asp

INFO: Writing Automation Clients for Multiple Office Versions
http://support.microsoft.com/kb/q244167

Working with the Office XP Primary Interop Assemblies
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnoxpta/html/odc_oxppias.asp

Office XP Primary Interop Assemblies Known Issues
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnoxpta/html/odc_piaissues.asp

Official Office 2003 Interop PIAs
http://support.microsoft.com/?scid=kb;en-us;897646&spid=2525&sid=global

INFO: Develop Microsoft Office solutions with Visual Studio .NET
http://support.microsoft.com/kb/q311452/

How would you rate the quality of this article?
1 2 3 4 5
Poor Excellent
Tell us why you rated this way (optional):

Article Rating
The average rating is: No-one else has rated this article yet.

Article rating:4.65 out of 5
 80 people have rated this page
Article Score28488
Related Articles
Attachments
Comments    Submit Comment

Comment #1  (Posted by an unknown user on 08/08/2005)
Rating
Becuase this will only work for products like Excel and Word. It will not work with Outlook.
 
Comment #2  (Posted by an unknown user on 08/15/2005)
Rating
Worked exactly as described and solved my issue immediately.

Thank you.
 
Comment #3  (Posted by an unknown user on 08/15/2005)
Rating
Worked exactly as described and solved my issue immediately.

Thank you.
 
Comment #4  (Posted by an unknown user on 08/15/2005)
Rating
Backwards Compatibility is always a problem, great solution.
 
Comment #5  (Posted by an unknown user on 08/26/2005)
Rating
just what i needed.....
 
Comment #6  (Posted by Simon Garcia on 08/29/2005)
Rating
what about the 5.0 object library?, is it possible to use this one for all versions of excel from the 5.0 and above?
 
Comment #7  (Posted by an unknown user on 09/01/2005)
Rating
Great! Helped us out!
 
Comment #8  (Posted by Simone on 10/27/2005)
Rating
Excellent! Solved our issue. Thanks
 
Comment #9  (Posted by an unknown user on 03/01/2006)
Rating
awesome !!
 
Comment #10  (Posted by an unknown user on 04/07/2006)
Rating
Its clear, accurate and best of all it works !
 
Comment #11  (Posted by an unknown user on 05/12/2006)
Rating
Just one word: Thanks.
 
Comment #12  (Posted by an unknown user on 05/13/2006)
Rating
Extremely helpful. The exact solution that I have been looking for. Thanks.
 
Comment #13  (Posted by an unknown user on 05/25/2006)
Rating
Thhanks so much!!!
 
Comment #14  (Posted by an unknown user on 07/03/2006)
Rating
thx!!!

i love you -_-
 
Comment #15  (Posted by an unknown user on 07/10/2006)
Rating
Brilliant. Thank you!
 
Comment #16  (Posted by an unknown user on 07/26/2006)
Rating
A good simple solution and a good explanation of why
 
Comment #17  (Posted by an unknown user on 08/08/2006)
Rating
its the best article ive found about this issue and i've been searching for a long time! thanks
 
Comment #18  (Posted by an unknown user on 08/29/2006)
Rating
Very good on completeness, but your solution involves working on the client's PC, which is not an option for me
 
Comment #19  (Posted by an unknown user on 09/07/2006)
Rating
No need to access any client PC, but you do need to get hold of the correct TLB/OLB file. In addition to being available on the target PC, this is also on the Office installation disks and I'd imagine would not be too difficult to find online.
 
Comment #20  (Posted by an unknown user on 09/07/2006)
Rating
Excellent
 
Comment #21  (Posted by an unknown user on 09/22/2006)
Rating
Good and fast solution to our problems caused by several users having only Excel 2000 installed..
 
Comment #22  (Posted by Giacomo on 09/24/2006)
Rating
Good job.

But I've got quite a problem...
Those lines of code:
Dim aRange As Word.Range
aRange = WordApp.ActiveDocument.Paragraphs(1).Range

Result in an error: Interface 'My.MsWord9.Interop.Paragraphs' cannot be indexed because it has no default property.

This does not happen if I import Office 2003's namespace instead of Office 2000's one.
 
Comment #23  (Posted by an unknown user on 09/28/2006)
Rating
Thank you very much.I hope to help in other case.Keep the good work
 
Comment #24  (Posted by an unknown user on 10/26/2006)
Rating
Great job
 
Comment #25  (Posted by an unknown user on 11/13/2006)
Rating
Excellent step-by-step
 
Comment #26  (Posted by an unknown user on 12/28/2006)
Rating
Simple and effective solution
 
Comment #27  (Posted by an unknown user on 01/05/2007)
Rating
Thank you so much! I would have gone mad if I wouldn't have found this great article ...
 
Comment #28  (Posted by an unknown user on 01/14/2007)
Rating
Excellent article, Thank you for sharing this!!
 
Comment #29  (Posted by an unknown user on 01/25/2007)
Rating
thanks
 
Comment #30  (Posted by an unknown user on 02/06/2007)
Rating
Thanks very much !
Just what I needed
 
Comment #31  (Posted by an unknown user on 02/10/2007)
Rating
Worked well for me. Thank you.
 
Comment #32  (Posted by an unknown user on 02/19/2007)
Rating
In my case we don't have office in ourserver.do u have any idia how to register/use my excel dll.
 
Comment #33  (Posted by [The Author] on 02/20/2007)
Rating