FRANCESCO BALENA ON VB MIGRATION

 

ADOLibrary is in semi-public beta!

clock August 10, 2010 13:03

After many months of internal beta testing, last week we released our revolutionary ADOLibrary to selected customers.

As you may remember from a previous post, Code Architects' ADOLibrary offers effortless migration from ADODB to ADO.NET. Basically, ADOLibrary is a set of ADO.NET-based classes that expose an ADODB-like object model. For example, the ADOConnection object has the same programming interface as ADODB.Connection and behaves much like the same; the ADORecordset class works like the ADODB.Recordset class, and so on. ADOLibrary currently supports all ADODB classes, with the only exception of the Record class. It is important to emphasize that ADOLibrary is fully ADO.NET and has no dependency on ADODB or other COM technologies.

ADOLibrary currently supports the vast majority of ADODB features, including forwardonly-readonly rowsets, optimistic batch updates, parameterized commands and stored procedures, the Filter property for client-side recordsets. If accessing Microosft SQL Server, keysets and dynamic server-side cursors are also supported. ADOLibrary event supports most ADODB dynamic properties, such as Update Criteria and Unique Table.

Actually, it's easier to list what ADOLibrary does *not*currently support, namely hierarchical recordset, the Record object, and multiple, semicolon-separated commands in the Execute method (they are fine in the Recordset.Open method, though).

The whole ADOLibrary documentation is already available online. This is a draft version and lacks some code samples, but it is already enough exhaustive to be usable.

 



The best code analysis tool for VB.NET and C#

clock April 13, 2010 06:17

 


 

 

A few customers asked us to indicate what tools they can use to analyze and improve the VB.NET code that VB Migration Partner generates. Our answer has always been: get a copy of NDepend. In a nutshell, NDpend allows you to

  • compute as many as 82 different code metrics, virtually all the code metrics you can think of
  • generate dependency graphs between methods, classes, and assemblies
  • compare two different versions of your codebase
  • gather code coverage results from NCover and Visual Studio Team System
  • perform very sophisticated queries on the analysis results, using a CQL, a query language that resembles SQL
NDepend is perfectly integrated with Visual Studio. For example, you can browse the result of a CQL query, double-click on a class or method name, and - presto! - you jump to the code inside that class or method.

Unlike all other code analysis tool I know about, which offer a limited set of reports, NDepend allows you to create your custom report thanks to the CQL query language. For example, consider these CQL example, taken from NDepend Feature page:

Which methods have been refactored since the last release and is not thoroughly covered by tests?
SELECT METHODS WHERE CodeWasChanged  AND  PercentageCoverage <  100

Which classes implement a particular interface?
SELECT TYPES WHERE IsClass AND Implements "System.IDisposable"

Which methods create objects of a particular class or assign a particular field?
SELECT METHODS WHERE CreateA "MyNamespace.MyClass"
SELECT METHODS WHERE IsDirectlyWriting "MyNamespace.MyClass.m_Field"

What are the 10 most complex methods?
SELECT TOP 10 METHODS ORDER BY CyclomaticComplexity

Which public methods could be declared as private?
SELECT METHODS WHERE IsPublic AND CouldBePrivate

Which complex method is not enough commented?
SELECT METHODS WHERE  CyclomaticComplexity >  15 AND  PercentageComment <  10

CQL does have a learning curve, but if you are familiar with SQL you will find yourself comfortable with it very soon. NDepend even comes with an integrated CQL editor that supports intellisense.

You can learn more about NDepend by watching this short but very informative video.



Code Architects' ADOLibrary, a revolutionary approach to ADODB to ADO.NET migration

clock October 2, 2009 08:32

When migrating a VB6 legacy application, obtaining a working piece of VB.NET code is only part of the story. To complete the transition to the .NET world you also want to convert your database-access code to ADO.NET.

The Upgrade Wizard that comes with Visual Studio doesn't offer any option to upgrade ADODB code, with a good reason: "traditional" code translators can't automatically convert from ADODB to ADO.NET, no matter how sophisticated the translator is. (More on this below)

Fortunately, VB Migration Partner isn't a "traditional" code conversion. We have already proved that it correctly translates many VB6 features and keywords that many "migration experts" swore that were impossible to translate automatically. VB Migration Partner 1.20 supports *all* the major VB6 features, inclduing Gosubs, Variants, graphic statements, drag-and-drop, DDE, and a lot more.

After we dealt with the complete set of VB6 features, we decided to focus our attention on the challenges of porting ADODB-based code to ADO.NET.

The result of our efforts is Code Architects' ADOLibrary, a revolutionary tool that makes ADODB-to-ADO.NET migration one or two orders of magnitudes simpler, faster, and less expensive.

In a nutshell, ADOLibrary is a set of native .NET classes that behave exactly like their ADODB counterparts. For example, the ADOConnection object supports all the methods, properties, and events of the ADODB.Connection object, with exactly the same syntax and the same behavior. The same holds true for the ADORecordset class, the ADOCommand class, and ancillary classes such as ADOParameter, ADOField, and ADOProperty.

ADOLibrary is currently in internal beta stage, but it already supports forwardonly-readonly cursors and client-side cursors with optimistic batch updates. We even and transparently support advanced ADODB programming techniques, such as asynchronous events and alternate update strategies (the Update Criteria property), for the benefit of demanding ADODB gurus out there.

With its vast support for most ADODB features, ADOLibrary enables you to migrate thousands of database-related statements in a matter of hours. This is perhaps 100-200x faster than a manual migration and 10-20x more productive than any other code translator on the market. In practical terms, it can save you weeks or months in a real-world migration project and significantly reduce migration costs.

The first ADOLibrary example

Let me give you an idea of what the ADOLibrary works. Say that you have the following piece of VB6/ADODB code:

    Dim cn As New ADODB.Connection
    Dim rs As New ADODB.Recordset
    ' connect to Northwind
    cn.Open "Provider=SQLOLEDB.1;Initial Catalog=Northwind;..."
    cn.CursorLocation = ADODB.adUseClient
    rs.Open "Select * from Products ", cn,
ADODB.adOpenStatic, _
       
ADODB.adLockBatchOptimistic
    
    ' Load a listbox with all product names
    Do Until rs.EOF
        ListBox1.AddItem rs.Fields("ProductName").Value
        rs.MoveNext
    Loop


Here's the VB.NET code that uses the ADOLibrary, as generated by VB Migration Partner:

    ' Assumes: Imports CodeArchitects.ADOLibrary

   
Dim cn As New ADOConnection
   
Dim rs As New ADORecordset
    ' connect to Northwind
    cn.Open("Provider=SQLOLEDB.1;Initial Catalog=Northwind;...")
    cn.CursorLocation = ADOCursorLocation.adUseClient
    rs.Open("Select * from Products ", cn, ADOCursorType.adOpenStatic, _
        ADOLockType.adLockBatchOptimistic)
    
    ' Load a listbox with all product names    
   
Do Until rs.EOF
        ListBox1.AddItem(rs.Fields("ProductName").Value)
        rs.MoveNext()
   
Loop

As you see, the VB.NET code is basically the same as the original VB6 code, except for the different class and enum names. Even more important, the code is perfectly equivalent to the original VB6 code

If you are an ADODB developer you will find yourself comfortable with the generated code, which is as maintainable as the original VB6 code, except it leverages ADO.NET's superior performance and scalability. You are immediately productive and don't have to study ADO.NET, because our ADOLibrary hides the many differences between the two object models.

Don't let the ADODB-like syntax fool you, though: ADOLibrary relies on ADO.NET objects exclusively and has no dependency on COM or ADODB. It's like having ADO.NET with an ADODB dress.

But the ADOLibrary is more than just an ADODB clone, because it exposes all the ADO.NET structures that it uses internally in addition to all the properties and methods "inherited" from ADODB.

For example, the ADORecordset object exposes the inner DataTable object that stores the individual records. You can therefore bind the "recordset" to .NET controls and data grids. Or you can optimize the converted code as follows, and improve it to keep track of both the product name and the product ID:

    ' Load a listbox with all product names
    ListBox1.ValueMember = "ProductID"
    ListBox1.DisplayMember = "ProductName"
    ListBox1.DataSource = rs.DataTable     ' use native .NET binding!


Thanks to the DataTable member, you can rely on .NET databinding to implement master-detail relationships, advanced data formatting, input validation, and so forth. Just keep in mind is that all these additions and fixes are optional, because the converted .NET code will work immediately as-is.


Why you can't obtain ADODB-to-ADO.NET functional equivalence with a traditional code translator

At least another VB6 conversion tool vendor claims that their product can handle ADODB to ADO.NET conversions by means of code transformation techniques. However, they don't go into many details about which features are converted and which ones require some (or a lot of) manual fixes.

The problem in automatic conversion of ADODB code to ADO.NET is two-fold. First and foremost, it is impossible to achieve full functional equivalence. Second, filling the gap between ADODB and ADO.NET by means of code transformations is that you end up generating verbose (and often illogical) code that is very hard to maintain and evolve in the future.

Consider the following trivial code snippet:

    Set cnNorthwind As New ADODB.Connection
   
Set rsOrders As New ADODB.Recordset
   
cnNorthwind.Open "Provider=SQLOLEDB;Data Source=.;Initial Catalog=Northwind;Integrated Security=SSPI"
    rsOrders.Open "SELECT * FROM Orders", db,
ADODB.adOpenKeyset, _
        ADODB.
adLockOptimistic

Notice that this example uses server-side keyset cursors, that aren't supported by ADO.NET. Keysets are typically used when you need to modify data in the database, therefore the closest ADO.NET structure that can perform the same task is the combination of a DataSet plus a DataAdapter. This is the best code that a conversion tool that relies solely on code transformation can generate

    Dim cnNorthwind As New SqlConnection
   
Dim rsOrders As New DataSet
    cnNorthwind.Open("
Provider=SQLOLEDB;Data Source=.;Initial Catalog=Northwind;Integrated Security=SSPI")
   
Dim cmd As New SqlCommand
   
cmd.Connection = cnNorthwind
   
cmd.CommandText = "SELECT * FROM Orders"
   
Dim da As New SqlDataAdapter(com.CommandText, com.Connection)
    adap.Fill(rs)

Up to here, the converted code behaves more or less like the original VB6 code. However, the actual problems arise now. For example, consider that

  • the original ADODB code typicall uses a Do Until rsOrders.EOF loop to visit and possibly modify each record in the database. The loop can be transformed into a For Each loop that visits all the rows in the DataTable, but the database is updated only when the DataAdapter's Update method is invoked.
  • when using a keyset on a locked record, you get a runtime error when you modify one or more fields and then move away from the current record. Conversely, the optimistic lock used by the DataAdapter.Update throws a single error when any record in the DataTable fails to update. The two models greatly differ, so expect a lot of manual fixes in this area.
  • The example shows a simple SELECT query, however many VB6 apps retrieve (and update) by means of queries or stored procedures with parameters. ADODB and ADO.NET mechanisms for retrieving and using stored proc parameters are very different and this gap can't be filled by writing some code. Besides, the .NET CommandBuilder.DeriveParameters method has several defects and can't be used in production code, thus in practice you are forced to define all the query parameters manually in code.

It isn't at all surprising that our competitors don't provide any code sample that shows how their tool converts these (and many other) ADODB basic features, such as Recordset and Connection events, transactions, and bookmarks. Not to mention more advanced ones such as the Update Criteria property and the Resync method.

In practice, we estimate that a traditional code translator can automate no more than 10-15% of the statements that read, write, and process data stored in a database. Is 15% enough to qualify for ADODB-to-ADO.NET automatic conversion?

Our competitor also claims that their tool can convert code in a database-agnostic fashion. In .NET parlance, it means that they generate code that uses objects in the System.Data.Common namespace exclusively, e.g. DbConnection and DbCommand. You might believe that it's a good approach at writing database-agnostic code, until you see how ADOLibrary solves the same problem.

Internally, ADOLibrary uses the .NET objects in the System.Data.Common namespace, therefore it is inherently database-agnostic. When it's time to create a concrete class, by default ADOLibrary instantiates the objects in the System.Data.OleDb namespace (e.g. OleDbConnection, OleDbCommand, and so forth), and is therefore as database-agnostic as the original ADODB code. However, this is just the default behavior and you can override it by simply setting a global property.

For example, if your application is designed to work with Microsoft SQL Server exclusively, you can have ADOLibrary instantiate concrete classes in the System.Data.SqlClient namespace, which delivers faster and more scalable code. To enable this optimization you just need to add the following single statement:

    ADOConfig.LibraryKind = ADOLibraryKind.SqlClient

That's it! No need to be confused with base classes or other similar annoyances! Wink

For even more flexibility, you can read the value of the LibraryKind property from the configuration file, to let your end users customize the application for the database they actually use, without you having to recompile your code. Talk about flexibility!



A .NET library to access Windows Vista and Windows 7 features

clock September 16, 2009 21:58

One of the reasons to migrate your code to .NET is create modern user interface that take advantage of the power of newer versions of Windows. On the other hand, the .NET Framework has been designed to work in the same way over a wide range of Windows versions, including versions that are about ten years old, and therefore it doesn't provide access to the most intriguing features of Vista and Windows 7.

The solution comes in a new library from Microsoft, named Windows API Code Pack for .NET Framework. Version 1.0 of this great tool has been just released, and already implements an impressive range of Windows features:

  • Windows 7 Taskbar Jump Lists, Icon Overlay, Progress Bar, Tabbed Thumbnails, and Thumbnail Toolbars.
  • Windows 7 Libraries, Known Folders, non-file system containers.
  • Windows Shell Search API support, a hierarchy of Shell Namespace entities, and Drag and Drop functionality for Shell Objects.
  • Explorer Browser Control.
  • Shell property system.
  • Windows Vista and Windows 7 Common File Dialogs, including custom controls.
  • Windows Vista and Windows 7 Task Dialogs.
  • Direct3D 11.0, Direct3D 10.1/10.0, DXGI 1.0/1.1, Direct2D 1.0, DirectWrite, Windows Imaging Component (WIC) APIs. (DirectWrite and WIC have partial support)
  • Sensor Platform APIs
  • Extended Linguistic Services APIs
  • Power Management APIs
  • Application Restart and Recovery APIs
  • Network List Manager APIs
  • Command Link control and System defined Shell icons.
  • Shell Search API support.
  • Drag and Drop functionality for Shell objects.
  • Support for Direct3D and Direct2D interoperability.
  • Support for Typography and Font enumeration DirectWrite APIs. 

The library comes with an extensive help file and all code samples are available in both VB.NET and C#. Last but not the least, the entire source code is provided.



Estimate total migration cost for existing VB6 conversion software

clock July 31, 2009 04:04

Every day we receive requests and queries from VB6 developers and companies who are interested in migrating their code to .NET. Migration a complex application to .NET is a serious matter, therefore it’s no surprise that virtually all our prospects plan to compare our software with the similar tools from the competition.

We take migration seriously and we take competition even more seriously. As a matter of fact, we entered this market niche only when we were sure we could offer the best VB6 software that could be possibly written. And that’s why we have continued to improve our VB Migration Partner until it offered support for virtually all major VB6 features, including outdated features such as “classic” drag-and-drop and DDE.

Some other companies in this market have a different perspective, though, and some of our competitors prefert to cut the list price instead of improving their software to match all the VB Migration Partner’s features. A recent example: One of our competitors has dropped their list prices twice in a few months, in an obvious attempt to compensate for all the features that their product lacks.

Which brings up an interesting question: is the list price the “correct” way to estimate how expensive migration tools are? Isn't the total cost of migration a better criterion for selecting the right conversion tool?

All the real-world migration experiences and case studies show that greater part of migration costs is related to the manpower needed for manual tasks that are to be completed before and after the mere action of passing the VB6 code through the conversion software. In the big scenario, the cost of the migration tool is a very small fraction of the total cost, often in the range 5-10% or even lower. Therefore, when comparing migration tools the most “correct” selection criterion should account for the manual labor that each tool saves you

Some time ago we published a very detailed white paper that compares VB Migration Partner with other VB6 conversion tools. The document clearly illustrates that VB Migration Partner outperforms the competition under virtually all aspects, yet it doesn’t really emphasizes which supported features impact on the total cost and duration of the migration process. Here we remedy with the following short summary.

1. Functional equivalence: VB Migration Partner can handle even the most subtle differences between VB6 and VB.NET, including true auto-instancing (As New) semantics, by-reference ParamArray, correct disposal of database connection and other COM objects, thread-safe behavior for multithreaded components, 100%-compatible file I/O statements, and the many methods that behave slightly differently in VB6 and VB.NET. These features can dramatically cut the time required for testing the migrated application.

"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." (from a case study by SIS, an Austrian Microsoft Partner)

2. Variant and Null values: VB Migration Partner can (optionally) translate Variants into the special VB6Variant type, which behaves exactly like the VB6 type. It even supports Empty and Null values, which is a lifesaver if you are migrating a database-intensive application that uses Null values in expressions and assignments. By comparison, all other conversion tools simply convert Variant into the Object type, which in practice means that you have carefully test each and every statement that might be using a Null or Empty value.

Note: one of our customers is converting a very large VB6 application that makes extensive use of Variants; they estimated that VB Migration Partner saved no fewer than 3-4 man/moths just because of its support for Variants and Null values. We will provide more details when the migration is completed.

3. Late-binding method calls: VB Migration Partner comes with a library of .NET controls that expose the same properties and methods as the original VB6 controls. This detail ensures that your code works fine after the conversion to .NET, even if the control is accessed in late-bound mode. If you use another conversion tool you must manually rewrite each and every statement that uses late binding. If your VB6 code uses many Variant, Object, and Control variables, this task alone can keep you busy for weeks.

4. Support for *all* VB6 keywords and features: if your VB6 app uses GoSub, On Goto, or On Gosub statements, using a conversion tool other than VB Migration Partner means spending at least a few minutes on each of these keywords. The problem might be more serious if your VB6 code relies on other, less common features - such as Dynamic Data Exchange (DDE), ADO data sources or data consumers - because you’d be forced to re-write large portions of your code. Implementing a reliable communication infrastructure based on .NET remoting or WCF may take one week or two if you aren’t a .NET guru, or it takes ten seconds flat if you use VB Migration Partner.

5. Graphic statements: VB Migration Partner supports virtually all VB6 graphic capabilities, including the Line and Circle methods, double-buffering (the AutoRedraw property), and user-defined system coordinates (ScaleMode property). VB Migration Partner lets you can convert a graphic-intensive VB6 application in a matter of seconds. Any other conversion tool takes days even for the simplest graphic project, because none of them supports these graphic features.

For examples of painless conversion of graphic-intensive VB6 code, have a look at EGL25, TypeNSign, Stars, Barcode Generator, BC-52, and MP3 Player applications in our Code Sample section. (We even have fully playable versions of classic games such as Tetris, Pacman, and Space Invaders!)

6. Windows API calls: all our competitors are behind VB Migration Partner in how they deal with complex Windows API calls, such As Any and callback (AddressOf) parameters in Declares statements. Our VB Migration Partner goes even further: it automatically fixes undocumented issues caused by string immutability and orphaned delegates, recommends the best “pure .NET” replacement for 300+ common Windows API calls, and automatically performs the substitution automatically, if possible. You can read more here.

7. Rich user interface: in theory all conversion tools support all VB6 user interface features; in practice tools from our competitors require that you manually fix each individual form. An indirect evidence of their limits is that none of our competitors dares to offer examples of real-world VB6 forms and the corresponding .NET form, because they would be obliged to mention all the manual fixes that are necessary to have a working .NET application. Also, none of our competitors even gets near VB Migration Partner’s support for more advanced UI features, such as drag-and-drop (both OLE and “classic” flavors), popup menus, dynamically created controls (the Controls.Add method), and 100%-compatible object models for complex controls such as TreeView, ListView, Toolbar, and StatusBar.

Tip: When comparing conversion tools, have a look at the many differences between VB6 and .NET controls, prepare a list of those that may be important for you, and ask each vendor whether their tool can handle them.

8. Staged migrations: VB Migration Partner is the only conversion software that can convert a large N-tiered VB6 application one DLL at a time while preserving the binary compatibility with the original VB6 components. Binary compatibility means that you can reuse the VB6 user interface to launch and test the converted .NET components, and you can even reuse your automatic test procedures, if you have any. You can even hit the market with a “hybrid” VB6 / .NET solution earlier, if you need to do so. If ease of testing and reduced time-to-market are important to you, the choice is obvious.

9. The convert-test-fix methodology: A real-world migration process may take weeks or months, and you might need to extend or modify the original VB6 code before the migration is complete. All other tools on the market work on a snapshot of the VB6 code, therefore once the migration is ended you’ll have to manually modify the .NET code to preserve the functional equivalence with the VB6 application. This process takes time and is error prone, and can be very expensive. You don’t incur in this added cost if you adopt our convert-test-fix methodology, which in turn is based on migration pragmas (another VB Migration Partner’s unique feature).

"The batch processing and code-test-fix methodology will allow us to convert a changing code base without making the same changes twice, once in VB6 and again in VB.Net." , said Brian Olson, Actuarial Systems Corporation, USA.

10. Documentation, code samples, licensing, and support: A realistic estimation of total migration costs must include the time needed to become familiar with the migration software and its idiosyncrasies, peculiarities, and defects. In this respect, nothing beats VB Migration Partner’s online manual and the vast knowledge base, which we update and improve almost every day with tips, code examples, and workarounds.

We believe so much in our software that we offer lifetime warranty on VB Migration Partner’s support library: if you are a registered user of version 1.xx you have the right to download future 1.xx versions of the library. (For more details, please read our EULA.) Compare our approach with the time-limited license that most of our competitors offer, and you’ll have a clearer idea of which product can really save your time and which one can waste your money.

As for the quality of tech support, here is what some of our customers have to say:

"The documentation is excellent, and Code Architects’ tech support has always been very responsive."
Dr. Otto J. Wiegele, CEO, SIS Datenverarbeitung GmbH

"I’d like to thank Code Architects’ technical support team, who supported us through our endeavors, in a professional and efficient way. They and their software allowed us to complete the migration of our flagship application earlier than expected.
"
Marco Meneo, ProgeSoftware, Italy

"The Code Architects Team always solved all our doubts and problems, often in a matter of hours. Francesco Balena in person replied to the toughest queries about COM marshaling and object disposal. It was a pleasant surprise to find such a competent team and a company that is willing to extend their support to issues that aren’t strictly related to their product."
Stefano Baldi, Engineering PLM Solutions, Italy

"Any issue that I raised was answered positively on a next day if not next hour basis also made a huge difference. It's really as close to having VB Migration Partner's support team work in my office as one could get!"
Ara Ashikian, P.Eng., President, Structural Concepts Ltd, Vancouver, BC - Canada



[WHITEPAPER] Comparing VB Migration Partner with other conversion tools

clock February 6, 2009 02:15

As I have written many times in this blog, we at Code Architects love competition. We think it's the driving force in any market, and software is arguably the field in which fair competion is likely to provide better results than anywhere else.

If users have more products to choose from, vendors are put under pressure and are more likely to improve their products at a faster pace. This is what we are seeing today in the segment niche of VB6 conversion tools, which has been quite still for years, until VB Migration Partner made its debut.

With more choices, however, developers face the difficult task of selecting the right tool for their needs. Basically, if you are planning to migrate your VB6 app to VB.NET you have three choices:

  • Microsoft Upgrade Wizard (that comes free with all versions of Visual Studio .NET)
  • Artinsof VB Upgrade Companion (an extension of Upgrade Wizard, with which it shares the same migration engine and approach)
  • Code Architects VB Migration Partner (by yours truly...)

To make an informed choice you have to compare these products, which isn't as easy as it sounds because there are so many factors to take into account. To help you in taking a decision, we prepared a feature comparison table that explains which features are fully (or partially) supported by each tool, and why you should care.

Rather than providing a dry list of feature names, we attempt to categorize each feature based on how it can affect the overall migration process. In the end, we came up with five categories:

C: the feature reduces or avoids compilation errors.

R: the feature avoids runtime errors and preserves functional equivalence.

M: the feature generates code that is more readable and concise, abides by .NET programming guidelines, and makes maintenance easier.

O: the feature generates optimized and faster VB.NET code.

T: the feature can reduce overall migration time and cost, for example it eliminates the need to prepare the VB6 app for the migration. Features that reduce learning and support costs also fall in this category.

Each feature can fall in just one category or in multiple categories. For example, the support for Gosub, On...Goto, and On...Gosub keywords clearly falls in category C, whereas the ability to generate correct cleanup code for IDisposable objects (e.g. database connections) belongs to category R (preserves functional equivalence, M (generated code follows .NET coding guidelines), and O (application that cleanup resources in an orderly manner are also more efficient).

We are aware that comparing our own VB Migration Partner with its competion is a delicate matter, therefore we tried to be as unbiased as possible. In building the feature list we used product information available at our competitors' Web site, therefore the result is as objective as it can possibly be.

When we couldn't find enough details on a given feature, we used a question mark (?) and added the suggestion to contact the vendor for more detailed info. It goes without saying that we will quickly revise the document if any reader deems that an item is incorrect or just misleading.

Happy comparison! Wink



VB Migration Partner vs. manual porting from VB6

clock January 20, 2009 02:31

More and more VB6 and VB.NET developers are discovering VB Migration Partner and are realizing that it *is* possible to convert VB6 legacy apps in a fraction of the time (and money) that is required when following other approaches or using other tools. However, a casual visit to VB6/VB.NET forums shows that many false myths and misconceptions about migration are still strong.

For this reason, every now and then I like to partecipate to these discussion and throw in my own point of view. I think it makes sense to republish it here. The following text is adapted from a longer comment I posted toa thread entitled Conversion from VB6 to VB.NET 2005 on DevX Forums.


 

I believe that the confusion about automatic code translators raises because most people expect that they work magically without any human intervention. Alas, this is the approach used by the Upgrade Wizard inside VS and this explains why it performs so poorly. In most real-world cases you can't simply run the tool on a piece of contorted VB6 code and have fully working VB.NET code at the first attempt. Instead, a real-world migration process is an iterative task.

A code translator should migrate your code according to *your* personal style and preferences. VB Migration Partner allows this by means of so-called "migration pragmas", which are special remarks that you embed in the original VB6 code. For example, this pragma tells VBMP that special code must be emitted so that the VB.NET can correctly handle default members even in late-bound mode (which is one of the main limitations of Upgrade Wizard):
    '## project: DefaultMemberSupport True
VBMP supports 60+ different pragmas to automate virtually every adjustment that might be needed after an initial quick-and-dirty migration. Pragmas are essential because they allow you to repeat the migration many times and still keep the VB6 and VB.NET code in sync, even if the migration process takes months.

VB Migration Partner can handle many recurring migration issues quite nicely. In most cases it can do it without human assistance, in the worst case it requires that you add a pragma.

Quoting a previous forum comment: "If you are crazy enough to spend 3 months to make a conversion work with a loss of performance compare to the VB6 application, while a 2 months rewrite would do the job and give you something that easier to maintain, go ahead."

With small projects this approach can make sense, provided that you can afford the extra time/cost and that you have a team that is adequately skilled in both VB6 and VB.NET. One of our customers is tackling one "monster" app of about 15 million lines scattered nearly 1500+ VB6 projects; the customer has estimated that it would take about 20 years/man to rewrite it from scratch, which they can't afford. They also estimated that VB Migration Partner will cut cost and time-to-market by at least 70-75%, which made their choice obvious. [NOTE: it later became clear that the actual savings was closer to 85-90%. The migration should be completed in a few months.]

The real value of a good converter such as ours is that an individual developer (or a team) can handle the migration process even if they aren't expert in either the source or the target language. VB Migration Partner contains a huge database of "good programming" rules as well as "obscure bugs" that are unknown to most developers, including a few expert ones. Let me make one simple example:

    Dim buffer As String
    buffer = Space(256)
    ' GetSystemDirectory API returns # of chars in the result string
    buffer = Left(buffer, GetSystemDirectory(buffer, 256))

This code works well in VB6 but delivers bogus results when translated as-is to VB.NET. VB Migration Partner correctly points to the issue and its solution. The question is: How many VB developers are aware of this subtle difference between the two languages? You might object that this code isn't representative of good VB programming, yet there are tons of code like it out there, and most "human converter" aren't skilled enough to find and fix it. (Here I talk from personal experience: it took hours to track down the problem the first time we bumped into it.)

Let me make one more example. In VB6 the default parameter passing mechanism is ByRef, which means that most methods take a byref argument only because the original developer forgot to add an explicit ByVal keyword. The problem is, VB.NET should use ByVal whenever possible because this coding style prevents a lot of compile and runtime errors. (You can have problems when passing an ADODB object to a byref parameter, and there are many other similar cases)

A developer doing the port or the rewrite, therefore, should carefully check each byref parameter and see whether it can be converted into ByVal without changing the code behavior, but this task takes days on a real-world app, because you'd have to check whether *each* parameter is modified, or passed to a method that modifies it, and so on recursively. VB Migration Partner does it automatically in a matter of seconds, emits a warning, and can optionally convert the ByRef into ByVal for you.

The code analysis engine in VB Migration Partner can do many other interesting things. It can remove unused methods, Declare, and Const statements; replace Exit Function with Return, merge DIM and assignments (eg Dim x As Integer = 1), suggest when a StringBuilder object could replace a set of concatenations, and so forth. Once again, all refactoring actions are optional and can be controlled via pragmas. An average developer can surely perform these task manually, but in practice it happens quite seldom because he or she can hardly afford the extra time that these activities require.

I could continue with more examples of how an automatic code converter can do a better job than developers. Not in all cases, but in a large percentage at least. If you are interested, you can find all docs, KB articles, videos, and code samples at www.vbmigration.com. (We provide both the original VB6 code and the resulting VB.NET code.)

As far as I know, we are the only migration tool authors who dare to expose all this information to the public *before* they purchase the product. I hope potential customers or just programmers who are curious about conversion technology will appreciate this "transparency" policy.



[WHITE PAPER] 17 Reasons for using a support library in migration scenarios

clock December 31, 2008 07:04

Unlike the majority of the language conversion products available on the market – which mainly attempt to convert code from one language to another – VB Migration Partner both converts the code and uses a support library to decrease the gap between VB6 and VB.NET and to ensure that the converted code really behaves as expected. When combined with its superior code parser and generation engine, the support library becomes an essential factor in VB Migration Parter's superior performance and high success ratio.

Using a support library in a migrated project isn't different from, say, using a 3rd-pary ActiveX control or a .NET control in your code. VBers have used custom controls for years, even if their source code wasn't available or consisted of poorly documented C++ code. VB developers have used 3rd-party custom controls because they didn't want to reinvent the wheel, they didn't want to spend months just to build a powerful grid or chart control, and preferred to invest their time and money on developing the real application, not just the infrastructure.

A support library offers pretty much the same advantages: it allows you to cut the cost of the migration process and bring the migrated VB.NET to the market earlier. As a matter of fact, a support library provides at least 17 important benefits.

Interestingly, our competitors felt the urge to comment our approach, in the attempt to convince potential customers that a library is a very scary thing. Their arguments are a bit lame, though, if you consider that their tool uses a support library for specific tasks, except their library isn't as complete as ours.

The truth is quite different, of course: a rich support library provides so many advantages that it would be silly NOT to use it. The advantages are so many and so important that we wrote a detailed white paper to describe them. Read it, compare it with what our competitors opinion, and then decide for yourself.

Have a great new 2009! Cool



More on binary compatibility

clock December 20, 2008 06:11

A reader of a previous post on binary compatibility asked for clarification about my claim about VB Migration Partner being the the only conversion tool on the market offering this important feature, mentioning that at least another tool from our competitors also claim to offer this feature, which they obtain by adding ComVisible, ProgID, and ClassInterface attributes.

I am aware there is some margin for ambiguity and for uncorrect information, so I decided to drill a bit deeper on this topic.

You have binary compatibility between a COM component a .NET component if you can unregister the COM component and install the .NET component in its place, without having to recompile the COM clients that were using the COM component. We call it "binary compatibility" because it's the kind of compatibility we used to enforce under VB6, to ensure that a new version of a given component was perfectly compatible with its previous releases.

The ability to generate a VB.NET component that is binary-compatible with the original VB6 component is greatly useful, for many reasons:

  • You can migrate a complex N-tier application starting with its innermost DLLs, typically those that access the database, without having to recompile or modify in any way existing COM clients. 
  • The ability to convert only a subset of existing DLLs without being forced to migrate the entire application allows you to focus on those components that suffer most from the inherent scalability and performance limitations imposed by COM. This is the so-called phased migration.
  • Just as important, you can immediately debug the converted DLLs because you can use existing COM clients and their user interface - no need to write small throw-away .NET projects with the only purpose of testing the DLLs you just converted.
  • Finally, if your organization is very serious about testing, odds are that you have defined unit tests, use cases, and maybe scripts that rely on commercial testing tools. The great news is that, in most cases, binary compatibility allows you to test the converted DLLs using existing unit tests and scripts, thus saving you even more time.

As you see, binary compatibility can be a tremendous time-saver when migrating a VB6 application that is split in many DLLs, and it's no surprise that a migration tool vendor would like to claim that its product offers this feature.

Unfortunately for our competitors, to generate a .NET class that is binary-compatible with the original VB6 class you need much more than three attributes. You have to extract GUIDs from the original DLL and apply them correctly to the generated .NET class, you must handle fields, enums, types, events, and interfaces with special care, and you have to pay attention to many special cases and exceptions.

More precisely if you just add the ComVisible, ProgID, and ClassInterface attributes, the best you can get is compatibility with existing VBScript and ASP clients, not with compiled COM clients 

The bottom line: based on what I can read and what I heard from customers, I can only reinforce my claim that only VB Migration Partner offers true backward binary-compatibility with existing COM clients and fully supports phased migrations of N-tier VB6 apps.



Exploring version 1.10 - Gosubs Refactoring

clock October 13, 2008 09:02

If you read virtually all books and articles related to VB6 migration, you'll learn that VB.NET doesn't support the Gosub keyword, therefore you had to manually refactor your VB6 apps and turn those Gosubs into calls to separate method.

All these articles and books were clearly written before VB Migration Partner made its debut, because we have demonstrated that the inability to convert Gosub keywords to VB.NET was only a limitation of the conversion engine used by the Upgrade Wizard that comes with Visual Studion .NET.

In fact, since its early beta versions VB Migration Partner has always been able to handle Gosub keywords and its On...Gosub variant. Translating a Gosub keyword isn't at all difficult if you think that a Gosub/Return pair can be simulated by a Goto plus another Goto that brings execution back to the statement following the Gosub. It's a simple technique and I show how to implement it during my Tips, Tracks, and Techniques in Migrating VB6 Applications to .NET 75-minute speech. (BTW, if you are attending VSLive! in Las Vegas, don't miss this session... it's tomorrow at 11 am.) Actually, it's such a simple technique that I always wondered why Upgrade Wizard didn't implement it.

Rendering Gosub/Return by means of Goto pairs ensures full functional equivalence between the original VB6 code and the generated VB.NET code, but has one defect: it makes your code less readable than it should. For these reason, a few users asked for a better way of dealing with this VB6 syntax.

The obvious solution was to extract the code portion pointed to by the Gosub keyword into a separate method and replace the Gosub with a call to that external method. The code in the external method must be able to access some (or all) variables in the original code, therefore it is necessary to pass these variables as ByRef parameters to the external method. Finally, if the original method included an On Error Resume Next statement, this statement has to be present in the external method as well.

Implmenting all these features wasn't a breeze, but we managed to do it and we are very proud of the result. As far as we know, VB Migration Partner is the first and only VB conversion tool that has this feature

Enabling Gosub refactoring is as easy as adding a ConvertGosubs pragma. Like most pragmas, it can have project-, file-, and method-level scope, therefore you can decide where exactly it has to be applied. In most cases, the best approach is adding it to the master VBMigrationPartner.pragmas file, so that all your migration projects will use it. 

    '## project:ConvertGosubs True

(You can disable this feature inside a specific file or method by simply inserting another pragma with narrower scope and False in its argument.) Consider the following VB6 code:

Function GetValue(x As Integer, id As String) As Integer
    '## ConvertGosubs True
    On Error Resume Next
   
    Dim s As String, name As String
    s = "ABC"
   name = "Code Architects"
    GoSub BuildResult
    Exit Function

BuildResult:
    GetValue = x + Len(s) + Len(name)
    Return
End Function

VB Migration Partner detects that the code that begins at the BuildResult label (a.k.a. the target label) can be safely refactored to a separate method that receives four arguments. The result of the conversion is therefore:

    Public Function GetValue(ByRef x As Short, ByRef id As String) As Short
        Dim s As String
        Dim name As String
        On Error Resume Next

        s = "ABC"
        name = "Code Architects"
        Gosub_GetValue_BuildResult(x, GetValue, s, name)
        Exit Function
    End Function

    Private Sub Gosub_GetValue_BuildResult( _
            ByRef x As Short, ByRef GetValue As Short, _
            ByRef s As String, ByRef name As String)
        On Error Resume Next
        GetValue = x + Len6(s) + Len6(name)
    End Sub

Notice that the external method contains an On Error Resume Next statement, because the original GetValue method also contains this statement. Also notice that the ID parameter isn't passed as an argument to the external method because it isn't referenced by the code inside it.

All arguments to the new Gosub_GetValue_BuildResult method are passed by reference, so that the caller can receive any value that has been modified inside the method (as is the case with the GetValue parameter in previous example.) You can have VB Migration Partner optimize this passing mechanism and use ByVal if possible by passing True as the second argument to the ConvertGosubs pragma:

    '## ConvertGosubs True, True

If this optimization is used in the above code, the separate method is rendered as follows:

    Private Sub Gosub_GetValue_BuildResult( _
           ByVal x As Short, ByRef GetValue As Short, _
           ByVal s As String, ByVal name As String)
        On Error Resume Next
        GetValue = x + Len6(s) + Len6(name)
    End Sub

If you don’t like the name that VB Migration Partner assigns to the automatically-generated method, you can easily change it by means of a PostProcess pragma:

    '## PostProcess "Gosub_GetValue_BuildResult", "AssignValueResult"

It is important to keep in mind that the conversion of a Gosub block of code into a separate method isn’t always possible. More precisely, VB Migration Partner can perform this conversions only if all the following conditions are met:

a) The method doesn't contain any Resume statement. (On Error Resume Next is OK, though).
b) The target label isn't located inside a If, Select, For, Do, or Loop block.
c) The target label isn't referenced by a Goto, On Goto/Gosub, or On Error statement.
d) The target label must be preceded by a Goto, Return, End, Or Exit Sub/Function/Property statement.
e) The code block must terminate with an unconditional Return, or an End Sub/Function/Property statement.  (Blocks that terminate with Exit Sub/Function/Property statements aren't converted.)
f) The block of code between the target label and the closing Return/End statement doesn't contain another label.

If the conversion of a specific Gosub isn't possible, VB Migration Partner reverts to the default way of converting Gosub/Return (i.e. using Goto pairs).





Follow Francesco Balena on VB6 migration’s group on

LinkedIn


VB Migration Partner - Subscribe to our feed RSS  blog RSS
 
AddThis Feed Button
 
 

Home blog
 
AddThis Social Bookmark Button


 

Sign in

Search

Calendar

<<  September 2010  >>
SuMoTuWeThFrSa
2930311234
567891011
12131415161718
19202122232425
262728293012
3456789

Archive

Categories

 

Microsoft Regional Director
Microsoft is a registered trademark of Microsoft Corporation in the United States and other countries and is used under license from Microsoft
 

My Blogs


My programming tools



VB Migration Partner


VBMaximizer for VB6


Form Maximizer for .NET

 

My books


Programming Microsoft Visual Basic 6


Programming Microsoft Visual Basic 2005: The Language


Practical Guidelines and Best Practices for Microsoft Visual Basic .NET and Visual C# Developers