Community Pick: Many members of our community have endorsed this article.

Converting VB6 to VB.NET

Published:
1.0 - Introduction
Converting Visual Basic 6.0 (VB6) to Visual Basic 2008+ (VB.NET).

If ever there was a subject full of murkiness and bad decisions, it is this one!   The first problem seems to be that people considering this task of converting VB6 to VB.NET seem to think that because these two languages have the same name (at least in part) that they are the same language; that is, VB.NET is just VB6 'NETicised'.  Maybe all you have to do is open the VB6 project in a .NET version of Visual Studio and the conversion wizard will do it all for you...

That thinking is wrong!  The two are very different languages, with completely different behaviours.

2.0 - Notice
In this article I have assumed that the version of the IDE being used is Visual Studio 2008 at a minimum, with V3.0 of the .NET Framework.


3.0 - Some Important Differences
There are a number of significant differences between the way VB6 and VB.NET work. These differences could create unexpected behaviour in the code if not dealt with. Some of these are outlined in this section.


3.1 - Fixed Length Strings
Unlike VB6, VB.NET does NOT support fixed length strings. You will probably find a VB6 code declaration of:
strTranDate As String * 8  ‘ a fixed length string 8 bytes long

Open in new window

... being converted to ...
<VBFixedString(8),System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray,SizeConst:=8)> Public strTranDate() As Char

Open in new window

You  need to be aware that even though the converted code states it is a fixed length string, it is not.  If you place 10 bytes into this 8-byte string, VB.NET will resize the string to 10 bytes. That's not a problem unless you are creating position-dependent data for other software to read -- and that software expects an 8-byte field there!  

If you are writing position-dependent code, then you must explicitly add logic to check the string and truncate it if necessary (or treat as an error) to avoid inappropriate behaviour.


3.2 - Buffer Allocation
Array indexing in VB6 starts from 1 rather than from 0 as it does in the .NET framework.

In order to preserve backward compatibility, VB.NET implements buffer allocation in a broken way -- it will actually allocate an extra element (something that does not happen in C#).  Thus, when you declare a Char buffer of a set size, VB.NET will create a buffer one byte larger.

For instance, in VB6 the following code
    Dim MyBuffer as new Char(6) {}

Open in new window

...will create a 6-byte array with a starting prefix of one.
However, in VB.NET, it will create a 7-byte array, with a starting prefix of zero.


3.3 - Error Numbers
Error numbers may vary.   In some cases, error codes returned by VB.NET may be different than those returned by VB6 Visual Basic 6.0.  For error handling code that relied on the values returned by Err.Number, this might cause different (and unwanted) behaviour in your application. For example:
‘ Visual Basic 6.0
                      On Local Error GoTo ErrorHandle
                      Dim x() As Boolean
                      Dim y As Variant
                      	
                      y = x(10)
                      	
                      ErrorHandle:
                           If Err.Number = 9 Then
                                ' Do something
                           Else
                                 ' Do something else
                           End If

Open in new window


3.4 - Late-bound Calls to COM Objects May Cause Type Mismatch Errors
In VB6, when a late-bound COM object is passed as a parameter to a late-bound call, the object is coerced to a Variant of type Nothing.

When upgraded to VB.NET, COM objects declared as type Object are treated the same as Variants (which are always converted to type Object during upgrade).  These objects are marshalled to the variant type Empty.  This causes a type mismatch error in VB.NET.

To avoid this problem, make sure that all objects are early bound.


3.5 - Closing a Form Calls Dispose
In VB6, you can unload a form and later reload it by calling the Show method.
In VB.NET, the Close method for a form calls the Dispose method so that it is automatically garbage-collected.  This can cause subtle behavioural differences that may be hard to detect.

In Visual Basic 2008, if you call the Show method for a form that has been unloaded, you will get a new instance of the form; any property settings from the base class will be lost.
For forms that are shown modally, Dispose is not called automatically. In some cases, you may want to call Dispose in order to clean up resources
3
6,405 Views

Comments (2)

Commented:
Hi Orcbighter,

There are a number of errors in 3.2 - Buffer Allocation that you could address.  For one thing, you can declare arrays in VB6 that have zero lower bound... In fact this is the default.  This statement:
Dim x(4) As Integer

Open in new window

creates an array with 5 elements, from zero to four.  The .NET conversion wizard will convert this without complaint.

When you explicitly declare the lower bound to be 1, however, the wizard will change the number of elements.
Dim y(1 To 4) As Integer

Open in new window

becomes
Dim y(4) As Short

Open in new window

and it will add a conversion warning as well so that you are aware of the behaviour.  

I'm not sure what you meant with this:
Dim MyBuffer as new Char(6) {}

Open in new window

This doesn't compile in either VB6 or VB.NET.

In general, I don't think I would recommend people use the conversion wizard at all, except for very limited cases.  I guess it could be seen as the start of a rewrite, but most of the COM components and Win API calls used in VBA/VB6 have native counterparts in .NET that are not addressed by the wizard at all.

Author

Commented:
Hi PaulHews
Yes I agree with you. For every problem there is a solution.
However, the point of my article was to address those who blindly convert from VB6 to VB.NET, either through lasiness or lack of skill (usually the latter).

My aim was to draw these areas to the reader's attension and alert them to possible problems. From here, the reader can go back and visit there code and, if such buffer allocation code exists, they can modify it, either along the lines you suggested, or along their own lines of thought.

The points I have raised in my article are ALL from bitter experience. I have had a number of contracts where I was commissioned to come in a fix bad conversions.

Have a question about something in this article? You can receive help directly from the article author. Sign up for a free trial to get started.