I just came back from executing a Ready assessment for a company in Minnesota, where I analyzed 740,000 lines of code in a VB6 application, of which 660,000 belonged to a single Visual Basic project (.vbp). This is actually the largest single .vbp I have seen so far, beating the previous record of about 500,000 lines of code held by an European company. We have migrated plenty of applications that contain 1+ million lines of code, but they are usually distributed across many .vbp’s.

Though unusual, single vbp’s of this size are perfectly manageable from a migration standpoint, and here are some things that can be done to deal with them:

Ensure that the migration computer has at the very minimum, 3GB of RAM.

Look for customization opportunities before you start migrating the code. Customizing the VBUC for this specific VBP can reduce manual effort drastically.

When making manual changes, start with a small team until you get the project to compile, especially if migrating to VB.NET as the compiler has a maximum of build errors that it can show at any given time.

Once the application compiles, increase the team size and go for Visual Equivalence by distributing the different forms and user controls across your developers.

Today, as part of the Visual Studio 2010 launch, Microsoft published a video of my coworker, Esteban Brenes, doing a brief demo of the latest beta of the Visual Basic Upgrade Companion 4.0. In this video, version 4.0 of the VBUC is used to generate code that works correctly with Visual Studio 2010. This is part of the VSIP Partners CAN DO! series of videos, which can be seen in this link.

We are very happy to announce the Visual Basic Upgrade Companion 4.0 Beta. You can now download a trial from the Trial Request page. While we complete beta testing, we’ll have both version 3.0 (current release version) and the 4.0 Beta available for download. If you have the chance, we would really appreciate it if you could download the beta, and send us any feedback either through ArtinSoft’s regular support email (support@artinsoft.com) or through my blog Contact Form.

This new version contains a large number of improvements over version 3.0, including:

Increased productivity for migration projects, with features such as improved conversion of ByRef/ByVal parameters (specially when working with Windows APIs), TypeName/TypeOf support, improved default property conversion, generate code to explicitly release COM objects when required, and hundreds of smaller enhancements and bug fixes that greatly improve the conversion of VB6.0 code.

Improved the user experience by adding localization/internationalization for German and Japanese and completely redesigned the installation and license process. Installing a license is now a straightforward process (no more copying files!!), and it is now possible to install and execute the VBUC on both 32- and 64-bit versions of Windows Vista and Windows 7, as well as 32-bit Windows XP. The installation requirements were also greatly simplified, so you don’t need Visual Studio installed to install the VBUC (though it is still recommended). You can now also select the target version of Visual Studio to generate the appropriate Solution file (*.sln). The VBUC can generate Visual Studio Solutions for version 2005, 2008 and 2010.

Enhanced Grid migration, by mapping the Microsoft Flexgrid and APEX/ComponentOne TrueDBGrid to a grid that extends the native .NET DataGridView. It will no longer be required to purchase a third-party grid solution when moving from these grid to .NET if you wish to move to 100% native .NET code without using COM Interop.

Improved assessment capabilities, by improving the accuracy of the VBUC Assessment Mode and making additional changes so members without specific mappings are tagged with an EWIs – in the past only members that were explicitly tagged as “Not Mapped” had an EWI.

One very common requirement for migration projects is to adapt certain error handling patterns used in a customer’s Visual Basic 6.0 code to the structured error handling provided by .NET, cleaning up the code, improving its maintainability, and, whenever possible, complying with .NET best practices.

The VBUC already converts several commonly used error handling patterns, such as the ones described in this old post. There are, however, situations where the VBUC is not able to recognize a pattern. these usually involve Goto statements, On Error Resume Next, Resume Next or some other construct usually associated with “spaghetti code”. When one of these patterns is encountered, the VBUC does a very basic transformation and generates an EWI so it can be cleaned up through manual intervention later on, such as in the following example:

Most of the time it is possible to generate a solution that will correctly convert the error handling pattern, maintaining functional equivalence and meeting any additional coding guidelines from our customers. For the previous example, The VBUC can be customized so the generated code looks as follows:

This example makes some assumptions on the nature of the code and on the intention of the original VB6.0 developer, in particular:

Errors raised by <STATEMENTS 1> should be handled by <STATEMENTS 5>

Errors raised by <STATEMENTS 2> should be handled by <STATEMENTS 4>

<STATEMENTS 3> is cleanup code that should always be executed

The Exception needs to be thrown again without loosing any information

This is just an example, but the intention is to show what type of customizations can be done. The VBUC transformation engine is very powerful, and, as long as a pattern can be identified, can help you automate the solution to most VB6.0 problems.

Next Monday, August 17, I will be presenting a Webinar along with Microsoft for the Latin America region on how you can use several options to get your VB6.0 applications to run on Windows 7 AND get the Windows 7 logo. The webinar will be in Spanish, and covers the business reasons for the migration, the benefits of using in the .NET Framework, alternatives, and information (+demo) of the VBUC.

One question commonly asked by our customers is how both duplicate (same file copied in several projects) and shared files (one copy of the file referenced from multiple projects) are counted. If you create a migration solution using the VBUC, it counts the lines of code in a project (Lines column):

This number displayed in the VBUC includes all the lines of code from files referenced in the *.vbp project. This means that it counts shared files and duplicate files each time they appear. This may increase the final amount of lines of code of the total solution. If you do need to find out the number of lines of code counting these files once, we offer you two options:

The first one is to download and run our new Visual Basic 6.0 and ASP Assessment Tool. This brand-new assessment tool considers both Shared and Duplicate files and counts both accordingly in separate columns. As shown in the screenshot below, the Assessment Tool identifies “Potential Duplicates”, which are files that have the same name and the same amount of effective (code + design) lines of code. In practice, they are normally the same file copied over several projects. You should note, however, that there may be small changes that keep the same amount of code (assignments, calls to different functions, etc), so there is no guarantee they are exactly the same. FYI, this was done to speed up the analysis process. In the future we will add additional heuristics to eliminate the possibility of false positives.

The second option is to use the same VBUC, but run a detailed analysis using the “Assessment” option. This can be executed from the main menu by selecting Upgrade->Assessment:

This is a more exhaustive assessment than the one executed by the VB6.0/ASP Assessment Tool, and takes much longer to execute. This assessment will not create an HTML report (like the VB6.0/ASP Assessment Tool), but you can open the detailed line count report produced (Assessment_LOC_Report.xml) using MS Excel 2003 or higher.

When either testing the trial version of the VBUC or actually running the migration tool on your project, there are a few things that you should check to ensure the best possible conversion. These are:

Project root: Make sure all projects are stored under a one “root” common directory. The VBUC migrates all Visual Basic 6.0 projects (*.vbp) found in a directory structure, including subdirectories, from one common root. You can read more information about setting up the folder structure in the VBUC Quick Start Guide.

Third-party Components: The VBUC requires that all third party components are correctly registered. Also, very important, ensure you correctly install all licenses for the components. Not including these licenses will not allow the VBUC to load and identify the PMEs (Properties, Methods and Events) and correctly either apply the necessary maps or generate the corresponding COM Interop wrappers.

Compile all projects: Make sure all projects compile correctly and that all the references between the output (EXE/DLL/OCX) of a project and the referenced component in another project match up. This will allow the VBUC pick up the references automatically, reducing the amount of migration warnings and thus minimize the work required to set up the migration solution. The VBUC Quick Start Guide contains additional details on the importance of this step.

This is a very simple configuration option that can really help you speed up the process of reviewing all migration EWIs (Errors, Warnings and Issues) when working with migrated code. In Visual Studio, you can use the Task List panel to keep track of a list of items (tasks) you need to go through. This Task List can be configured to show migration EWIs, as shown in the following screenshot:

For this to work, in the Visual Studio IDE, select Tools->Options from the main menu. In the Options window, navigate to Environment->Task List. Here, you’ll need to add the four types of EWIs inserted by the VBUC, along with their priority:

UPGRADE_ISSUE: Issues appear when there is some migrated code that is very likely to cause a compilation error. My recommendation is that you add it with Normal priority

UPGRADE_NOTE: Notes are basically information messages. For example, if the VBUC detects dead code, it will comment it out and add an UPGRADE_NOTE comment to make sure the developer understand why it was removed. This can be added as Low priority, since they very rarely require manual intervention after the migration.

UPGRADE_TODO: Partially upgraded code. These EWIs should be added as high priority, since they indicate the developer needs to perform some additional work to complete the migration.

UPGRADE_WARNING: Warnings appear when there is a difference in behavior between the VB6 code and its .NET equivalent. The solution provided normally works, but there are some scenarios where additional manual intervention may be required (most likely from runtime errors). I normally add them to the Task List as Normal priority.

With this configuration, you can very easily and quickly browse through all the EWIs in a file, and determine which ones actually require you to perform some manual work, and which ones can be either removed because the line they are tagging will work, or if their verification will be deferred until functional testing takes place.

A couple of days ago we made available the final release candidate for version 3.0 of both the Visual Basic Upgrade Companion Enterprise Edition and Developer Edition. You can now directly download a trial of the VBUC Developer Edition on the trial download page, or request a trial of the Enterprise Edition on this page.

I need to mention an obligatory disclaimer saying this is the final Release Candidate, so, unless we find something at the last minute, it should be the same version officially released within a week or so. We need your help to verify we won’t find anything by downloading it and trying it out. :)

I already covered some of the features of this version on a previous post. There was significant improvements in several areas from version 2.2, which should help you achieve even greater productivity on your migration projects.

As I blogged before, the release of the VB Upgrade Companion v3.0 is due within the next few weeks. In this version we concentrated on three major areas:

Automation: We analyzed the data from several million lines of code to determine the most common causes of manual intervention, and, by making some strategic changes to the way the code is generated, managed to reduce the amount of both EWIs (Error, Warning and Information messages) and compilation errors significantly on large (>1 million Lines of Code), complex applications. Also, depending on the VB6 features used, the VBUC now automates the migration of even more smaller applications and components completely!

New Features: The VBUC v3.0 also contains additional features, such as the migration of the IsMissing statement and increased support for additional third party components. We are also integrating the VBUC with brand new online documentation resources that should help you as you perform the migration!

Code Quality: The Visual Basic Upgrade Companion always tries to generate high-quality code that looks as if it was originally written in .NET. This increases the maintainability of the migrated application, and allows developers joining the project at a later date to very quickly start working on the codebase. Because of the great differences between Visual Basic 6.0 and VB.NET/C#, however, achieving this goal is not always possible. For this release we continued increasing the quality of the migrated code, including minor refactorings to control structures, and adding things like support for translating additional error handling statements to try/catch statements.

All of these was supported by some significant changes we did under the hood, which should make it easier to add new features in the future (including customer-specific customizations) and reduced the memory footprint significantly, while increasing migration speed. Watch this space for more details as the release date approaches!

We are currently wrapping up all development effort to focus on the final testing and stabilization of the next version of the Visual Basic Upgrade Companion, both Enterprise and Developer Editions, version 3.0. For this version we focused more on architecture improvements, preparing the code base for more significant upgrades in the future. We still we managed to add some great features such as:

Enhanced resolution of default properties: By both improving the typing engine of the VBUC and generating additional code for runtime resolution of default properties, we were able to reduce the total amount of EWIs present in the code by 30%!

Improved support for API Calls: Most API calls should now work correctly. There are still a couple of issues, but they should be sorted out by the final release

IsMissing migration: We now correctly support the migration of the IsMissing statement.

Enhanced support for the migration of common controls, such as Imagelist, Listview, Statusbar, Toolbar and Treeview, to native .NET components. We now correctly convert most functionality of these controls to .NET

A greatly enhanced Assessment Mode to better estimate the effort required to perform a migration project

Significant performance improvements and memory footprint

Over 150 code generation improvements based on feedback from projects we’ve done, our clients and partners

We are currently conducting a limited Beta program for the VBUC Developer Edition v3.0. If you are interested in participating, drop me a line and I’ll get back to you with further instructions.

Edit: The upcoming version of the VBUC will be version 3.0 - this release represents a leap in the level of automation and additional features we managed to squeeze in, and thus deserved a new major version number. I will post additional details on the different features as the final release date approaches.

This week we published a new case study on the migration we performed for Banamex, part of Citigroup and one of the largest Mexican banks. In this project we migrated 124 Visual Basic 6.0 and ASP applications from different divisions of the bank to C# and ASP.NET. All in all, we migrated over 5 MILLION LINES OF VB6 AND ASP CODE. This is the largest VB6 to .NET migration we’ve done so far, it was a huge success story – so much that we are now working on the migration of some other applications that weren’t originally included in the scope of the project.

One of the key features of the Visual Basic Upgrade Companion (one that is not present in the Developer Edition, BTW) is that it’s functionality can be customized and extended. By doing this, developers working on a migration can have the VBUC do as much of the work as possible for them, minimizing the manual work and producing a higher quality product that satisfy both the developer’s and end user’s expectations. Performing repetitive changes to, for example, replace the data access components from VB6 (ADO/RDO/DAO) with native .NET data access (ADO.NET), is better done by the VBUC at migration time. This also applies to particular programming patterns used by organizations that need to be replaced by .NET-native patterns, and to coding conventions that vary between VB6 and .NET languages.

The Visual Basic Upgrade Companion includes three mechanisms to customize the generated code: Migration Profiles, Custom Maps and Additional Customizations.

Migration Profiles

A new feature that was introduced in version 2.0 of the Visual Basic Upgrade Companion, it gives end users control over which features and transformations to use for a particular migration, by using the concept of Migration Profiles. These profiles provide two types of rules that can be switched on/off. The first type, Code Conversion Rules, that deal with patterns applied to the code, such as generating structure error handling (try…catch) from On Error…Goto statements or applying commonly used naming conventions to the code. The second type is called Component Maps, and deal with translations from from one ActiveX component, such as a status bar or a grid, to a native version of the component.

Profiles are managed through the Profile Maintenance screen:

Custom Maps

The Visual Basic Upgrade Companion includes a “mapping” mechanism that allow end-users of the tool to define the transformation of one element of a library used in the VB6 code to a member of an assembly in .NET. This allows a migration team to identify and implement time-saving transformations, and, when combined with the implementation of an adapter for the .NET component, can speed up the migration process dramatically.

The Mappings are defined through a GUI editor launched from within the VBUC itself:

Once the mappings are defined, they can be switched on and off in the migration through the Migration Profile Maintenance Window:

Additional Customizations

ArtinSoft’s VBUC development team can also include additional complex rules in the VBUC, including customizations for items such as error handling patterns, architectural modifications, and others. These customizations also include mapping COM controls to in-house libraries, or force in-house naming conventions. This was a decision point for one of clients in the United Kingdom, Vertex Financial Services, as documented in the Vertex Omiga case study:

“Vertex decided to migrate the Omiga application to C# using a customized version of the Visual Basic Upgrade Companion, a tool developed by ArtinSoft based on artificial intelligence technology. ArtinSoft was highly recommended by Microsoft UK, and the customization of this migration tool enabled Vertex to automatically convert coding patterns and meet its preferred standards.”

These type of customizations require some modifications to the VBUC that can only be performed by ArtinSoft’s in-house team. It is a very valuable option that allows companies to get a an end product which furthers increases the return on investment from the migration.

The VBUC Developer Edition does have some fewer features than the fully-fledged Visual Basic Upgrade Companion. All the features that we decided to include in the Developer Edition, however, are targeted towards automating as much of the migration process as possible. So, we left out features that have been introduced by the request of our enterprise customers over the 7+ years the tool has been on the market (yep, we were already doing VB6 migrations before the official release of .NET - and it wasn't all fun with the Betas). We made it so that getting an application up and running in C# or VB.NET is as simple as possible.

The Visual Basic Upgrade Companion is able to generate both C# and Visual Basic .NET code from the original Visual Basic 6.0 code base. Thus, when doing a migration project with our tools, you can choose either language. This decision is a challenge itself, especially if you aren't doing any .NET development before the migration. You have to measure the skill set of your staff, and how comfortable they will feel with the transition from VB6 to either language.

Here are some points that are normally thrown around when comparing C# and VB.NET:

Support: Both languages are well supported by Microsoft, and are first-class citizens on the .NET Framework. Neither one will go the way of the Dodo (or the way of J#, for that matter).

Adoption: C# seems to have higher adoption than VB.NET. A completely unscientific and in no way statistically valid quick search on the books section of Amazon, however, returned 15,429 results for C#, and 2,267 results for Visual Basic .NET. Most of our customers migrate to C# instead of VB.NET as well. So there may be some truth in this.

Perception: C# was developed from the ground up for the .NET Framework. This has affected VB.NET's mind share, as C# is viewed as the new, cool language in town. C# is also seen as an evolution of C and C++, which are considered more powerful languages. And we've all heard at least one Visual Basic 6.0 joke - which means that even though VB.NET is a completely different beast, the "VB" name may work against it.

Familiarity: Visual Basic .NET's syntax is very similar to VB6's, so it is assumed that VB6 developers will feel right at home. This may or may not be true, since they will need to learn all the differences of the new environment, not only the syntax.

.NET allows you to mix programming languages, even on the same Solution. So you could have some developers work in C#, while other work in VB.NET - basically let them use the language they feel more comfortable with. DON'T. This may become a maintenance nightmare in the future. You should definitely standardize on just one language, either C# or VB.NET, and stick with it. That way you'll save time and resources, and overall have a more flexible team.

Also, keep in mind that the biggest learning curve when coming from the VB6 world won't be the object orientation of VB.NET or the curly bracket syntax of C#. It will be learning the .NET Framework. That is what you should plan training for, not for a particular language. Learning the syntax for a new programming language is pretty trivial compared to the effort required to correctly use all the APIs in .NET.

All in all, you can do anything on either language. I personally like C# better, mainly because I started with C, C++ and Java before moving on to .NET development. Coding is C# is "natural" for me. But you can develop any type of application in C# or VB.NET, as there's no meaningful difference under the covers.

When planning the migration of large applications you may want to use a phased approach. This means that as you migrate the first portions of your application to .NET, you will need to keep the interaction with the Visual Basic 6.0 code. Depending on your application's architecture, you can use one of the following approaches:

Interop Forms toolkit: Now at version 2.0, it simplifies the process of embedding .NET forms and controls inside VB6 applications. It is recommended for GUI-intensive applications

Binary Compatible .NET DLLs: This technique allows you to expose .NET components through COM. It is recommended for multi-tier apps, especially if you want to migrate the back end before you migrate the front end. It allows VB6 and ASP applications to continue using the same components even after they are migrated to the .NET Framework.

Once you have the .NET code, you need to check Register for COM Interop in the Project Properties page in Visual Studio.NET, and then you are all set. Your VB6 and ASP applications will continue working with the newly migrated .NET components, transparently, while they await their turn for a migration.

We recently did some quick tests on the results of some projects that we just finished migrating to compare the binary size and memory footprint of the resulting migrated .NET application and the original Visual Basic 6.0 application. Here is a brief summary of the results.

Binary Size

We have seen that binary sizes remain very similar or decrease by a small margin when compared to the original Visual Basic 6.0 binaries. There is a small amount of application re-factoring that contributes to this reduction, though, such as consolidating all shared files to a common library (instead of including the same files in several VB6 projects, which increases the code base and binary size).

You do have to take into account the space required by the .NET Framework itself, that varies from 280MB to 610MB.

Memory Footprint

Our observations on the memory footprint of migrated .NET applications, when compared to the original VB6 applications, is consistent to what we've seen with the binaries' size. .NET applications have higher initial memory consumption, since the .NET Framework sets up the stack and heap space at startup, and you have to add the memory required by the JIT compiler. Even with these constraints, a quick revision of applications that we've migrated for customers shows that the memory consumption is, on average, around 10% less than in VB6 (these are no scientific measurements, just based on monitoring memory consumption during the execution of test cases).

We have also seen that .NET normally maintains a more consistent memory usage pattern, while VB6 applications has more peaks where the memory consumption goes up, then back down. This is caused by the .NET Framework holding on to resources until the Garbage Collector runs, and the overall improvements in memory management included in the .NET Framework.

.NET applications have a memory overhead associated with the .NET Framework itself. This is more noticeable in small applications, but overall, is a tradeoff required for running on a managed environment. According to the .NET System Requirements, the Framework requires at least 96MB (256MB recommended) of RAM to run. In our experience, however, you should have at least 512MB (1GB recommended) of RAM to run migrated applications comfortably (on Windows XP).

The performance of a migrated .NET application, when compared to the original VB6 application, is normally very similar or better. The only instances when we have seen a performance decrease is when doing an important re-architecture or when the database engine is changed (from Access to Oracle, for example). Every once in a while we also run into issues with the Garbage Collector, but fortunately they are not that common and are easy to detect.

One thing to keep in mind is the way .NET loads assemblies, and how they are executed. .NET assemblies are compiled to an intermediate language, called CIL (Common Intermediate Language, formerly MSIL). When these assemblies are executed, the default behavior for the .NET Framework is to use a Just-In-Time compiler, which compiles the CIL code for a method to native code "on the fly" the first time the method is called. This implies an overhead on this first call, which suffers from a (normally acceptable) performance impact while the JIT compiler runs. Once a method is compiled, though, it is kept in memory, so the performance of subsequent calls is not affected. Once the code is in memory the performance of the .NET application is normally better than the performance of the VB6 application. You can find more information on JIT here.

As I mention in a post last week, we recently released version 2.2 of the Visual Basic Upgrade Companion. The previous version, 2.1, added some new things, but focused mostly on "under the covers" improvements, and fixing several issues reported with version 2.0. However, for this release, we do have several exciting new features that should make migrations from Visual Basic 6.0 go much smoother. Among these, we can mention:

Custom MappingsThe Visual Basic Upgrade Companion enables the user to define customized transformations for the upgrade process execution. This technique allows to implement coverage for non-supported legacy components and to enhance and fine-tune the existing support. I already covered Custom Maps on this post and you can read more about this on the Custom Maps page.

Data access - new flavors availableThe Visual Basic Upgrade Companion converts the data access model on your VB6 application (ADO, DAO, RDO) to ADO.NET, using the either SQLClient data provider or the classes defined in the System.Data.Common namespace. Using the latter will allow your migrated application to connect with most major .NET database providers. Version 2.2 added support for the automated migration of DAO and RDO to ADO.NET, and greatly improved the migration of ADO to ADO.NET. More information here.

Naming conventions refactoringThis feature lets the end-user migrate his Visual Basic 6 code to VB.NET or C# with standard Naming Conventions. This feature is a compound of common naming conventions for .NET languages, and use standard coding practices for C# and VB.NET. You can find more information on this and the next feature in this page.

Renaming mechanismThe renaming feature changes the name of an identifier and all of its references in order to avoid conflicts with another name. Some of the conflicts solved by the VBUC are:

Keywords: The VBUC must rename the names that are the same as keywords from Visual Basic .NET and C#. Moreover, the VBUC should take into account the target language (Visual Basic.NET or C#) to recognize the keywords that apply for each case.

Case sensitive issues (C#): Visual Basic 6 is a case insensitive language, but C# is not. The VBUC must correct the name references used with different cases to the case used in the declaration.

Scope conflict: This is necessary when a Type declaration element has the same name as the type declaration. If this case is detected the element declaration must be renamed along with the references to this type element.

Conflicts with .NET classes: This section applies for Forms and UserControls, mainly, because they could declare some member names that are part of the corresponding class in .NET (in this case System.Windows.Forms.Form & System.Windows.Forms.UserControl). These members must be renamed in order to avoid any conflict.

User Controls and Custom Properties In Visual Basic 6.0 user controls expose their programmer-defined properties in the property list on the designer window. These user properties can be configured to be displayed in a specific category and based on these settings. The Visual Basic Upgrade Companion can determine the most appropriate type and settings for the resulting properties to have functional equivalence with the original VB6 user property. I plan on elaborating on this feature in a future blog post.

Custom Maps: You can now define custom transformations for libraries that have somewhat similar interfaces. This should significantly speed up your migration projects if you are using third party controls that have a native .NET version or if you are already developing in .NET and wish to map methods from your VB6 code to your .NET code.

Legacy VB6 Data Access Models: for version 2.2 we now support the transformation of ADO, RDO and DAO to ADO.NET. This data access migration is implemented using the classes and interfaces from the System.Data.Common namespace, so you should be able to connect to any database using any ADO.NET data provider.

Support for additional third party libraries: We have enhanced the support for third party libraries, for which we both extended the coverage of the libraries we already supported and added additional libraries. The complete list can be found here.

Plus hundreds of bug fixes and code generation improvements based on the feedback from our clients and partners!