Converting VB6 to VB.NET

AID: 3883
  • Status: Published

3250 points

  • ByOrcbighter
  • TypeTutorial
  • Posted on2010-09-30 at 05:13:29
Awards
  • Community Pick
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
                                    
1:

Select allOpen in new window


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

Select allOpen 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) {}
                                    
1:

Select allOpen 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
                                    
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:

Select allOpen 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
Asked On
2010-09-30 at 05:13:29ID3883
Tags

VB6

,

VB.NET

,

Framework

,

conversion

Topic

Microsoft Visual Basic.Net

Views
1330

Comments

Expert Comment

by: PaulHews on 2010-10-05 at 14:58:09ID: 20261

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
                                        
1:

Select allOpen 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
                                        
1:

Select allOpen in new window

becomes
Dim y(4) As Short
                                        
1:

Select allOpen 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) {}
                                        
1:

Select allOpen 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 Comment

by: Orcbighter on 2010-10-05 at 16:29:46ID: 20265

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.

Add your Comment

Please Sign up or Log in to comment on this article.

Join Experts Exchange Today

Gain Access to all our Tech Resources

Get personalized answers

Ask unlimited questions

Access Proven Solutions

Search 3.2 million solutions

Read In-Depth How-To Guides

1000+ articles, demos, & tips

Watch Step by Step Tutorials

Learn direct from top tech pros

And Much More!

Your complete tech resource

See Plans and Pricing

30-day free trial. Register in 60 seconds.

Loading Advertisement...

Top Visual Basic.NET Experts

  1. CodeCruiser

    1,541,075

    Genius

    8,400 points yesterday

    Profile
    Rank: Genius
  2. kaufmed

    303,871

    Wizard

    500 points yesterday

    Profile
    Rank: Genius
  3. Idle_Mind

    230,817

    Guru

    2,010 points yesterday

    Profile
    Rank: Savant
  4. nepaluz

    192,076

    Guru

    0 points yesterday

    Profile
    Rank: Sage
  5. PaulHews

    161,438

    Guru

    520 points yesterday

    Profile
    Rank: Genius
  6. BuggyCoder

    150,598

    Guru

    0 points yesterday

    Profile
    Rank: Sage
  7. JamesBurger

    123,179

    Master

    0 points yesterday

    Profile
    Rank: Sage
  8. emoreau

    112,211

    Master

    0 points yesterday

    Profile
    Rank: Genius
  9. Masteraco

    102,128

    Master

    0 points yesterday

    Profile
    Rank: Wizard
  10. TheLearnedOne

    80,982

    Master

    0 points yesterday

    Profile
    Rank: Savant
  11. Dhaest

    63,803

    Master

    2,000 points yesterday

    Profile
    Rank: Genius
  12. MlandaT

    53,803

    Master

    2,100 points yesterday

    Profile
    Rank: Genius
  13. wdosanjos

    53,796

    Master

    0 points yesterday

    Profile
    Rank: Genius
  14. mlmcc

    53,048

    Master

    0 points yesterday

    Profile
    Rank: Savant
  15. RolandDeschain

    41,679

    10 points yesterday

    Profile
    Rank: Sage
  16. srosebabu

    31,025

    2,000 points yesterday

    Profile
    Rank: Guru
  17. mas_oz2003

    28,400

    0 points yesterday

    Profile
    Rank: Genius
  18. sedgwick

    27,350

    0 points yesterday

    Profile
    Rank: Genius
  19. jacko72

    26,596

    0 points yesterday

    Profile
    Rank: Genius
  20. tommyBoy

    25,850

    0 points yesterday

    Profile
    Rank: Genius
  21. dlmille

    22,160

    0 points yesterday

    Profile
    Rank: Genius
  22. imnorie

    21,664

    1,600 points yesterday

    Profile
    Rank: Genius
  23. Cluskitt

    21,418

    0 points yesterday

    Profile
    Rank: Wizard
  24. robert_schutt

    20,440

    0 points yesterday

    Profile
    Rank: Guru
  25. navneethegde

    20,332

    0 points yesterday

    Profile
    Rank: Wizard

Hall Of Fame