This is another highly technical post, so I apologise to those readers with no interest in programming.
This week I have continued the ghastly process of migrating the 27,000 lines of code that make up QuickLatin from Visual Basic 6 to VB.Net 2008.
I found that the “Upgrade Wizard” for VB6 was no longer included in versions of Visual Studio later than 2008. So I don’t really get a choice on which version of dotNet to use. That said, I have found that it works quite well, so long as you approach the problem in the right way. You will, in fact, have to adopt this approach whatever tool you use.
The first thing is to place the existing code under source control. You will need to change this code a lot, to make it fit to convert. Sometimes you will get it wrong, and need to revert back to the last checked-in version. Believe me, you will! I checked in code after each small set of changes. It was the only way.
You see, the key to converting a VB6 application to VB.Net is to keep the application working at all times. Don’t simply launch the upgrade wizard and then end up with 50,000 errors in the VB.net version, and then start at one end to fix them all. You will just give up!
Instead, make changes to the VB6 version of the code. Make small changes, check it works, check in the change. Then do another; and another.
We all know the sort of things that don’t get converted OK:
- Fixed strings in user-defined types (UDTs). So code these out. Convert them to non-fixed strings, a little at a time. Of course you created them in order to do Win32 API calls? Well, they won’t convert, and you will have to recode this stuff by hand. So, do a little recode in VB6.
- API calls, i.e. stuff that you added in to do more hairy stuff. Recode to remove them. You may end up just commenting the contents of the functions out. I have stuff that does a splash screen. I don’t need that code in VB.Net, which has a built-in SplashScreen template. So with other things.
- Front-end forms stuff. No need for splitters – VB.NET has its own SplitterContainer.
There are many more. Some are listed in a Microsoft document “Preparing Your Visual Basic 6.0 Applications for the Upgrade to Visual Basic.NET” (no doubt this link will fail in a couple of years, thanks to Microsoft’s idiotic policy of moving files around on their website). If you page down past the general chit-chat, at the bottom is a list of stuff that won’t convert. Fix these.
If you do this, you can eliminate most of the rubbish, while keeping most of your code still working.
Once you have done this, then do a test of the Upgrade Wizard. Expect to throw it away; but it will give you a list of failures to address in VB6.
Once I did this, I ended up with some 37 errors in VB.Net. That was a tiny number! Most of these I fixed in VB6, and reran the Upgrade Wizard several times. By the end my VB6 application was rather damaged, and much of the UI didn’t really work. But the logic engine was still running just fine.
A few things just won’t convert. But you can fix a few on the other side.
Once your VB.Net application compiles, you can try and run it. It will fail, of course. This bit is just slog. You find out what is wrong, and then consider if you can code it out in VB6 and re-upgrade. Often you can.
QuickLatin has a lot of file-handling. VB6 was slow in reading files, so I created a .DLL written in Visual C++, purely to grab a file and squirt it into an area of memory mapped to an array of UDTs. Needless to say this did not convert to dotNet! So what I did was write a slow version, in raw VB6, which did the same thing. I unpicked the optimisation, knowing that I could reoptimise on the other side of the upgrade process.
I ended up recompiling the DLL. I’m not sure when I wrote that, but it was probably in Visual Studio 6. It produced a DLL which was around 80k in size. The version of the same code, produced by Visual C++ 2008, was 107kb. It did exactly the same; but Microsoft’s lazy compiler developers had bloated it by 25%. Microsoft was always notorious for code bloat. I remember that when IBM took over the source code for OS/2, they were horrified at how flabby it all was, and rewrote most of it in assembler.
However I couldn’t get the DLL to work in VB.Net, whatever I did. So… I eliminated it and accepted the slower load, for now.
I’ve now reached the stage where the code runs, but it isn’t doing it right. This is not unexpected. The change from arrays based on 1 to arrays based on 0 was always likely to break something. But it’s an opportunity to make use of a VB.Net feature, and create unit tests! I have started to do this, not without pain.
Of course even VB.NET 2008 is now more than a decade old. At that time the idea of loose coupling and dependency injection was only just coming in. I gather that even today Visual Studio 2019 doesn’t really support this all that well. To a professional Java developer like myself, the idea that the DI equivalent of Spring isn’t even on the mental horizon of Microsoft staff is extraordinary. I’ll manage somehow; but why can’t I just annotate my classes in dotNet, as I do in Java? Why?
In the course of today, it has become clear to me that Microsoft’s developers never used VB6 themselves, nor do they use VB.Net. If they had, they would never have created this huge roadblock to upgrading VB6. There is still a huge amount of VB6 out there in corporations. But Microsoft’s staff couldn’t care less. Indeed there always was a lot of it about, which is one reason that I found it expedient to learn some, all those years ago. Job security consists of having the skills that people want, even if they don’t want to see them on your CV.
Had Microsoft’s developers ever used VB6 internally, they would have collared the VB.Net team and given them a straight talking-to.
Likewise anybody who does the upgrade immediately finds that he can’t do a lot without massive refactoring. Again, this shows that nobody at Microsoft actually ever went through this process. Because you don’t want to do a load of refactoring. You have no tests. You might break stuff. You can’t easily create tests either for code in Modules, rather than classes.
Microsoft was founded by Bill Gates, who owed his start to writing a Basic Interpreter for some of the early microprocessors. So Basic was important to him. It seems that in later years it wasn’t important to anyone else. This is a shame.
Microsoft was very arrogant in the 90s and early 2000s. Few were sorry when Google knocked them off their perch.
Oh well. Onwards. Thank heavens I have lots of time right now, tho!