15.6 Use a COM Component in a .NET Client


Problem

You need to use a COM component in a .NET client.

Solution

Use a primary interop assembly, if one is available. Otherwise, generate a runtime callable wrapper using the Type Library Importer (Tlbimp.exe), or the Add Reference feature in Visual Studio .NET.

Discussion

The .NET Framework includes extensive support for COM interoperability. To allow .NET clients to interact with a COM component, .NET uses a runtime callable wrapper (RCW)a special .NET proxy class that sits between your .NET code and the COM component. The RCW handles all the details, including marshalling data types, using the traditional COM interfaces, and handling COM events.

You have the following three options for using an RCW:

  • Obtain one from the author of the original COM component. In this case, the RCW is called a primary interop assembly (PIA).

  • Generate one using the Tlbimp.exe command-line utility or Visual Studio .NET.

  • Create your own using the types in the System.Runtime.InteropServices namespace. (This can be an extremely tedious and complicated process.)

If you want to use Visual Studio .NET to generate an RCW, you simply need to select Project Add Reference from the menu and then select the appropriate component from the COM tab. When you click OK, you will be prompted to continue and create the RCW. The interop assembly will then be generated and added to your project references. After that, you can use the Object Browser to inspect the namespaces and classes that are available.

If you aren't using Visual Studio .NET, you can create a wrapper assembly using the Tlbimp.exe command-line utility that is included with the .NET Framework. The only mandatory piece of information is the file name that contains the COM component. For example, the following statement creates an RCW with the default file name and namespace, assuming that the MyCOMComponent.dll file is in the current directory.

 tlbimp MyCOMComponent.dll 

Assuming that the MyCOMComponent has a type library named MyClasses, the generated RCW file will have the name MyClasses.dll and will expose its classes through a namespace named MyClasses. You can also configure these options with command-line parameters, as described in the MSDN reference. For example, you can use /out:[Filename] to specify a different assembly file name and /namespace:[Namespace] to set a different namespace for the generated classes. You can also specify a key file using / keyfile [keyfilename] so that the component will be signed and given a strong name, allowing it to be placed in the global assembly cache (GAC). Use the /primary parameter to create a PIA.

If possible, you should always use a PIA instead of generating your own RCW. Primary interop assemblies are more likely to work as expected, because they are created by the original component publisher. They might also include additional .NET refinements or enhancements. If a PIA is registered on your system for a COM component, Visual Studio .NET will automatically use that PIA when you add a reference to the COM component. For example, the .NET Framework includes an adodb.dll assembly that allows you to use the ADO classic COM objects. If you add a reference to the Microsoft ActiveX Data Objects component, this interop assembly will be used automatically; no new RCW will be generated. Similarly, Microsoft Office XP provides a PIA that improves .NET support for Office Automation. However, you must download this assembly from the MSDN Web site (at http://msdn.microsoft.com/downloads/list/office.asp ).

The following example shows how you can use COM interop to access the classic ADO objects from a .NET Framework application:

 using System; public class ADOClassic {     private static void Main() {         ADODB.Connection con = new ADODB.Connection();         string connectionString = "Provider=SQLOLEDB.1;" +           "Data Source=localhost;" +           "Initial Catalog=Northwind;Integrated Security=SSPI";         con.Open(connectionString, null, null, 0);         object recordsAffected;         ADODB.Recordset rs = con.Execute("SELECT * From Customers",           out recordsAffected, 0);         while (rs.EOF != true) {             Console.WriteLine(rs.Fields["CustomerID"].Value);             rs.MoveNext();         }         Console.ReadLine();     } } 



C# Programmer[ap]s Cookbook
C# Programmer[ap]s Cookbook
ISBN: 735619301
EAN: N/A
Year: 2006
Pages: 266

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net