When you plan to migrate to .NET, you must remember the following guidelines:
Select an appropriate migration strategy that allows you to reduce the risk of migration. In adverse situations, you may migrate from your existing application and the converted code may not run as desired.
Migrate to .NET in a way that allows you to retain existing COM code. You need to consider which
Obtain the advantages of the features that .NET provides. Migration is not of much use if you are not planning to avail of the new features that .NET provides.
Select the right code to migrate. It is important to select the right code or you may find it difficult to integrate the new code with the existing application. It is best to perform a code
Select an operating system that utilizes all the features of .NET. For example, Windows 98, Windows NT, and Windows ME do not provide all the .NET features. It is better to use Windows 2000, 2003, or XP to use all the features of .NET.
A migration process requires a lot of effort, several resources, and time. You need to perform a cost/benefit analysis to check the feasibility of migration. The best practice for migration is to initially migrate DLLs, modules, and classes. You should migrate ADO, ActiveX, or COM
OLE container code
Dynamic data exchange
To migrate an application to the .NET environment, you need to:
Understand the existing application before you start modifying it. You need to know the application's working and functionalities. You can acquire this information from the existing documentation of the application.
Decide the features that you need in the application. In addition to existing functionalities, you also need to decide the additional features that you should include based on the client's requirements.
Delete all the unnecessary or repetitive code in your application. This saves effort and costs when you migrate the application to .NET.
Use a code analyzer to delete unused code.
Declare variables explicitly before you start the migration process. Declaring
Perform the migration using the migration tool.
Solve the upgrade issues that might occur when the Upgrade wizard is unable to convert all
Upgrade syntax and controls. Syntax errors may occur when you migrate your application because .NET applications have different syntax when you compile. You need to use the latest syntax and controls to take advantage of the .NET technology.
Run the code after fixing all the errors. Check if the code runs according to requirements.
Migrating an entire application to .NET may not be
.NET supports the following features for interoperability between managed and unmanaged code:
Object binding: Supports both early and late binding of components.
Data assembling and translation: Manages data type conversion among managed and unmanaged data types. For example, an integer type in VB 6.0 is of 16 bits but an integer type in VB.NET is of 32 bits.
Managing objects: Manages objects during their lifetimes and ensures that you release the objects or send them for garbage collection.
Object identity: Implements the identity rules of COM objects so that the COM components can be identified when you refer to the COM components from .NET applications.
Exception handling: Translates the values of COM HResult to .NET exceptions.
You can perform interoperability in two ways:
By calling unmanaged code from managed code
By exposing managed code to unmanaged code
You can call unmanaged code from managed code in three ways. The technologies that allow this interaction are:
Platform Invoke that allows you to call any function in any unmanaged language if its signature is redeclared in managed code.
COM interop using Runtime Callable Wrappers (RCW) allows you to call COM components in any managed language, such as VB.NET or C#, which behaves similar to normal managed components.
C++ interop allows the direct use of flat APIs and COM APIs. This powerful feature is specific to C++.
You can call unmanaged code from managed code using the platform invoke feature. You can use the DLLImportAttribute class to identify the
You use COM interop to call methods of COM components in .NET applications because COM interop imports COM types to the .NET application. COM interop also assists forward compatibility to allow you to call managed .NET code from COM clients. COM interoperability is two ways. This means that .NET components can call COM components and vice-versa. When you talk about calling COM components from .NET
Figure 2-5: Run-Time Callable Wrappers
RCW changes COM metadata to .NET metadata. You use the type library importer (tlbimp) tool to perform this conversion. This tool is available in the .NET Framework Software Developer Kit. tlbimp tool reads metadata from a COM type library and creates a similar .NET interop assembly to call the COM component. The main functions of RCW are:
Managing interaction between the COM component and .NET
Creating and binding the COM object
Converting unmanaged COM interfaces to a managed form
Translating and assembling data among environments
Administering the wrapped COM object during its lifetime
In .NET client applications, you refer to COM components directly but actually, you use a RCW to fetch the objects in unmanaged code. To add a reference to a COM component to a VB.NET project:
Select Project ->Add Reference from the menu bar.
Select the COM tab in the Add Reference dialog box.
Select the component from the list and click Select. If the desired component is not present in the list, select the Browse button to search the component. This adds the selected component to the Selected Components list. Click OK.
When you build the project, the runtime creates Interop.ComponentName.dll in the project's /BIN folder. The runtime derives the name of the DLL from the component’s name.
You can use the tlbimp method or the direct reference method to call the COM component but it is important to know when to call which method. The reasons for calling a particular method are:
To use a COM component that is to be shared with multiple projects, it is best to use tlbimp. Tlbimp allows you to sign the resultant assembly and store it in the Global Cache assembly, which allows you to create a RCW.
To create a COM component that is not to be shared with other projects, it is best to use direct reference.
To control the advanced details of the assembly, such as version number or namespace, you use tlbimp. You do not acquire control over advanced details if you use direct reference.
To learn more about COM interoperability, see the COM Interop ReferencePoint.
You can call unmanaged flat APIs from managed code through C++ interop used only in C++. You use C++ interop when you call COM components, depending on the Interface Definition Language (IDL) file that contains a number of interface definitions. C++ interop allows direct access to COM APIs. To call complex unmanaged APIs or simple unmanaged APIs that change while developing managed code, it is better to use C++ interop, which allows you to directly access unmanaged APIs.Figure 2-6 shows the flow diagram for calling unmanaged APIs:
Figure 2-6: Flow Diagram for Calling Unmanaged APIs
Using COM interop, you can expose the public managed class to unmanaged code. Although managed and COM object models are different, exposing a managed API as a COM API is easy because COM interop
Figure 2-7: COM Callable Wrapper Functionality
The two requirements that you need to meet before creating a .NET class that COM clients use are:
Defining an interface in .NET code and making the class implement the interface. When you implement the functionality through interfaces, the implementation provides key advantages to COM clients. Interfaces
Declaring the classes as public that are noticeable to the COM clients. The tools through which you create CCW also define types based on public classes. The methods, properties, and events that COM clients use follow the same rules.
You can also sign .NET assemblies containing classes that COM clients can use with a cryptographic key pair. You sign the assembly with a strong name. .NET ensures that nobody tampers with the code in the assembly after you publish the assembly. All global assemblies, which are distributed among different clients, are required to follow this, though COM clients can call unsigned assemblies. You should ensure that you sign all the assemblies, including the private assemblies. This creates improved class IDs (CLSIDs) for managed classes and ensures that collisions do not occur between classes in different assemblies. The main functions of CCW are:
Managing interaction between COM and managed code
Creating and binding unmanaged code
Translating and assembling data among environments
Administering a .NET component during its lifetime
Translating the exceptions in .NET to COM HResult values