We have fixed over 40 known bugs in this release, but above all we have added many new features, including:

  • the AddSourceFile pragma allows you to add a VB.NET source file to the migrated project
  • the AddLibraryPath pragma tells VB Migration Partner where to search for type libraries that have been already converted to .NET
  • the ShiftIndex pragma tells VB Migration Partner that the indexes of a given array must be offset by a specified value
  • the FixParamArray pragma tells VB Migration Partner to generate special code that ensures that arguments passed to a ParamArray parameter and modified by the callee are returned to the caller
  • the ParseReplace pragma allows you to replace a VB6 statement with another statement before the parsing process begins
  • the user interface shows migration progress (with a progress bar) and you can terminate the migration by pressing the Esc key
  • a special migration warning draws your attention to inefficiente string concatenations inside a loop
  • the new StringBuilder6 type allows you to speed up string concatenations by replacing just the variable declaration

Let me briefly illustrate more in detail the most important improvements.

When you convert a complex application that consistes in multiple DLLs - for example, we are now migrating a few real-world apps that consists of some hundreds DLLs! - you typically convert one DLL at a time, starting with the DLLs that don't depend on other DLLs and then continuing with the projects that depend on the DLLs that you have already migrated. For example, say that you have an ActiveX DLL project named MyDll and that exposes a VB6 class named MyDll.MoneyTransfer, which is converted to a VB.NET class named MyNetDll.MoneyTransfer. Of course, when you later convert projects that reference the MyDll project, you want that all references to the "old" MyDll type library are converted into references to the MyNetDll library. In earlier versions of VB Migration Partner you were asked to store the converted VB.NET DLL (MyNetDll, in our example) inside VB Migration Partner's installation directory, but this approach was a bit too weak and introduced a few problems if you were converting several VB6 projects in the same period.

The AddLibraryPath pragma offers a nice solution to this problem: you just need to store all the .NET DLLs into a directory, or a directory tree, and then mention that folder in an AddLibraryPath, as in this example:

     '## AddLibraryPath "c:\mynetdlls", True

where the second argument specifies whether the search is extended to child folders (if False or omitted, the search is limited to the specified directory). You can include multiple AddLibraryPath pragmas to specify multiple search folders. This pragma should be included in a *.pragmas file, and is ignored if included in the application's source files. Another important effect of the AddLibraryPath pragma is that all the DLLs in the search folders are never copied to the \SupportDLLs directory under the VB.NET project.

The ShiftIndex pragma is useful for arrays under the scope of an ArrayBounds pragma. For example, consider this VB6 code:

    '## arr.ArrayBounds Shift
    Dim arr(1 To 10) As Integer
    arr(1) = 5: arr(2) = 7: arr(3) = 11: arr(4) = 13

which is converted to VB.NET as follows:

     Dim arr(9) As Short
    arr(1) = 5: arr(2) = 7: arr(3) = 11: arr(4) = 13

The resulting code is not correct and in previous releases of VB Migration Partner you were forced to manually fix the indexes in the second line. The ShiftIndexes pragma solves this problem quite nicely:

    '## arr.ArrayBounds Shift
    '## arr.ShiftIndexes 1
    Dim arr(1 To 10) As Integer
    arr(1) = 5: arr(2) = 7: arr(3) = 11: arr(4) = 13

 here's the converted code:

     Dim arr(9) As Short
    arr(0) = 5: arr(1) = 7: arr(2) = 11: arr(3) = 13

The last important improvement is that now VB Migration Partner solves a subtle but serious problem in the VB6 to VB.NET conversion. Before I show the solution, let's have a look at the problem, which stems from the fact that VB6 accepts by-reference ParamArray parameters, where VB.NET accepts only by-value ParamArray parameters. The neat effect is that the following code can't be converted correctly

    Sub Increment(ParamArray args() As Variant)
        Dim i As Integer
        For i = 0 To UBound(args)
            args(i) = args(i) + 1
    End Sub

    Sub Main()
        Dim a As Integer, b As Integer
        a = 10: b = 20
        Increment a, b
        Debug.Print a, b    ' => 11, 21
    End Sub

When you migrate this code to VB.NET, VB Migration Partner issues a migration warnings that draws your attention to the fact that one or more elements of the args parameter are modified inside the method but the changes won't be propagated to the caller. If you realize that one or more callers actually relies on the by-reference nature of that parameter, you should add a FixParamArray pragma, as in this code:

    '## FixParamArray 5
    Sub Increment(ParamArray args() As Variant)
    '... remainder of code as in previous example

The effect of that pragma is that VB Migration Partner generates the code that replaces the args ParamArray parameter with exactly 5 Optional ByRef parameters, so that changes to these parameters are propagated back to callers exactly as it happens in VB6. (More details in an upcoming post.)

That's all for now. Let's play a little with this release and get ready for version 1.0 later this month.