ToDos

The following are some of the most common ToDos generated by the VB6 AI Migrator.

1035 - #If #EndIf block was not upgraded because the expression %1 did not evaluate to True or was not evaluated

Description

The #If #EndIf directives are evaluated by the VB6 AI Migrator preprocessing engine during the preliminary stage of the upgrade process. The current compiler-variable values are taken into consideration to figure out which blocks of code are active and which are inactive. The active blocks are upgraded to .NET, while the inactive ones are copied unchanged to the upgraded code and preceded by this EWI.

Recommendations

Often, conditional compilation directives might be missing and not all code paths will be expressed. Conditional compilation constants can be defined in three different ways in VB6:

How To Set

Scope

Project Properties dialog box

Public to all modules in the project

Command line

Public to all modules in the project

#Const statement in code

Available only in the module in which they are declared

Knowing the scope of these constants can help when modifying the code to correct this EWI. If the inactive code is small and simple, it can safely be rewritten manually. However, if the conditionally compiled code is extensive, an extra migration might be required. Different values of the conditional constants can be used for all valid permutations. This will convert previously inactive blocks of code. The results can then be manually merged to get a fully converted code block.

In some cases, it might be possible to comment out the conditionally compiled code segments completely. This will only work if there are no conflicts and the original code can be upgraded without the conditional compilation directives.

triangle-exclamation

Some inactive blocks of code might no longer be in use. If this is the case, then those code segments can be removed. Special care should be taken when reviewing conditionally compiled code. Locally declared variables do not affect and are not used for the evaluation of conditional compilation directives.

VB6 Original Code

#Const ShowMessage = -1 'True

Public Sub ConditionalCompilation()
   'ShowMessage is True'
   #If ShowMessage Then
      MsgBox "It will show this message!"
   #Else
      MsgBox "This text will not show!"
   #End If
End Sub

Public Sub ImproperConditionalCompilation()
   Dim show As Boolean
   Set show = True
   ' show is a local variable, and is not'
   ' used for conditional compilation'
   #If show Then
      MsgBox "This text will not show!"
   #Else
      'This message box is shown.'
      MsgBox "It will show this message!"
   #End If
End Sub

C# Upgraded Code

VB.NET Upgraded Code

1050 - Structure %1 may require marshalling attributes to be passed as an argument in this Declare statement

Description

In Visual Basic 6, user-defined types could be passed as an argument in a Declare statement for a Windows API. Actually, we have a feature called PInvoke (Platform Invocation Service) that allows calls to native code and interact with .NET unmanaged code.

In Visual Basic .NET, a structure (user-defined type) passed as an argument in a Declare statement may require additional marshalling attributes in order to be passed correctly to the external function or subroutine. In particular, arrays and fixed-length strings may not function as expected without these attributes.

As mentioned before, we use the PInvoke feature; in this case, the declared statement will be commented and a new struct will be created using this feature in another file.

To see more information: PInvoke feature

Recommendations

Add an Imports statement to reference the System.Runtime.InteropServices namespace and then modify the structure and the string declaration to include marshalling attributes.

VB6 Original Code

C# Upgraded Code

Module1.cs

UnsafeMethods\Structures.cs

C# Expected Code

Module1.cs

UnsafeMethods\Structures.cs

VB.NET Upgraded Code

Module1.vb

UnsafeMethods\Structures.vb

VB.NET Expected Code

Module1.vb

UnsafeMethods\Structures.vb

1059 - Code was upgraded to use %1 which may not have the same behavior

Description

This EWI appears when a Visual Basic method call is changed to a .NET counterpart that may not have the same behavior as the original.

Recommendations

  • In most cases, the .NET equivalents provide equivalent functionality, but there can be some cases for which its functionality differs. Most commonly VB6 performed a lot of validations and auto coercions. Unfortunately, there is such a wide variety of cases that might cause this EWI that it would be prohibitive to list them all with possible resolutions. It is, however, important to note that oftentimes these differences can depend on the parameters passed to the methods. Thus choosing a different signature of the same method might provide the desired functionality.

  • Therefore, it is recommended that the migration consultant research the target and source methods to achieve the desired functionality.

VB6 Original Code

C# Upgraded Code

VB.NET Upgraded Code

1065 - Error handling statement (%1) could not be converted

Description

This EWI is generated when an error-handling statement is too complex or if it is a pattern that is not supported by the VB6 AI Migrator.

Recommendations

  • Most occurrences of this EWI will require manual changes to the source code to fix the issue. However, most cases of an error label that is globally called within a function can be replaced by a single try-catch statement with the addition of return statements.

  • The error handling is associated with the Error Handling upgrade option in the VB6 AI Migrator Tool. You can change it to generate different code.

See also: Error Handling Upgrade Option

VB6 Original Code

C# Upgraded Code

VB.NET Upgraded Code

1067 - Member %2 is not defined in type %3

Description

This EWI appears when an object cannot be typed correctly or a particular method could not be found in the class. This usually occurs in late binding scenarios. In some cases, the VB6 AI Migrator will still be unable to map the reference correctly due to late binding scenarios where multiple types are sent as parameters.

See also: Late Binding Resolution

VB6 Original Code

C# Upgraded Code

VB.NET Upgraded Code

1069 - Error handling statement (%1) was converted to a pattern that might have a different behavior

Description

This usually occurs when a Resume Next Error Handling Pattern appears. It is a warning because functional equivalence could not be accomplished in this scenario.

Recommendations

  • The Resume Next error handling pattern resumes execution of the next statement after an error. In the case of structured error handling, the resulting behavior is more similar to an On Error GoTo statement, where the catch statement serves as the GoTo label. For this reason, the replacement done by the VB6 AI Migrator might not be the exact functional equivalent of the original code. In cases where the code is related, meaning if one call fails subsequent calls are likely to fail, then leaving a single try-catch statement could work. Since an error at any point of the process would merely be replicated in the subsequent.

  • In other cases, the error pattern of Resume Next is necessary when the code statements are fairly independent (a failure in one statement does not affect the error condition of a subsequent call). In order to ensure functional equivalence, it's necessary to add a try-catch (with an empty clause) to each line that can throw an exception. In these cases the main try-catch (generated by the VB6 AI Migrator) is less effective and should be removed.

  • The error handling is associated with the Error Handling upgrade option in the VB6 AI Migrator Tool. You can change it to generate a different code.

See also: Error Handling Upgrade Option

VB6 Original Code

C# Upgraded Code

VB.NET Upgraded Code

2018 - Remove the next line of code to stop form from automatically showing

Description

VB6 AI Migrator converts MDI forms to regular .NET forms but also applies specific conversion rules in order to emulate exactly the same behavior as in VB6. If that behavior is no longer wanted, then just remove the tagged comment and the line of code that calls the Show method of the form.

circle-info

This EWI will appear in the designer file.

Recommendations

  • If the MDI form in the VB6 project had its AutoShowChildren property set to True, to simulate the VB6 behavior, VB6 AI Migrator needs to automatically show the form whenever it is loaded.

VB6 Original Code

MDIForm1.frm

C# Upgraded Code

Form1Child.Designer.cs

VB.NET Upgraded Code

Form1Child.Designer.vb

2045 - Only TrueType and OpenType fonts are supported in Windows Forms

VB6 Original Code

C# Upgraded Code

VB.NET Upgraded COde

7010 - The connection string must be verified to fullfill the .NET data provider connection string requirements

Description

In most cases, the conversion of ADO, RDO, or DAO to ADO.NET will require a manual modification of the connection string.

Recommendations

  • ADO.NET uses different parameters to connect to the database. The easiest way to know the appropriate connection string in the .NET environment is to use the "Data Connections" tool, which can be found in the "Server Explorer" tab of the .NET IDE, to create a new connection to the database and get the complete connection string from there.

  • This EWI is associated with the ADODB Upgraded Option. You can change it to generate a different code.

See also: ADODB to ADO.NET

VB6 Original Code

C# Upgraded Code

VB.NET Upgraded Code

7016 - This property was auto-generated because it is used in WriteProperties but does not exist.

Description

Visual Basic 6 allows the user to add design-time properties to user controls by adding them in the WriteProperties event of the UserControl class, even though the properties are not defined in the UserControl. The following example defines such a UserControl.

VB6 Original Code

When this type of control is added to a form, the form's designer code will look like this:

Since the UserControl does not contain an IsActive property, the VB6 AI Migrator will auto-generate one to provide a single place to fix this issue.

C# generated code

Recommendations

This code will provide the missing property at design time, but will need to be manually changed to provide the same functionality as the VB6 program. By using the contents of ReadProperties and WriteProperties, it should be possible to manually change the getter and setter of the new property to achieve functional equivalence.

How to prevent the application from exiting immediately after starting

Basic Scenario

The basic scenario is the invocation of the main form of the application from the Main sub. This is described here.

VB6 Application

We have a simple application with a main module which contains the main sub, and a main form that is displayed in the main sub.

Startup Project

This is the code for the main module:

As mentioned before, this application will start the execution on the main sub, display the main form and exit the main sub, keeping the main form open. The application will exit as soon as the main form is closed.

Upgraded Application

The VB6 AI Migrator tool generates lines that are equivalent to the lines in the original application, it also generates an EWI informing the user that the "Application will terminate when Sub Main() finishes".

If we execute this code, the main form window will be displayed and the main sub will not be executed until the main form is closed. To fix this behavior, you need to change the order in the VB6 application, placing form.show at the end of the main sub.

VB6 Code

CS Upgraded Code

Last updated

Was this helpful?