Companies still using Visual Basic 6.0 for application development are faced with the challenge of moving away from a platform that, as of March, 2008, is no longer supported by Microsoft. One option that is available to those companies is to use automated migration technologies to help migrate these application to Microsoft's .NET Platform (Framework or Core). Migrating from VB6 to .NET allows companies to leverage the investment in the current application, while moving into a fully-supported and updated development environment.
There are several tools in the market that can help with the VB6 to .NET migration process. Most companies offer a black box approach with a runtime that requires a customer to pay an ongoing maintenance fee. Companies like Mobilize.Net offer the Visual Basic Upgrade Companion with a proven record of successful migration projects.
Even with the help of these VB6 to .NET migration tools, it is still necessary to plan the migration project in order to ensure its success. Mobilize.Net has been involved in automated software migrations for more than 20 years, and has been working alongside Microsoft for more than 20 years performing VB6 to .NET, web and Azure migrations.
In the following sections, we present eight recommendations that you should take into account when planning a Visual Basic 6.0 migration. These VB6 to .NET migration tips are based on Mobilize.Net's experience gained over decades of migrating large projects.
Mobilize.Net has developed a very mature project methodology that allows for a predictable, controlled migration process. This is achieved by dividing the application upgrade into two main phases:
First, getting an application in the new platform that has 90% Functional Equivalence to the original Visual Basic 6.0 application.
Second, performing incremental changes to leverage the new functionality available in .NET Framework and .NET Core.
With this methodology, the migration project is divided into several process groups:
User Acceptance Testing
A VB6 to .NET migration project requires a plan for some pre-migration work. In this first part of the project it is essential to perform certain activities to improve the quality of the code that will be generated during the automated migration. There are two types of pre-migration tasks that involve changes to the Visual Basic 6.0 code base: Code Cleanup and Code Preparation.
The Code Cleanup activity is an opportunity to perform maintenance tasks on the code that are usually put off during the regular development cycle. This includes removing code that is no longer used, removing redundant functions or methods, and some basic code and project restructuring.
For the Code Preparation activity, the developers should modify the application's code to improve the quality of the generated code. There are tools out there that can help you identify code in the application that will not convert cleanly. Some issues are easier to fix in Visual Basic 6.0 than in .NET, such as the Use of #if and Non-Zero based arrays, so you should take care of them regardless of the migration solution you are using.
Also, keep in mind the following rule of thumb: Using high quality code as input for the VBUC generates high quality .NET code as output.
VB6 to .NET migration projects, depending on the company's needs, can be structured in several ways. The two most common ways of establishing this order are to use either a Top-Down or Bottom-Up Visual Basic 6.0 to .NET migration.
Top-Down VB6 to .NET migrations starting with the Visual Basic 6.0 projects (*.vbp) you want and then working your way down to the migration issues, are recommended if:
You need to do partial deployments
The cost of additional testing and integration work is acceptable
You are working on a proof of concept
Bottoms-Up VB6 to .NET migrations implies that you will first fix the upgrade issues in the generated code, and then start moving upwards until you have fully functional projects. The downside of this is that you need to have at least all the migration and compilation issues solved before you can start testing the application. As for the work distribution between the developers that will be assigned to the project, it can also be done in several ways, each with its advantages and disadvantages:
Per Visual Basic 6.0 project (*.vbp): This is usually recommended if the original developer of the VB6 project will be working on the migration. Due to the developer's familiarity with the code, it will be easier to fix the different migration issues present in it.
Per Visual Basic 6.0 file: This is a more scalable approach than going per Visual Basic 6.0 project. Different files can be assigned to different developers and have each one fix all the compilation and upgrade issues present in these files. This can significantly speed up the first stages of the Manual Changes process by parallelizing the work.
Per Migration Issue: Having a developer specialize in solving one particular type of migration issue allows an even higher degree of concurrency in the project. Usually fixing the first occurrence of a particular issue requires some research and thus takes more time. Further occurrences are normally fixed in a fraction of the time it took the first time. By using this approach, the developer's efforts are optimized, and it also lends itself to having a large number of resources tackling different migration issues in parallel, further speeding up the process.
Even though this is a very generic statement, there are a couple of things that can be done in a Visual Basic 6.0 to .NET migration project in order to mitigate risks. First of all, it is recommended that you convert a small, representative module (using a Top-Down approach) before starting the whole VB6 to .NET migration. This is useful in diminishing threats associated with:
Performance: The performance of the migrated module can be tested and tuned while performing the migration of the remaining modules. Since VB6 and .NET are significantly different platforms, analyzing the performance upfront will help you identify potential issues and avoid surprises during the last stages of the project.
Estimate: It is necessary to closely track the effort required to migrate this first module. This will help with the validation of the estimate for the remainder of the application.
Also, something from Mobilize.Net's experience that has been key in performing successful upgrades is to migrate to functional equivalence first, and then start making changes to leverage the functionality of the new platform. This will be further expanded in Tip #5: Migrate to Functional Equivalence, then Re-Architect.
Migration projects are more QA-intensive than other types of software development efforts. You should allocate AT LEAST 35% of the total effort of the project to testing activities, though the ideal is to assign around 50% of the time for these tasks.
As for planning the testing, you should use a set of test cases as an objective validation for the migration process. The quality assurance team should make sure that these test cases execute correctly in the Visual Basic 6.0 application before running them on the migrated version. This should be done in parallel by the testing team with the first development activities of the project. This point is covered with more detail in Tip #6: Identify a Test Harness to Validate Functional Equivalence.
Making the decision to migrate an application means that there is significant value in the business rules and the logic embedded in it. The business may depend on these very specialized rules, so it is imperative to leverage the current investment by moving them forward. This is something very important to keep in mind during the migration project.
It is always tempting, especially for developers, to use the migration as an opportunity to rewrite parts of the applications that could work in a better way. On paper this sounds like the ideal time to do this, but in reality, it is something that should be avoided as much as possible. Mobilize.Net's experience shows that doing a straightforward port to reach functional equivalence is a measurable, easy way to control the process. Adding additional technical complexity to the project by rewriting a large part of the application adds uncertainty, and can cause the project to go out of control. There will always be an opportunity to do some improvements while performing the migration, but if a decision is made to work on them, make sure that all stakeholders understand the impact that these changes may have on the overall migration effort.
VB6 to .NET migration projects should have measurable, deterministic criteria to establish when the project is completed. This will set realistic expectations with stakeholders in the project, and in turn will translate into a more manageable and controllable project.
In Mobilize.Net's experience, using test cases is an ideal medium to validate when the migration is complete. Having a set of test cases will help the project to have very clear goals: to have the migrated application run the same test cases as the original system, and produce the exact same results.
If there is the possibility of using a third party to provide additional resources during the Visual Basic 6.0 to .NET migration effort, then special care should be taken to make sure that the test cases are as detailed as possible, without skipping any functionality of the application. Keep in mind that these additional resources are not experts in the application or its domain, so having detailed instructions will allow them to be productive very quickly, without having to undertake application-specific or domain-specific training.
Several VB6 to .NET migration solutions out there will release you from one legacy environment only to lock you in with a proprietary runtime. Over time, this approach leads to additional costs, namely:
Additional support costs from the Visual Basic 6.0 to .NET migration tool's vendor
Dead time while waiting for the vendor to release a new version of the runtime that fixes an issue that is affecting you
Possible backward compatibility issues with new releases of the runtime
Inability to take advantage of the new platform
Additional training costs and a higher learning curve when new developers start doing maintenance on the migrated software
Using a runtime might be an option when there is a significant difference with the target platform. This may speed up the process, and can significantly lower the cost of the VB6 to .NET migration, but if you decide to go with a runtime make sure that it:
Does not limit the future scalability of the migrated application
Provides full source code and documentation, so you do not have to rely on the vendor
Does not have royalties of any kind associated with it
This last bullet is especially important, not from a technical but from a business perspective. Being tied down with redistribution royalties may end up affecting potential business models you may want to explore in the future.
The team that is required to achieve a successful VB6 to .NET migration has a mix of skills and roles. The skills for positions such as quality assurance or project management are very similar to the ones required for any other software development effort.
At a high level, the profile of the developers that will be working in the code itself has three main skill sets, in decreasing order of importance:
Target platform experience: It is ideal that the developers have good knowledge and experience in the .NET Platform (either VB.NET or C#). This is the single most important factor for the Visual Basic 6.0 to .NET migration to be successful
Source platform experience: It is important to have resources on the team that are knowledgeable on Visual Basic 6.0. This, however, comes in second and is not required for all developers
Application knowledge: The ideal scenario is to have the developers of the VB6 application or somebody with in-depth knowledge of the source code involved in the project directly, or at least available for questions. Many questions will arise during the migration, and having an expert on the functionality is the best way to avoid wasting time figuring out what a block of code was trying to achieve.
Using automated migration tools as part of an overall upgrade project methodology is a good way to leverage the current investment in Visual Basic 6.0 applications and move them to the latest technology. Due to the VB6 to .NET migration tools that are available in the market today, like Mobilize.Net's Visual Basic Upgrade Companion, this has become a very viable proposition, especially given the fact that Visual Basic 6.0 is not supported by Microsoft.
A Migration Project presents some challenges that are not common in other types of software development efforts. With more than twenty years executing successful Visual Basic 6.0 to .NET conversion projects, Mobilize.Net has developed a proven software migration methodology, and the tips presented in this document are based on the experience accumulated over these years, having proved their value over and over again.
Having a tool like the VBUC, compiling VB6 code and a source environment set is not all that is needed to ensure success in a migration project from VB6 code to .NET. This entry will describe a list of things that SHOULD NOT be done during the project.
The green-code is the direct output generated by the VBUC tool after converting the VB6 code to .NET without any manual change.
The quality of this code and the way specific patterns or components are migrated rely on the configuration of the source environment, the completeness of the source code and the Upgrade Options (settings) indicated on the VBUC.
If the code to be migrated consists of different VB6 projects, then, configure a single Upgrade Solution that includes all projects required to be migrated. In this way you will make sure to select the same Upgrade Options for the entire code.
Avoid performing different migrations for different portions of the source code. If you still need to do that, make sure the same Upgrade Options are used in every migration.
Avoid making more changes to the application before getting the converted code to functional equivalence (FE).
After converting the source code, manual changes may be needed to get a functional equivalent application. Debugging both applications (the original and the migrated) side-by-side makes it easy to diagnose problems.
Once your converted application has reached functional equivalence it will be a better time to start thinking about major changes.
If there is still a need to introduce some changes or re-architecture then:
Take some time to analyze the changes that will be performed.
Make a plan to apply those changes on a systematical and consistent way.
Try to limit the scope of those changes.
And again, do not restructure the migrated code or add new features until the migrated application is debugged.
In most of migrated projects manual effort is needed to get the code to functional equivalence. Make sure to follow some rules before modifying the code:
The fewer manual changes, the quicker to get a functional code soon.
Before changing a migrated line, be analytical and economical. Make sure to answers questions like the following before you introduce those changes:
Is really this modification needed? (For example formatting, name convention changes, are things that can wait until the code is working, making those changes may introduce unnoticed different behaviors or make the code hard to track to its source)
Is this line of code the right place to introduce a modification?
Is this modification needed in several places? Is there any way to make this less massive? Perhaps think about general solutions.
The above questions require the person to introduce changes to have great abstraction capabilities.
When the above rules are not accomplished, different errors can be committed to the code.
Same problem solved in different ways (by different people)
Fix (supposedly) a compilation error by creating potential runtime exceptions VB6
x = <recordset>(EnumType.enumMember)
Note: EnumType.EnumMember is an enum
Green Code C#
x = <recordsethelper>[EnumType.EnumMember];
The <recordsethelper> indexer property can be either a column-index or a column-name, so casting is needed in the above case. Given ecfpFacilityList.ecfpflFacilityRef is an enum value, then the casting to int is needed.
x = <recordsethelper>[EnumType.EnumMember.ToString()];
x = <recordsethelper>[Convert.ToInt32(EnumType.EnumMember)];
x = <recordsethelper>[(int)EnumType.EnumMember];
Unneeded manual changes Consider the following two lines of code:
if (Convert.ToString(iteration_row["Name"]) != "" &&!Convert.IsDBNull(iteration_row["Name"]))
if (Convert.ToString(iteration_row["Name"]) != "" &&!DBNull.Value.Equals(iteration_row["Name"]))
The former is generated by the VBUC and the latter is a manual modification of that line: An irrelevant change that only increases the number of manual changes and does not provide any gain to the code.
Change the application logic.
For instance, the migrated code has the following if-condition:
and a manual change modifies the condition to:
Before starting a migration project, read and understand the Mobilize migration methodology is a key part of the project. Make sure to follow the suggested steps and avoid start making manual changes in your migrated code without understanding how and why the .NET code was generated.
Just to remember:
Development is horizontal, not vertical
In traditional development, each program is fixed sequentially
In a migration project, specific issues are resolved across the entire application: Rather than work file by file, work issue by issue.