Click here to Skip to main content
15,889,808 members
Articles / Programming Languages / Visual Basic
Article

Upgrading VB6 to VB.NET

Rate me:
Please Sign up or sign in to vote.
4.60/5 (15 votes)
22 Dec 2008CPOL8 min read 280K   71   23
This article discusses various things to consider when upgrading a VB6 app to VB.NET.

Introduction

I'm currently working for a company where I have to upgrade over 50 VB6 programs to VB.NET 2008. So far I'm about half way through, and I've learned quite a few tricks that drastically improve the performance of VB.NET apps.

Because there are a lot of programmers that are going to be making this move, I thought I would share this information. I'm certain it will be very valuable to those who are faced with this task.

One of the first things to think about is whether you want to upgrade your VB6 program to a VB.NET 2008 Windows Forms application or a VB.NET 2008 Windows Presentation Foundation (WPF) application. If you are upgrading to VB.NET 2005, then you don't have the WPF option, but if you are upgrading to VB.NET 2008, then you do, and you may choose to use it.

Why would you want to upgrade a VB6 Windows Forms application to WPF? Because that is the future of Windows programming. Windows Forms have been using the same technology for more than 15 years, and are now at the very beginning of their sunset. Windows Forms applications use User32 (User before 32-bit) and GDI/GDI+ for gui rendering, but WPF applications use DirectX for gui rendering, which is much more powerful. Additionally, WPF uses Extensible Application Markup Language (XAML) to define the layout of the interface, and instantiate .NET objects.

By far, the easiest choice is to upgrade a VB6 Windows Forms application to a VB.NET 2008 Windows Forms application. Since Windows Forms are going to be around for quite a while, we'll take a look at that.

Here are some steps and tips for upgrading a VB6 Windows Forms application to a VB.NET 2008 Windows Forms Application:

     1.  Use VS 2008's Upgrade Wizard
     2.  Change the Target Framework
     3.  Delete the Upgrade Report
     4.  Correct all errors
     5.  Update Code
     6.  Add API's to increase DoEvents performance.

Performing the upgrade

1 Using the Visual Studio 2008 Upgrade Wizard

Open Visual Studio 2008
From the File menu, select Open | Project/Solution

- Navigate to the VB6 project that you want to upgrade, and select it.
- The Upgrade Wizard will start automatically.
- Click "Next" through each window of the Wizard until the Wizard begins the conversion.

** Upgrade Errors:
I have encountered some VB6 projects that did not complete the Upgrade Wizard, and would not upgrade. A couple of the errors I received were:

     "Upgrade failed: General error accessing file 'C'"

     "Unable to read the project file..."

If you have a problem upgrading a VB6 application to VB.NET, then you have 3 options:

1. Install Visual Studio 2008 Service Pack 1 (SP1) and try it again.

2. Use the command-line version of the Wizard.
This is the same Upgrade engine that is used by the VS IDE Upgrade Wizard, but for some reason it worked every time a VB6 program crashed during upgrade. Here's how:

     - Create a folder on the C:\ with a short name (like "Upgrade")
     - Copy and paste the VB6 Project files into this folder.
     - Open a Visual Studio Command Prompt
          (Windows XP: Start button > All Programs > Microsoft Visual Studio 2008 >
               Visual Studio Tools > Visual Studio 2008 Command Prompt)

     - Make sure you are in the VB directory (mine opened to VC)

     - Type "cd..", press Enter to move up 1 directory.
     - Type "cd VB", press Enter to change directory.

     - Go to the VBUpgrade directory

     - Type "cd VBUpgrade", press Enter.

     - Run the command-line version of the Upgrade Wizard:

     - Include "VBUpgrade.exe"
     - Include the input project path <filename>
     - Include the new folder the VB.NET project will be created in (Output directory)

     Structure:
     VBUpgrade.exe <filename> /Out <directory>

     Example:
     VBUpgrade.exe "C:\Upgrade\Project1.vbp" /Out "C:\Upgrade\VB Upgrade"

     - Press the Enter key after you type the above, and the Upgrade should begin.

3. If the command-line version of the Upgrade Wizard does not work for you, try
contacting John Hart at Microsoft (John.Hart@microsoft.com), he may be able to help.

2 Change the Target Framework

By default the Target Framework will be set to ".Net Framework 2.0". You can use this if you want to. I changed it to ".Net Framework 3.5". If you desire to do so, here's how:

- Click on the Project Menu | Properties
- Click the Compile tab
- Click the "Advanced Compile Options..." button at the bottom of the tab page
- Change the "Target framework" to ".Net Framework 3.5"
- Click "OK", then "Yes"

3 Delete the Upgrade Report

When you perform an Upgrade using the Upgrade Wizard, an Upgrade Report is automatically generated. If you would like to look at the report, then Open the Solution Explorer in Visual Studio (View menu | Solution Explorer), and double-click "_UpgradeReport.htm". I personally haven't used the report, so I delete it (right-click, Delete in Solution Explorer).

- If you decide to delete the report, you'll also need to open Windows Explorer and navigate to your project folder, then delete the "_UpgradeReport_Files" folder.

Example: delete "C:\Upgrade\VB Upgrade\_UpgradeReport_Files"

4 Error Correction

Once you upgrade your VB6 Windows Forms application to .NET, you will have lots of errors! To see a list of errors, open the "Error List" (View menu | Error List).

To actually go to an error, double-click an error from the Error List. Visual Studio will automatically take you to the line of code where the error occurs.

Above the line of code where the error occurs, you will notice an "Upgrade Warning". This warning describes the error, and provides a fairly helpful link that can help you get more information about the error, plus steps you can take to fix the error. To use the link, hold down the control button and left-click it with your mouse.

For example, if you had a CommonDialog control on your VB6 form, then you will receive an error informing you that the CommonDialog was not upgraded. The helpful link will provide links to new controls that replace the CommonDialog, such as "OpenFileDialog", "SaveFileDialog", etc.

Correct all of the errors in the project before continuing.

5 Update Code

VB.Net 2008 continues to support many VB6 methods. HOWEVER, they are actually SLOWER than their VB.NET counterparts, so it is very important to go through each line of code in your project, and replace each VB6 method with it's .NET counterpart.

VB6 code runs good in VB6, but VB6 code in VB.NET runs bad (very bad). VB.NET code in VB.NET runs good (VERY good), much faster than VB6 code runs in VB6 (if that makes sense).

So here are some examples of how to replace VB6 methods with VB.NET counterparts:

'TIP: VB.Net strings are zero based, in other words, the first position of a string is 0. In VB6, the first position was 1. This greatly affects how strings are parsed.

VB.NET
Dim myString As String = "Go ahead and search for this string"

- Instr - Instead of using the Instr() method to search a string, use the IndexOf() method.

VB.NET
Instr(myString, "search for this string")     'Old way
myString.IndexOf("search for this string")    'New way
- Mid - Instead of using the Mid() method to get a portion of a string, use the SubString() method.

VB.NET
Mid(myString, 14)         'Old way
myString.SubString(13)    'New way
- Trim - Instead of using the Trim(), LTrim() and RTrim(), use .Trim(), .TrimStart(), .TrimEnd()

VB.NET
Trim(myString), LTrim(myString), RTrim(myString)             'Old way
myString.Trim(), myString.TrimStart(), mystring.TrimEnd()    'New way
- Len - Instead of using the Len() method, use .Length() to get the length of a string.

VB.NET
Len(myString)        'Old way
myString.Length()    'New way
- Replace the "And" operator with "AndAlso".  (Do this in any non-bitwise comparison).

VB.NET
If 1 = 1 And 2 = 2 And 3 = 3 Then            'And Old way
If 1 = 1 AndAlso 2 = 2 AndAlso 3 = 3 Then    'And New way
- Replace the "Or" operator with "OrElse".  (Do this in any non-bitwise comparison.)

VB.NET
If 1 = 1 Or 2 = 2 Or 3 = 3 Then            'Or old way
If 1 = 1 OrElse 2 = 2 OrElse 3 = 3 Then    'Or new way
- Replace ALL VB6 File I/O classes with the new .NET File I/O Classes. They are faster than VB6's so make sure you use them!

VB.NET
Dim myFile As String = "C:\Temp\myfile.txt"
Dim instring As String = String.Empty

'** VB6 File I/O:
FileOpen(1, myFile, OpenMode.Input)
Do Until EOF(1)
    instring = LineInput(1) 'Read 1 line from a file
Loop
FileClose(1)

'** VB.Net File I/O:
Dim reader As New System.IO.StreamReader(myF<wbr />ile)
Do Until reader.EndOfStream = True
    instring = reader.ReadLine()   'Read 1 line from a file
Loop
reader.Close()
reader.Dispose()
6 DoEvents

As soon as I upgraded processor intensive VB6 applications to VB.NET, I noticed that the performance was terrible! While code upgrades are contributing factors, DoEvents is one of the biggest culprits! VB6 applications ran (in some cases) about 10 times slower when they were upgraded to VB.NET. With a few tweaks, VB.NET application performance can be greatly improved, so that they run about 40% - 50% FASTER than VB6...

1. Add a Module to your project, and name it something like "Do_Events"

2. Insert the following code into the module you added:

VB.NET
Module Do_Events

     Friend Declare Function SetThreadPriority Lib "kernel32" (ByVal hThread As Integer, _
          ByVal nPriority As Integer) As Integer

     Friend Declare Function SetPriorityClass Lib "kernel32" (ByVal hProcess As Integer, _
          ByVal dwPriorityClass As Integer) As Integer

     Friend Declare Function GetCurrentThread Lib "kernel32" () As Integer
     Friend Declare Function GetCurrentProcess Lib "kernel32" () As Integer

     Friend Const THREAD_PRIORITY_HIGHEST As Short = 2
     Friend Const HIGH_PRIORITY_CLASS As Integer = &H80

End Module
3. Add 2 lines of code before the intensive processing begins to set the thread priority:

VB.NET
SetThreadPriority(GetCurre<wbr />ntThread, THREAD_PRIORITY_HIGHEST)
SetPriorityClass(GetCurren<wbr />tProcess, HIGH_PRIORITY_CLASS)
4. Use DoEvents() sparingly! Calling DoEvents() has a big performance hit, so use it sparingly.

VB.NET
Dim iLoops As Integer = 0
Do Until iLoops = 10000

'Calling DoEvents() every 500 loops will greatly increase application performance
If iLoops Mod 500 = 0 Then DoEvents()

     iLoops += 1 'Add 1 to iLoops

Loop
5. Create a specific Sub routine for updating the controls on your Form, and call the Sub whenever you want to update the form.

In the example above, you can substitue DoEvents() with the name of your update method
Example:

VB.NET
Private Sub UpdateForm()

     'Update all controls here:
     progressBar1.Value += 1 'Update ProgressBar
     label1.Text = "Processing..." 'Update Labels, TextBoxes, etc...

     Application.DoEvents() 'Call DoEvents() so the form can refresh the changes to the controls

End Sub



If you follow the steps and tips included in this article, then your upgrade should go pretty smoothly, and your application should perform quite a bit faster in VB.NET than it did in VB6.

Good luck!

VBRocks

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer DataPrint, LLC
United States United States

Comments and Discussions

 
QuestionDo you know that there is a new Upgrade Wizard for VB6 to VB.NET? Pin
Orellabac10-Apr-20 10:31
Orellabac10-Apr-20 10:31 
QuestionThanks Man Pin
Hassan Mokdad5-Jan-16 2:17
Hassan Mokdad5-Jan-16 2:17 
QuestionVB6 programming continues in Windows 10 Pin
VB6 Programming26-Aug-15 21:38
VB6 Programming26-Aug-15 21:38 
QuestionVB6 programming looks set to continue Pin
VB6 Programming10-Aug-14 3:23
VB6 Programming10-Aug-14 3:23 
QuestionFortunately, in 2014 Visual Basic 6 has become popular again! Pin
ISpliter3-Mar-14 13:35
ISpliter3-Mar-14 13:35 
AnswerRe: Fortunately, in 2014 Visual Basic 6 has become popular again! Pin
Kevin Matney27-Apr-14 13:26
Kevin Matney27-Apr-14 13:26 
GeneralRe: Fortunately, in 2014 Visual Basic 6 has become popular again! Pin
sten20053-May-14 11:36
sten20053-May-14 11:36 
QuestionSome Miscellaneous syntax, Please correct it, BTW Excellent Post.................. Pin
Bsienn3-Jul-12 23:35
Bsienn3-Jul-12 23:35 
QuestionMy application(s) contain more than 100,000 LOC. Should I Migrate? Pin
Jawad Munir30-May-11 2:31
Jawad Munir30-May-11 2:31 
GeneralAn older post Pin
rookie12w14-Oct-10 3:11
rookie12w14-Oct-10 3:11 
QuestionQuestion for DoEvent Pin
BMWABCD11-Aug-10 8:05
BMWABCD11-Aug-10 8:05 
AnswerRe: Question for DoEvent Pin
CS Rocks13-Aug-10 5:29
CS Rocks13-Aug-10 5:29 
QuestionDatareport from vb6 Pin
david2006es22-Nov-09 21:06
david2006es22-Nov-09 21:06 
GeneralWhich Visual Studio are u using Pin
Member 226013428-Jun-09 11:41
Member 226013428-Jun-09 11:41 
Question"Upgrading"? Pin
Emil - Gabriel23-Dec-08 3:40
Emil - Gabriel23-Dec-08 3:40 
AnswerRe: "Upgrading"? Pin
Michael Loux30-Dec-08 2:29
Michael Loux30-Dec-08 2:29 
AnswerRe: "Upgrading"? Pin
tobywf30-Dec-08 6:15
tobywf30-Dec-08 6:15 
RantRe: "Upgrading"? Pin
Thomas Wells30-Dec-08 12:28
Thomas Wells30-Dec-08 12:28 
GeneralRe: "Upgrading"? Pin
CS Rocks8-May-09 4:53
CS Rocks8-May-09 4:53 
QuestionMuch faster? Pin
vbfengshui22-Dec-08 20:06
vbfengshui22-Dec-08 20:06 
AnswerRe: Much faster / VB6 Collections Pin
supercat923-Dec-08 8:19
supercat923-Dec-08 8:19 
Len() will always work exactly as any VB6er would expect it to, but .Length absolutely will not (it fails on uninitialized strings). So you have to be careful about blanket-converting many of the VB6 built in functions.

Correct. More generally, if one uses the VB6-style mid, len, etc. one generally doesn't have to worry about the distinction between a Nothing string and an empty one; when using the vb6-style functions, one can let strings default to nothing, but with the .net methods one must initialize them to empty. Given that strings are not an inheritable type (which should imply that none of the methods support overrides), I would think the system could always use the default string methods for any string variable, whether empty or not, but .net doesn't allow such a thing.

Also, note that vb.net string handling can be faster than VB6 if one uses objects like System.Text.Stringbuilder wisely, but can be much slower (over 10x) than VB6 if one uses string-handling code as-is.

BTW, is there any good replacement for the vb6-style "Collection" that does everything the Collection can do? It has some definite annoyances, but it also seems to have some unique features. For example, if the objects in a Collection have a "name" field which matches their name, one can easily code something like:
For Each Thing in myCollection
  If Thing.ShouldBeDeleted Then
    myCollection.Remove(Thing.Name)
  End If
Next
Nice, simple, and straightforward, and it works. None of the non-VB types offer such functionality; the only way I've found to perform such a function with them is to build a list of objects to be deleted and then delete those objects on a second pass.

I tried implementing my own class to mimic the functionality of the VB6 Collection object, but with the added benefits of generic support, a Contains function, etc. but the performance was nowhere near as good as the VB6 Collection object. Presently, I use Dictionary(of T) and handle purges by building a list of objects to delete, but that really seems a horrible way to do things.

I can understand a desire to have an enumerator throw an exception if the list is modified during enumeration in such a fashion that the enumerator would be unable to continue without trouble, or even if the list is modified in a way which could not consistently be performed without causing trouble (e.g. adding an item to a hash table could break things if the addition causes the table to expand, with existing objects getting arbitrarily resequenced; such a hash table should probably throw an exception if an object is added during enumeration, whether or not that particular addition triggered a rehash, unless the table would be able to ensure that previously-existing objects could still be read out correctly). Is there any good reason why data structures that would be capable of handling modifications during enumeration should not do so? The VB6 "Collection" is the only Microsoft iEnumerable data structure I know of that does.
GeneralRe: Much faster / VB6 Collections Pin
tobywf30-Dec-08 6:29
tobywf30-Dec-08 6:29 
GeneralRe: Much faster / VB6 Collections Pin
supercat930-Dec-08 18:48
supercat930-Dec-08 18:48 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.