VB6 and VB.NET are similar languages that differ for a myriad of major and minor
details. Even keywords, methods, and controls that have the same name in both environments
may have a completely different behavior, as we exhaustively show in our
Resource section. Of course, the problem is even bigger when converting from VB6 to C#.
A tool that aims at preserving functional equivalence with the original VB6 code
should account for all or at least the majority of these differences. All the VB6
conversion products on the market, including VB Migration Partner, fill this gap
with a combination of these two elements:
- code transformation techniques, to generate VB.NET or C# code that behaves like the original
VB6 code
- support library that expose methods and controls that aren't found in the .NET Framework
or in the Microsoft.VisualBasic namespace
One of VB Migration Partner's strengths is its comprehensive support library. Its
dozens of classes and hundreds of methods ensure that the generated VB.NET or C# code
always performs like the original VB6 app, an important factor in dramatically reducing
the time and cost of the migration process. No other conversion tool comes with
such a complete library and in fact no other conversion tool can compare to VB Migration
Partner in its support for VB6 features.
Our competitors are aware of the many advantages of this approach, therefore some
of them are adopting a twofold strategy: on one hand they are expanding *their*
support library, on the other they publish whitepapers that suggest that
extensive libraries compromise the maintainability of the generated .NET
project, using sentences like this one:
“Migration tools that use on extensive libraries can generate code that is
hard to maintain“
Even if it isn’t mentioning any specific product, they are undoubtedly speaking
of us, because VB Migration Partner is the only VB6 migration software that relies
on an extensive support library.
By omitting any concrete reference, our competitors prevent readers from comparing the relative strengths
and weakness of each product.
The purpose of this document is to confute these and other “facts” that can be found in
marketing literature. In our quest for objectivity, we will back up our affirmation with
concrete code samples or other technical documentation.
All VB6 converters use a support library
Quite understandably, none of our competitors prefer not to emphasize that
all VB6 converters rely on a support library to an extent.
Even the Upgrade Wizard included in Visual Studio, arguably the least sophisticated
conversion tool around, relies on two support libraries - Microsoft.VisualBasic.Compatibility.dll
and Microsoft.VisualBasic.Compatibility.Data.dll - to support VB6 features that
have no direct correspondence in VB.NET, such as control arrays and the ADODC, DriveListBox,
DirListBox, and FileListBox controls. Even if they are signed by Microsoft, strictly speaking these
libraries aren’t part of the .NET Framework and have the only purpose of supporting converted VB6 apps.
Another example: the product from one of our competitors uses a support library
that consists of over 30,000 lines, for about 1.5M characters
gathered in helper classes that perform a variety of tasks that are essential for
the migrated .NET code to work correctly. If your VB6 code references any property
or method that isn’t directly supported by a .NET control (or that behaves
in a different manner), the generated code references one of these helper classes
and therefore depends on them.
Our competitor's support library is written in C#, but this is a port from an older
version of the library that was written in VB.NET, and for this reason the
C# library still depends on some classes in the Microsoft.VisualBasic and Microsoft.VisualBasic.Compatibility
DLLs. If you have selected C# to cut all dependencies from Visual
Basic and to make your project ready to be ported to other platforms, such hidden dependencies will survive
if you use our competitor’s conversion tool.
To recap: all migration tools are based on a support library, the
main difference being that VB Migration Partner’s library is more powerful
and provides support for virtually all VB6 features, including DDE, drag-and-drop,
graphic methods, etc. All our competitors, including those who have been in this
market for longer than us, fail to support these and many other language
features.
VB Migration Partner translates VB6 controls into references to .NET controls defined
in the support library. For example, the TextBox control maps to the VB6TextBox
class, the TreeView control maps to the VB6TreeView class, etc. Thanks to these
control classes, VB Migration Partner can preserve 100% functional equivalence
with the original VB6 program, with few or no manual fixes to the generated
code.
This important feature dramatically reduces the duration and cost of even the most
complex migration project. Just as important, developers working on the
migration don’t need to be familiar with the intricacies of .NET Framework,
because the support library takes care of all the differences between the VB6 and
the .NET worlds. This detail means that VB6 developers can be immediately productive
with .NET, with no need for in-depth .NET Framework training.
Only a support library guarantees full functional equivalence
For the most part, classes in VB Migration Partner’s library are thin wrappers
for native .NET controls that ensure that each property, method, and event behaves
exactly as in VB6. For example, let’s consider the following VB6 code:
txtEditor.SelStart = 0
A “traditional” VB6 converter – such as Upgrade Wizard (included
in Visual Studio) or similar products – converts the above code into:
txtEditor.SelectionStart = 0
No warning is emitted, thus a developer working at the migration is led into thinking
that the result is perfectly equivalent to the original code, which is not the case.
Assignments to the VB6 SelStart property have two side-effects that the .NET SelectionStart
property doesn’t have: they clear the selection and scroll the field contents
to ensure that the text cursor is in the visible area of the control.
The SelStart property of the VB6TextBox class in VB Migration Partner’s library
reproduces both side-effects, so that the developer doesn’t have to worry
about them:
Public Property SelStart() As Integer
Get
Return MyBase.SelectionStart
End Get
Set(ByVal value As Integer)
MyBase.SelectionStart = value
MyBase.ScrollToCaret()
MyBase.SelectionLength = 0
End Set
End Property
In addition to perfectly mimicking VB6 behavior, the SelStart property ensures that
the code works correctly even if the TextBox control is accessed via late-binding.
For example, only VB Migration Partner correctly deals with the following VB6 code:
Sub ResetCursor(ctrl As Object)
ctrl.SelStart = 0
End Sub
All properties and methods in VB Migration Partner are conceptually similar to
SelStart, and account for major and minor differences between VB6 and .NET. For
example, the code behind Left, Top, Width, and Height properties ensures that they
work correctly with all possible ScaleMode settings:
Public Shadows Property Left() As Single
Get
Return VB6Utils.FromPixelX(Me, MyBase.Left, False)
End Get
Set(ByVal Value As Single)
MyBase.Left = VB6Utils.ToPixelX(Me, Value, False)
End Set
End Property
(VB6Utils is a helper class defined elsewhere in the library). Thanks to its support
library, VB Migration Partner is the only VB6 conversion software that works correctly
with any VB6 coordinate system, including user-defined ones.
False myths about support libraries
Some developers may be concerned about support library and would prefer not to distribute
an additional DLL with their migrated apps. These concerns are understandable, yet we
believe that they are negligible if compared to the many advantages that
a well-written, comprehensive library gives you.
Such benefits stand out so clearly that even our competitors don’t deny that
an extensive library can speed up a migration project. To counter this evidence,
however, they may insist that a library has many shortcomings.
We can easily prove that all these “issues” are groundless, as we do
in our 17 reasons for using a support library
in migration scenarios whitepaper.
The point is, a comprehensive support library is the key factor in achieving 100%
functional equivalence and in keeping migration time and
cost as low as possible. Just read what one of our customers
has to say:
“An initial migration compared migration tools from six vendors. It showed
superior results for VB Migration Partner, which delivered fewer compilation and
runtime errors than all its competitors… It took 2.5 hours to get a compilable
and runnable VB.NET project with VB Migration Partner, and 13 hours with its closest
competitor.”
The higher productivity that a complete support library gives you is a sure fact,
and no competitor has yet published different results in
similar rigorous productivity tests. In the absence of objective measurements, however, they can
attempt to scare potential customers away from VB Migration Partner by making vague
statements about its supposed limitations.
The following list summarizes the kind of claims we found in our competitors’
documentation. It isn’t clear which product they had in mind when they wrote
these sentences, however we can easily prove that all of them are false when applied
to VB Migration Partner.
-
…other vendors charge a runtime fee for their support library.
FALSE! VB Migration Partner users can freely distribute its library with their apps.
-
…other vendors may charge a subscription for using the library in the future.
FALSE! VB Migration Partner’s EULA states that users will be allowed to download any future 1.xx version of the library at no additional cost.
-
…other vendors don’t make their library’s source code available to customers.
FALSE! VB Migration Partner users can license the library’s code.
-
… apps that rely on a support library might not work on future versions of the operating system.
FALSE! VB Migration Partner’s library is written in pure VB.NET and uses only documented features of the .NET Framework. As such, the library is guaranteed to work on all future Windows versions that support .NET Framework 3.5 binaries.
A closer examination reveals that this line of reasoning is illogical. Just for
the sake of discussion, let’s assume that Microsoft releases a Windows or
.NET Framework version breaks compatibility with existing .NET 4.0 programs. In
such a highly unlikely case, your own .NET applications will stop working correctly
and the support library will be the least of your problems.
A support library actually helps to preserve compatibility. Should a future version of Windows have minor problems in running .NET 4.0 apps, Code Architects will promptly fix the problem release a new support library that all users can download for free. You’ll still have to solve compatibility problems of your main app, but at least you don’t have to worry about the support library.
-
… if your migrated apps depend on a 3rd-party library, you might be in trouble if the vendor decides to stop supporting it in the future
FALSE! VB Migration Partner’s EULA states that – should Code Architects stop supporting the product – all customers will receive the library’s source code at no additional cost. In this respect, choosing Code Architects is as safe as, or safer than, choosing any 3rd-party control such as a grid or a charting component.
-
… a support library can slow down your code
FALSE! VB Migration Partner’s library has been authored by a team of expert developers, including two Microsoft Regional Directors who have written 7 top-selling Microsoft Press books on VB and .NET programming, have authored over one hundred articles on magazines such as Visual Studio Magazine and MSDN Magazine, routinely give lectures in US and Europe, and consult for Microsoft and its largest customers.
VB Migration Partner is carefully optimized and often runs much faster than
the code that most VB.NET or C# developers usually write, especially if they are
put under pressure by near deadlines. For example, our VB6Collection class
runs many times faster than the standard VB.NET Collection object, and our StringBuilder6
object allows you to automatically speed up string concatenations by a factor of
100x without having you modify the generated .NET code.
-
…other migration tools generate inefficient code that retains its VB6 flavor
FALSE! VB Migration Partner’s conversion engine uses very sophisticated refactoring techniques and generates code that takes full advantage of VB.NET and C# features, including Try/Catch blocks, short-circuiting (the AndAlso or && operators), the IDisposable interface, variable initializers, compound operators (e.g. x += 1 or x++), and much more.
Interestingly, VB Migration Partner can apply many refactoring techniques that no
other VB6 conversion tool currently supports, e.g. Gosub refactoring, Declare overloads,
using StringBuilder to speed up string concatenations, enforcement of ByVal keyword
if possible, plus a number of C#-only feature such as using dynamic variables for late-bound method calls,
using of “out” parameters when possible, optionally generation of overloads for ref/out parameter to simplify method calls.
Finally, keep in mind that VB Migration Partner’s developers wrote Practical Guidelines and Best Practices for VB and C# Developers (Microsoft Press), perhaps the definitive textbook on this topic, and VB Migration Partner’s generates code that abides by all those rules. For example, VB Migration Partner can optionally rename all members to comply with .NET naming rules. If you don’t like these rules, however, you can easily customize the rename engine by modifying an XML file. No other conversion software supports customizable rename rules.
-
…projects produced by other VB6 converters are difficult to evolve
FALSE! VB Migration Partner library doesn’t limit you in any way, because all its classes inherit from native .NET classes and you can therefore leverage the .NET Framework full potential.
-
…you can’t mix .NET native forms and controls with forms and controls defined in a support library
FALSE! After you’ve converted a VB6 project
to VB.NET using VB Migration Partner, you can extend the application by adding .NET
native forms, and you can drop .NET native controls onto a migrated form.
NOTE: Earlier versions of VB Migration Partner didn’t support
using controls from the support library inside a native .NET form. This limitation
has been lifted in version 1.34.
-
…you can’t use Visual Studio Test Wizard to generate unit tests for VB.NET projects generated by other conversion software.
FALSE! We describe this apparent problem - and its solution - in this KB article.
-
…the code produced by other VB6 converters that adopt a support library is hard to maintain
FALSE! A support library can make your migrated code more readable and easier to maintain, as demonstrated in the next section.
Readability and maintainability of generated code
Proving that an extensive support library can generate more readable and maintainable code is very easy. We just need to compare the code generated by VB Migration Partner with the code coming out from a “traditional” VB6 conversion tool that has a less extensive support library. Consider the following KeyPress handler written in VB6:
Private Sub Text1_KeyPress(KeyAscii As Integer)
If KeyAscii = 32 Then KeyAscii = 0 : Exit Sub
KeyAscii = Asc(Chr(KeyAscii))
End Sub
VB Migration Partner converts it as follows:
Private Sub Text1_KeyPress(ByRef KeyAscii As Short) Handles Text1.KeyPress
If KeyAscii = 32 Then KeyAscii = 0 : Exit Sub
KeyAscii = Asc(Chr(KeyAscii))
End Sub
private void Text1_KeyPress(ref short KeyAscii)
{
if (KeyAscii == 32 )
{
KeyAscii = 0;
return;
}
KeyAscii = VB6Helpers.Asc(VB6Helpers.Chr(KeyAscii));
}
The resulting .NET code is basically identical to the original code, and many
VB6 developers understand how to read and maintain this code. Obviously there is
no maintainability problem here.
Let’s see now the code produced by another conversion tool that doesn't rely on an extensive support library.
The name of the product we used to generate the following lines doesn’t really matter, because the same reasoning
applies to any conversion tool that attempts to fill the gap between VB6 and VB.NET exclusively by means of code transformation techniques:
Private Sub Text1_KeyPress(ByVal sender As Object, _
ByVal e As KeyPressEventArgs) Handles Text1.KeyPress
Dim KeyAscii As Integer = Asc(e.KeyChar)
If KeyAscii = 32 Then
KeyAscii = 0
If KeyAscii = 0 Then
e.Handled = True
End If
Exit Sub
End If
KeyAscii = Strings.Asc(Strings.Chr(KeyAscii).ToString()(0))
If KeyAscii = 0 Then
e.Handled = True
End If
e.KeyChar = Chr(KeyAscii)
End Sub
private void Text1_KeyPress(Object eventSender, KeyPressEventArgs eventArgs)
{
int KeyAscii = Strings.Asc(eventArgs.KeyChar);
if (KeyAscii == 32)
{
KeyAscii = 0;
if (KeyAscii == 0)
{
eventArgs.Handled = true;
}
return;
}
KeyAscii = Strings.Asc(Strings.Chr(KeyAscii).ToString()[0]);
if (KeyAscii == 0)
{
eventArgs.Handled = true;
}
eventArgs.KeyChar = Convert.ToChar(KeyAscii);
}
In the attempt to preserve functional equivalence of the original 3 statements inside the method, the tool generated as many as 13 (thirteen!) statements, a 4x increase in size.
You might believe that the KeyPress event is a special and unique case, so let’s see another code snippet, a simple VB6 method that defines two optional parameters:
Public Sub TestOptional(Optional x As Variant, Optional y As Variant)
If IsMissing(x) Then
If IsMissing(y) Then
x = 10
y = 20
End If
End If
MsgBox(x * y)
End Sub
This is how VB Migration Partner correctly translates it to .NET:
Public Sub TestOptional(ByRef Optional x As Object = MissingValue6, _
ByRef Optional y As Object = MissingValue6)
If IsMissing6(x) AndAlso IsMissing6(y) Then
x = 10
y = 20
End If
MsgBox6(x * y)
End Sub
public void TestOptional(ref object x, ref object y)
{
if ( VB6Helpers.IsMissing(x) && VB6Helpers.IsMissing(y) )
{
x = 10;
y = 20;
}
VB6Helpers.MsgBox(VB6Helpers.CStr(VB6Helpers.CDbl(x) * VB6Helpers.CDbl(y)));
}
Thanks to its support library, VB Migration Partner can generate code that is as readable and maintainable as the original VB6 method, even after conversion to C#. Well, the generated code is actually more readable, because our software merged the two nested IFs, however this improvement is achieved by means of its sophisticated conversion engine and isn't a consequence of using a library.
Let’s now look at the code that another tool generates for the same method:
Public Sub TestOptional(ByRef opt_x As Object, _
ByRef opt_y As Object)
Dim y As Object = Nothing
If opt_y Is Nothing Or Not opt_y.Equals(Type.Missing) Then _
y = TryCast(opt_y, Object)
Dim x As Object = Nothing
If opt_x Is Nothing Or Not opt_x.Equals(Type.Missing) Then _
x = TryCast(opt_x, Object)
Try
If Not (opt_x Is Nothing) AndAlso opt_x.Equals(Type.Missing) Then
If Not (opt_y Is Nothing) AndAlso opt_y.Equals(Type.Missing) Then
y = 20
End If
End If
MessageBox.Show(CStr(CDbl(x) * CDbl(y)), Application.ProductName)
Finally
opt_y = y
opt_x = x
End Try
End Sub
Public Sub TestOptional(ByRef opt_x As Object)
Dim tempRefParam As Object = Type.Missing
TestOptional(opt_x, tempRefParam)
End Sub
Public Sub TestOptional()
Dim tempRefParam2 As Object = Type.Missing
Dim tempRefParam3 As Object = Type.Missing
TestOptional(tempRefParam2, tempRefParam3)
End Sub
Notice that this code introduced two new methods and two new variables inside the main method, yet it doesn’t contain a single remark that explains why this extra code was generated.
Frankly, it isn’t clear why the optional parameters caused the creation of overload methods: apparently, our competitors fail to take advantage of optional parameters, which are now available both in VB.NET and C#.
As an aside, it should be noted that this extra code doesn’t guarantee functional equivalence with the original code. In fact, this approach generates a compilation error in any call that specifies only the second argument, as in:
TestOptional(, 1)
Now ask yourself: Which code would you like to maintain in the future? The concise and readable 7-line method produced by VB Migration Partner or the 3 methods and 28 statements produced by the other tool?
We might add many more examples of how a support library can make your code more concise, faster, easier to read, and easier to maintain in the future, but we don’t think we really need to: just pay a visit to our code sample section and see the code that VB Migration Partner generates for real-world VB6 apps.