I am the host of ".NET Rocks!", an Internet audio talk show for .NET developers online at www.dotnetrocks.com and msdn.microsoft.com/dotnetrocks. My co-host Richard Campbell and I interview the movers and shakers in the .NET community. We have nearly 200 shows archived online, and we publish a new show every Tuesday morning. For more history of the show check out the May/June 2004 issue of CoDe Magazine, in which the first column appeared.
In Show #184 Richard and I talked to Jon Rauschenberger about his secrets for moving VB6 applications to .NET using a toolkit that he helped the Microsoft VB team develop.
Carl Franklin: So Jon, what are you working on and thinking about these days?
Jon Rauschenberger: Well, I am doing a bunch of things. [In] my role at Clarity I am kind of charged with thinking about technology and where should we invest in technologies to help our customers. And I am also running a couple of our projects, so I actually get to apply the stuff that we’re thinking about and seeing how it works in real world. One of the most interesting things we just wrapped up is a project for Microsoft with the interoperability layer between VB 6.0 and VB.NET that we’ve been working on with them for about the last two and half months.
Carl Franklin: Yeah, this is something that you don’t hear about a lot and that a lot of people desperately need to know how to do. Maybe not a lot of people, but there is really a good handful of people who are depending on this old legacy code. And the Interop story between VB 6.0 has never particularly been good if you are in VB 6.0 trying to access VB.NET.
Jon Rauschenberger: Yeah, and that’s what really what drove this effort we did with Microsoft. It was just looking at not only our customers, but all the companies out there that are still running big chunks of their business on VB 6.0 apps that work fine. They’re doing what they’re supposed to do-they’re enhancing them, fixing them, but those apps are running their business and it is a challenge to move them over, and we wanted to see if we [could] come up with a way to help out with some of that migration.
Carl Franklin: I am curious as to how you did it. I remember trying to expose some things to VB 6.0 through VB.NET and using VB 6.0 as the host and going the other way, it’s pretty simple. You’ve got an… ActiveX DLL and you get the IntelliSense and all that, and you have nice features on the .NET side, but going back the other way, you don’t have IntelliSense. And… if you want to pass a dataset to VB 6.0 for example, oh! my God, that’s a can of worms right there! I found I had to make type libraries for all of these assemblies in the .NET Framework and it just hit me all of sudden, “How come there isn’t just a great big type library for the .NET Framework, for everything?”
Jon Rauschenberger: Sure. So, the Interop story has always been pretty interesting for Microsoft. There [have] been some good points and there [have] been bad points, and you touched on the bunch of them. I mean, some of the Interop stuff does just kind of work nicely. You slap a COM interface on a nice simple VB.NET DLL, it references from VB 6.0, and as long as you’re not doing anything along the lines of passing datasets around, it works fairly well, it’s pretty easy. There were a couple of places though, where we just saw our customers struggling, us struggling, when we would try to work with it. You touched on one. Datasets and recordsets interoperability is pretty much non-existent and you have to hand code it. And the other big one though, we felt like it was pretty broadly applicable, was-“How do I take a visual thing, let’s say, and not try to tie it to a technology, but how do I take a visual piece of functionality that I have written in VB 6.0 or alternatively that I have written in VB.NET and make those two Interop nicely so that I can have one application, where one form is a VB 6.0 form and the other form is a VB.NET form, and let me, as a developer pick and choose, when if I am going to at all, when am I going to migrate a form over to the VB.NET or when am I going to write something new in VB.NET?” And if you ever try it, it’s interesting, I spoke at TechEd and I asked this question: “How many people have run a form based on VB 6.0 through the conversion wizard?” Pretty much everybody in the room, about 150 people, raised their hands and [then} I asked, “How many of you were delighted with the results you got?” One guy left his hand up. I don’t what kind of luck he had, but he was happy with what he got.
Carl Franklin: He probably works at Microsoft.
Jon Rauschenberger: It could be, yes. He did have a blue shirt on, may be, but…
Richard Campbell: Now, I find it interesting that you’re talking about forms because when you first talked about companies still running VB 6.0 code, I am thinking COM DLLs that they’re not ready to give up on yet. They’re too complicated. They got too much code in them. You’re actually talking about forms and clients, they’re written in VB 6.0. They’re not ready to give up that yet either.
Jon Rauschenberger: Yeah, it is both. I mean, there certainly is a ton of code out there that’s better than COM DLLs written in VB 6.0 that people need to carry forward and continue using. We looked at that, though you know, with the exception of some data type problems-there are some workable solutions for that.
Richard Campbell: So, the Interop story is not that bad.
Jon Rauschenberger: It’s not that bad until you get some of the data-type problems. Recordsets and datasets being the biggest one. There are a handful of others but for the most part, if you wrote your COM DLL in VB6, .NET is going to be able to consume it fine.
Carl Franklin: Yeah, that’s not the issue.
Jon Rauschenberger: If you flip it around-you write something in .NET, you are exposing, you know, a System.Drawing.Point or some other data type that VB6 has no clue what to do with, then you can get into problems. But, you know, the other way around we’ve got plenty of customers that have built VB .NET or ASP.NET apps that use their old VB6 COM DLLs without having to convert them over. Alternately when you talk about the code conversion story, honestly it’s not that bad if you run a non-Visual DLL through. And with the recordset disclaimer; but if you have got a COM DLL that you wrote in VB.NET that has no UI elements to it, you run it through the conversion tool, and you are 95% of the way there.
Carl Franklin: So as long as you use the primitive data types, I mean, if you use convertible data types, blittable I guess you call them. Right?
Jon Rauschenberger: Yes. You know, the data type restrictions are always there. You know, there is something I think Microsoft can do to make it easier but at least you had a path, you had resources out there to say, “If you are using these data types here’s some things you can do.” You know, there was some guidance. Where we really saw a void was, I got a form that I wrote in VB .NET, “How the hell can I consume that or use that from my VB6 App?” and really there was just a void of guidance to us-just kind of nothing. So… we had a customer who had a large VB6 app, had a hundred forms or so-built it up over about five years. I don’t know the exact number or line count but it was definitely in the 10’s of 1000’s of lines of code; really heavy forms. You know, it was a stock real-time trading application. And they wanted to really build on this app… but they weren’t comfortable doing it in VB6, given the technology road map there, but they also knew it and we helped them out. We took a look [and asked], “What if we convert this thing to VB.NET?” We actually went through the exercises; we ran the project through the conversion tool. We had about four or five developers spend three weeks, just trying to get the VB.NET solution to compile-forget about run, we just want it to build. We got it to build and you’d bring up forms and there would be these goofy controls all over the place, nothing looked quite right. At that point we realized this isn’t going to work. So, we [thought], “Okay, what if we just manually convert the code. We will just go to VB .NET, we will create new forms, and we will manually port that all over.” And we came up with an estimate of about 18 calendar months for a team of about 10 people get this big application converted over.
Carl Franklin: I got to ask you, Jon, was this application the typical old school VB application where all the code was behind the buttons, or was it well separated?
Jon Rauschenberger: I would call it a hybrid. I mean, there were non-visual business objects that encapsulated most or at least a decent percentage of the, you know, the business logic of placing an order or cancelling an order, that sort of thing. But there certainly was a lot of, what I think anybody would characterize as business rules and application logic embedded in those forms. Sometimes for good reasons, sometimes for bad reasons but it was probably pretty close to the typical, you know, VB6-a good but not perfect app that was built by some good solid VB6 [developers].
Carl Franklin: They gave it the old try but sometimes they didn’t follow the rules.
Jon Rauschenberger: Yeah.
Carl Franklin: With an app with that kind of legs, you bet, it went through a lot of different hands of varying skill and skills that evolved and rarely does the real code get cleaned up.
Jon Rauschenberger: I was having some fun just reading through the code. I’ve been working with this client for a long time and it was kind of like a walk down memory lane of all the developers who we have worked with over the years. They’d all made their little contributions to the app and they are still in there.
Carl Franklin: So, you’ve obviously got a process now for dealing with this. I guess that’s what we really want to hear.
Jon Rauschenberger: Yeah. [So, the product] we helped Microsoft work on came out of this and essentially what we wanted to do. We [had] 150 forms [and] we wanted to pick 25 of them and convert those over to VB.NET and then release a new version of the application and then do another 25 and another 25. And the business was okay with 18 to 24 months of conversion process. They just weren’t okay with getting nothing during that time [such as] no new releases in there. We came up with an architecture in .NET, VB.NET, [where] we could create forms, you know, [and] we would create business objects where we needed to. We actually ran the old VB6 business objects through the code conversion tool and they came through pretty clean and we compiled that into, you know, a managed DLL. We put a COM interface on top of [that DLL] and then we put a little bit of code in VB 6.0 saying when the user clicks on, lets just say the new order button, we made a message call on this COM DLL within the VB 6.0 world that’s going to pop up a form which happens to be a VB.NET form. And now in the VB 6.0 process, we are hosting the .NET Framework in a common language runtime and we are side-by-side showing one form as the VB 6.0 form and one form as a VB.NET form. And what we are able to do, using that architecture, was take this application and over a span of about 6 releases, get the entire application ported over. Took us a little bit longer, so it took about 2 years instead of 18 months but we did 6 releases on that. And in the end, we kind of felt like, you know, “This feels like something that isn’t probably unique to this customer.”
So, we took it to the VB team and this is one of the things I love about the VB team. We said, “Hey! Look, this is what we did; we’ve got a good relationship with [this client]. Is this something you think [Microsoft] would be interested in making easier to do so that other people could take it and apply it [to] their needs?” Out of that came about a two and a half month project where we built a little tool kit-it’s going to be available as a free download sometime this summer. I don’t have an exact date yet but in the next 6-8 weeks I would guess. [This toolkit] basically streamlines the process of creating a form in VB.NET-clicking a button, building your solution and now you have got a form that you can very easily pull into your VB 6.0 application just by adding a reference to a COM object and programming against what looks and feels like a VB 6.0 form but under the covers there is an Interop layer that’s mapping those COM calls to the appropriate .NET objects; shelling the right forms. And [it] even allows you to do things like raise events, so when a user clicks on the button in your VB.NET form, you can raise the event back over to VB 6.0 and you can handle that event and it shows properties. We even went so far as to allow some concepts that don’t apply to VB 6.0, like overloading constructors, to be offered in VB.NET and then through our mapping layer we turn that into initializers on the VB 6.0 side so you end up with an initialized method-which is kind of pretty common VB 6.0 if you want to initialize something.
Carl Franklin: What I like about this is that it isn’t like typical transitional kind of conversion wizards because the goal is not to have something that you are going to use forever. The goal is to have something that compiles, something that works, something that will get you to the next release when, maybe, the code will be replaced by 100% managed.
Jon Rauschenberger: Yeah, that actually was probably our number one design goal. The people writing code in VB.NET didn’t know they were writing a form that was going to be hosted in VB 6.0. So we didn’t want you to be constrained in terms of how you are going to design your form because this Interopping was going to happen. For that very reason when you are done with the Interop, if you ever do finish-say two years from now, you don’t have the Interop anymore, we didn’t want all this Interop goo, you know, sprinkled throughout your code that we talked about earlier-you’d never get cleaned up. Ten years from now, people would be looking at it and thinking, “What did we do that for?” So, we really try to keep a nice clean separation. You write that code, use a little toolkit we have-a Visual Studio add-in-that will generate the appropriate COM interface code for you and you don’t have to worry about any of that.
Carl Franklin: That’s great! Very very cool. So, you are looking at what-the end of the year before this comes out? Oh no, you said 6-8 weeks.
Jon Rauschenberger: Yeah, it’s going to be available as a free download from the MSDN site and the download includes the Visual Studio add-in. It includes a little helper class that we use for some of the Interop stuff. Two sample applications, the “Hello World”-style app and then a larger, sort of full-blown line of business application using Interop and then a bunch of documentation. And the other cool thing is that, at least as of right now, the plan is to release, if you need it, the source code for all this stuff. So, if you want to go in and tweak and change it around a little bit, that source code will be there. Our goal, though, is that no one needs to do that.
Carl Franklin: Is there a project name, like a nickname for the project?
Jon Rauschenberger: Yeah, it’s currently referred to as the “Interop Form Toolkit” and that is sort of a, working name. So, it may change but it will be something along those lines. And we do want to focus [on] solving one problem, which is, “How do I take a form written in VB.NET and host it in a VB 6.0 application as part of the migration path?” There is nothing in the toolkit that helps you convert your non-visual DLLs. There’s nothing that helps you to direct at dataset problems. We wanted to focus on, “lets solve one problem and solve it well and let other people and other groups worry about providing some guidance around the other pieces.”
Carl Franklin: So, given that you have all this experience doing this conversion, let me ask you-what was, other than the Interop stuff-what was the most challenging thing that you had to come up against when you did this conversion?
Jon Rauschenberger: The data type problem was a bit constraining and that kind of carries forward into the toolkit. You need to be conscious of what data types you can marshal across the Interop boundaries and which ones you can't. And then the other piece-the two different forms engines. The VB 6.0 “Ruby” forms engines and the VB .NET WinForms engine, they do behave just a little bit differently. So, for example, in some instances where VB 6.0 fires a MouseDown event, VB .NET fires a button’s Click event. And if you are a developer, just going back and forth, its kind of like jumping back and forth between C# and VB .NET, for example, that mental shift-you have to jump through when you go from one to the other. It’s a bit of a challenge.
Carl Franklin: What about the graphics stuff? I mean, I know there are some things that VB 6.0 applications relied heavily on the Windows API to do-things that VB couldn’t do. I know that there are some things that you can do in the API that you can’t do in .NET. I think, scrolling is one-like ScrollDC is one. If I can remember correctly, FindWindow, the FindWindow API-there is no equivalent in the .NET Framework for that.
Jon Rauschenberger: Right.
Carl Franklin: So, did you ever come across those things too where you had to just, totally, throw a monkey wrench in the architecture and you had to redesign.
Jon Rauschenberger: You know, actually this was something I never thought I would do, but the FindWindow is a good example where we needed to do that; at least when our app was in hybrid mode. We need to find a Window and we didn’t have great support and in VB 6.0, it was so easy. What we actually did was just create a VB 6.0 COM DLL, call the function, and then we’d call it in VB.NET actually.
Carl Franklin: There you go.
Jon Rauschenberger: Most of the time our Interop was going the other way, where we wanted to do something that was easier in VB .NET and whether it was graphics or anything else-bonding threads or calling Web services and you know, that sort of thing. But that one instance, we did go back the other way. That’s actually [where] I think Microsoft has changed their tone a little bit here. That’s where I get excited about Interop. Its like, you pick the right tool for the job, build an application-you just don’t care which language or technology you are using. And if we can smooth out some of these Interop road bumps, I think, it would become a much more thought-about architecture to say, “Let’s create an app that’s partially VB 6.0, partially VB.NET, partially C++ if we need to.”
The conversation continues online at http://dotnetrocks.com/default.aspx?showID=187