 On today's Visual Studio Toolbox, we're going to look at a tool called WebMap that you can use to take a desktop app and easily and quickly turn it into a web app. Hi, welcome to Visual Studio Toolbox. I'm your host, Robert Green, and joining me today are Didi Walsh and John Brown. Hey guys. Hey. I'm Didi. Hi John. I'm John. From mobilize.net, and we are going to talk about what do you do with your legacy line of business apps. Now, let's understand that legacy means that it works perfectly fine and it's running the business. Right. But you have these apps that have been built quite some time ago, that you're maintaining, and you have all this new stuff going on, containers and web and cloud, and you might want to modernize your applications in some form. That's basically what you guys do. Yeah. That's what we do because we're the old Visual Basic Visual Studio team from way back. Didi and I go way, way back. John's an old Microsofty, so we were at Microsoft for, between everyone in our company, we have about 100 years of Microsoft. So we're the team that got you into it, so now we'll help you get back out again. So with that, John will take over and talk through some of this. Yeah. So I got a little PowerPoint, and I got a little demo, and I call the PowerPoint saving the beaver, and it's not that beaver, it's not beaver cleaver, and it's also the idea of reversing entropy and legacy code, because entropy always moves forward in a closed system. Right. So what is this? This is a de Havilland beaver, and that's Ken Moore. You've probably flown on them I have. Yeah. They fly right across the water here. Okay. The de Havilland beaver was, they haven't been built since 1967. They built these aircraft from 1947 to 1967. They built over 1,000 of them. It's one of the 10 best products ever out of Canada, including hockey pucks and ice apparently. Okay. Not to mention snow, right? Yeah. That's the best product. The reason that they're still in operation was, they do exactly what they were designed for, which is short takeoff and landing operations. They're the world's greatest bush plane. Okay. But they've been modernized. Okay. And Ken Moore basically has this ongoing process of getting these planes from, militaries all over the world, modernizing them and flying them daily. Okay. Because they do exactly the right thing. Now, there was another aircraft I want to mention, which was the famous ME-163, the world's worst fighter jet. Okay. This was a last ditch attempt by Hitler to shoot down bombers flying over Germany and World War II. So he took a rocket engine and stuck it in this thing. They took some poor sucker and put him in the cockpit. The thing took off. It could only fly for three minutes before the engine ran out of gas. Okay. And then they had to glide back and try to land the thing. Okay. And the fuel was so combustible, if you spilled any on your leather flying jacket, you'd burst into flames. Okay. So, you know, the question is, is your legacy code of the Havilland Beaver or the world's worst fighter aircraft? Okay. And so, obviously, there's code out there, and we see it in our company every day, that's running applications, it's running businesses, it has, you know, it's been worked on for years, like the Beaver, but it needs to be modernized. Right. Okay. And also, you know, I was watching VS Toolbox and you had this great two-part thing about containers. Yep. And so, the question is, well, what about all that stuff? If your application, if your legacy application is a web app today and you're hosting it on your local data center, whatever, yeah, great. Move it to Azure, you know, refactor it, build microservices, all that stuff. It doesn't work for a desktop app. Right. You can't really take a desktop app and host it in the cloud. I have lots of people work at it, right? That's just a terrible solution. So, what we've got is a way with technology to move desktop apps from the desktop, okay, all the way to a really well-formed web application. Okay. And so, that's really what I thought I'd demo. Cool. All right. So, let's get out of my favorite software PowerPoint. Everybody's favorite. Everybody's favorite software. Thank you, Microsoft Office. This is something, brace yourself. Oh, my gosh. This is BB6, right? There it is. BB6, there it is. And, you know, it was well-beloved in its time, reviled by all of us on the C world. I built a few of those apps. Yeah, we did this, right? Okay. And if we run this guy, this is a little canonical ERP system that we created as a demo, as a demo testbed. And basically what it does is it's a fictitious seafood wholesaler called Salmon King Seafood. And here I can create an order. I can do a search on my database and look up customers, you know, based on a text field like a W. I can put in orders. And I look at this and we laugh and we shudder. Oh, that's so ancient. But there are a lot tons and tons of these apps actually still in use running the business. And do we get credit for not using Northwind traders? Right. So, you know, the things that are interesting about this, from going from desktop to web, there's a couple of things that are going on here. One is we've got a lot of data-bound controls, right? There's actually an access database behind this. Okay. And we've got this modal dialogue right here, which is so common in Windows desktop apps, you never see them in web apps because they're a nightmare, right? Because right now I suspended this execution to run on my laptop. Can't do that on a web server when you've got all these simultaneous sessions going on, right? So, we had to be able to map these things forward. Also, the look and feel, you know, the way that like if I hit tab, the focus moves, you know, so these are line of business apps. These are ones that are just hammering on every day by customers and by users. And you can't just take this and completely change it. You have to try and preserve the user experience so you don't have to retrain people. The training costs are some of the highest costs associated with this kind of stuff. So, let's ditch out of, oh, see it's modal, I got to get out of here. Let's ditch out of EV6 and hope we never have to look at that again. And now, let me, so what we're gonna do is, I have to see which version I'm in here. I wanna go to Visual Studio 2015. We have a tool, Robert Microsoft actually paid for it to get built 15 years ago, okay? And it's called. 20 years ago. 20 years ago, yeah. Okay, that's true, yeah. It's been around for what, no, 17 years, right? So, Tom Button, our beloved and fearless leader, indeed he found this company in Costa Rica and while he was still on Microsoft's side and they paid him to build this tool, it used to be part of Visual Studio, Visual Basic Upgrade Companion. So that lets you take that Visual Basic 6 and move it to .NET, okay? And so that's what I've done here with that very same application. It's boring to watch the process, okay? But you find all of your OCXs, you make sure they all work, you resolve all those issues. And then there's always gonna be things you have to fix, okay? Once you move it to C Sharp or VB.NET, right? You've got array, you know, indexes, you've got stuff like is empty that doesn't pass forward and things like that, right? But what we try to do with this one is, again, preserve the look and feel, right? Not have to have the developer try and understand everything new from scratch. You took the VB6 app and you converted it to a C Sharp WinForms app. Yep, uh-huh. So every VB form now has a C Sharp file and a designer file, okay? You can use the WYSIWYG, you know, Visual Studio Designer to update those controls and set properties on them, right? The business logic is all intact. We've preserved all the symbol names, all the object names, you know, all of the module names. We've preserved all the original comments. And now where there's places where there's some discrepancy between what VB6 could do syntactically or semantically and what C Sharp or .NET can do, we've generated an error message basically as a comment with a URL, okay? Click here for more information. And then we've done some things, you know, the trivial but they're sometimes important. Like instead of on error, go to try catch. Okay, things like that. All right, but this is still on the desktop. It still works the same way. And it could be VB.NET if customers want to stay with VB. So this is fine for some customers. They're still kept it to the desktop, right? But when you think about the number of people that want to use a non-Windows device, okay? Or they want to be able to access it from a variety of devices in a variety of different situations, or they want to reduce the deployment costs of dealing with actual executables that have to be installed. Okay, of course, Windows 10 will fix that at some point, right? But right now, you know, it can be a problem. So you can build it as a web app, okay? And that does a lot of great things because then it's ready to go up to the cloud. Right. It's ready to implement things like CI, CD, DevOps, all the coolness that you can get with those things. But it's got to be a well-formed web app, right? So now we run into these problems of, well, you go from a single user to multi-user, single session to multi-session, you've got network latency, you've got a very, very restricted sandbox for the UI inside the browser, right? That you have to work with. And you still want to be able to have code that the developer can understand. This may be, come to surprise you, some of our customers, developers and not the world's most cutting-edge guys if they're still working on VV6 apps. So when they see, you know, web apps with Angular and JSON and Ajax and, you know, UI frameworks and JavaScript and TypeScript and, you know, their heads explode, right? So we wanted to try and solve some of that complexity for them, okay? And I think that's what we've got. So what we have is a tool called WebMap, okay? And what WebMap does is it can read in WinForms C sharp.net source code. It uses AI to sort of churn it, okay? And what it's looking for is it's looking for patterns that it understands, okay? So a good example of that is let's say that you've got some SQL code, where you're doing some sort of a CRUD operation on SQL inside your code. There's basically two or three parts of that that are really standard, right? Where you're going to make a connection, you're going to do some sort of an operation and you're gonna have a result from that operation that's returned, right? But those three things may be separated by a lot of code, okay? So one of the things that the AI engine can do is go in and identify that pattern of, oh, A, B, C, boom. I know what to do with this on the backend, okay? So if we were to migrate this to WebMap, what would the code look like? What does that mean, migrate this to WebMap? Okay, so WebMap is the tool. It's like, VBUC is the tool that, you know, it's a one and done migration from VBC to. Is it an extension inside Visual Studio? Is it a standalone tool? Right now it's a standalone tool. Okay, running in Azure, okay, yeah. Yeah, yeah, runs in Azure, okay. The only version I have right now just has a command line interface, which is HIP again, so that's cool. Okay. But it's kind of boring to watch, you know. But it basically, it takes the code base, I point it to you like this is where all the code is. I say, here's the input, here's the output, creates a new directory, and so that would look like this. Let's look at a briefly canonical example real quick. So if we were to look at something that is a little easier to get our heads around than that application, here is a little hello world application, okay? And when we look at the, we look at the source code that's created. You notice there's a migrated solution basically, right? And there's a solution file on one level up. So if we go into this, what we'll see is a C-sharp file, right? Okay. A solution, we'll see a angular directory. And in the angular directory, we're gonna see all the things that we normally see. Okay. Okay, so let's go back to our bigger example here and let's start with the back end code, okay? So once again, we have a basically for every original form, okay? We have a C-sharp file, right? And if you look at the code, it doesn't look that different than WinForms code, okay? Even though this is actually running in ASP.NET Core, running a web server on the back end. And the nice thing about this is, is that because we've preserved all of this sort of familiar code pattern, the developer from, let's say from the WinForms version, can maintain this, they can read it, they'll understand it. Okay, they can fix bugs in it, right? Now, if we look inside the directory, we see this WWE root directory, okay? And that was generated by the front end. Okay. Okay, so let's see what that looks like. Right now, I'm gonna bring that up in Visual Studio Code because it's just a little friendlier to the sort of the world of Angular and web development, right? And once again, we can see over in our app directory, we have all of our components for all of our forms, okay? So each form gets its own folder and inside of there will be three files, TypeScript file that basically sets all the imports, defines the components, right? There's gonna be an HTML file and CSS file. So if we look at one of those, and I think that's the same guy here. So here's our TypeScript file and you can see that basically we're importing some web map type stuff, okay? There's some mobilized namespaces here. And this is where the magic happens because we've got these packages that are going to map a lot of the Angular stuff and the Kendo framework that we're using right now to build all the controls that we want. They're gonna map those over to HTML and CSS, okay? So if we look at, for example, the HTML file, even though we're using Angular 5 and we're using Kendo for Angular, right? You're not gonna see any references in here to those native controls, okay? So we've extracted all of that to our class definitions which map right back to those same namespaces and the source code, okay? The whole point of this is to make it simple, okay? Now, a lot of people would do this approach but they'd have a binary runtime that would basically sit between the operating system or the browser and the source code, okay? And there's nothing wrong with that approach except that it creates a dependency on the company that released the runtime to maintain it and extend it, okay? And we've seen some examples in the past where those companies abandoned that or they went out of business or something bad happened leaving the users who had already embraced that technology and sort of alerted, okay? So we're doing everything with basically source code, right? Now, the next question is, of course, is how are we able to have this sort of WinForms looking code here, okay? And make it actually into a web application, right? And so as you and I were talking a few minutes ago, we're using the .NET compiler framework, is that what it's called now? .NET compiler platform, aka Roslin, right? Which is Visual Studio 2017, right? And so Roslin supports this concept of weaving which is aspect-oriented programming, right? So you take these common concerns, you know, a real normal example of this is logging where every method you wanna be able to log something, right? But you don't wanna clutter up the code of every method with these calls to some sort of a logging class, right? So aspect-oriented programming lets you take those sorts of what's called cross-cutting concerns and put them somewhere else. And then the compiler figures out, you basically, you set an attribute and say, hey, this thing is, you know, this is a concern. So deal with this, you know, when you go to compile, right? Then the compiler can take that and take that attribute and inject code, okay? After, you know, you and I of the world have, you know, partied on it, right? Before it actually generates IL, okay? And so if you actually look in our source tree, what you're gonna see is inside the obj folder, all these C-sharp files that are super complicated to read because Roslin has injected all of this code. So it's injected code, for example, to listen to every object in the UI and understand if its state has been changed, okay? Has that object been dirty, right? It's got code injected in there that will take care of modal dialogue. So when that, you know, do you wanna save or cancel dialogue box comes up, right? We can still do that and I'll show it in just a second when I run the app. What we're doing is we're suspending all the state that led up to that point, okay? Very carefully and managing that so that when the user comes back and completes that action, it just runs seamlessly without interfering with anything else going on, okay? So that's how this works. So let's take a look at what happens if we hit go here. And we've got a little console that comes up right now that's just an internal tool for tracking. So it's gonna check all the packages, it's gonna build it. And what's cool also, we can do this for like PowerBuilder and if you wanna move off of PowerBuilder, we help you. Yeah, you remember PowerBuilder? And you know what? There's a lot of customers out there that use that. But this is a web app that purposefully has the same UI as the WinForms app, which basically has the same UI as the old VB6 apps. Again, these are line of business apps where customers, the users have been using these for years. So your training cost of how to use the app is minimal. And it should work the same way. If I type a WN, it's gonna do a data lookup, right? If I click on this fictitious company WAPEC, it's gonna populate this grid control down here. You know, selecting the quantities, gonna highlight it down here. Changing the quantity does a lookup and a calculation. If I say save it, ooh, there's a modal dialogue. Okay. Okay. And it is a modal dialogue. I can't do anything now until I do something with this dialogue, right? And the other thing that's cool about this is it's MDI. So I can come up here now and go like, oh, look, I got multiple documents in the frame, okay? And, you know, all of the usual sort of windows type data bound control stuff is working. Okay. We've done a lot of cool stuff behind the scenes that's completely invisible here to make sure the thing will run fast, okay? Because now you take something that was designed for, you know, a single user and you're gonna make how and a known number of users run it, right? So one of the things we do that our guys came up with that I thought was super clever is this second grid control right here, okay? Right now there's nothing in there. So we haven't actually instantiated the grid control in the UI, okay? We actually, it's just invisible so we don't even load it. As soon as something happens where I select and we're gonna load down here, then we build it. So we make the app less chatty, okay? The second thing is, is all these data bound controls, instead of using the classic AJAX JSON sort of pattern where we update the server side model, because this is MVVM obviously, right? We're using WebAPI. So we go right past all of that, go get the data from the struct where it's been loaded, okay? Bring it right back, okay? And save a lot of grief on both sides, okay? And since it's WebAPI, that endpoint could be, you know, right now it's just a RESTful endpoint in our code, but it could be a web server. It could be a web service. Where is the data? What did you do with that? Where is the data? Well, you know, it's out there in the clouds. Well, this application, again, we haven't, I didn't bother to like change it to SQL server. I've actually got the database, move the SQL server on the computer. But, you know, it's just a question of changing the connection string. Got it. Okay, so now you could take the database and I could put that in Azure. I could leave the web server on-prem, you know, in my data center. You could leave the SQL server on-prem too, right? You could leave the SQL server on-prem. This doesn't have to be cloud. It could be an internal web app. Talking to internal data. As a matter of fact, if you wanted, and we had a customer that wanted to do this, it could all be just running in localhost. Okay. Sure. Because why not, right? You know, like now you're not limited to what kind of device. I know I'm at Microsoft. I don't want to say that. I see a lot of MacBooks out there and you have them here on this desk from time to time. I've seen that, right? So, you know, you could just run the whole thing on localhost, right? Or you can run it, you know, on-prem. You can run it hybrid. You can run it all on the cloud, but you've got all these options. So, let's say I do this. Let's say I start from a Winform app. Let's skip the VB6 to .NET part. Yeah, yeah, please. That's been talked about. I've got an existing Winform app written in C-Sharp. I run it through the tool. It's now a web app with a bunch of code that looks familiar to me. And then a bunch of Angular and TypeScript and CSS that I haven't necessarily had the chance to learn yet. Yeah. I'm going to be building web apps. It's probably now a good time to start learning that, but that's a journey that I'm just starting now, right? How do I maintain this app? What if I need to make a change? Do I have to go back to the Winform app and then run the mapping tool again? Great question. Great question. So, I guess it's a two-part question. How do I make changes in both places because we're still potentially going to maintain this existing desktop app? We may be getting rid of it. We may be keeping it and extending it with the web version. Or if we are literally getting rid of the desktop app, and now I'm expected to continue working on this app that's now written in a bunch of stuff that I don't know yet. All right. Well, those are both great questions. Let's take the second one first. The scenario you just described where you maintain two parallel sets of source code, that is a rarity. We do have a very, very large customer in Brazil that need to do that with PowerBuilder. And they went to actually using this technology to Java Spring MVC on the back-end side. But normally, because this is normally not a transpiler, it's a one-and-done scenario, because there's a lot of fix ups and changes you have to make. From the desktop, if I were accessing my C drive, I can't do that in a web app very easily, because that's not accessible. So I have to go in and change that code. If I were accessing hardware, I'd have to change that code. So to have that all keep redoing that, that would be kind of complicated. Now, the first question is, well, how do you extend this? Do you have to know Angular and Ajax and JSON and TypeScript? Oh, God. No, because what we've done is we've made it so that using your WinForm skill set in effect, you can go in and say, OK, I'm going to add a control. Let's say it's a dropdown, and it's going to be data-bound. So it's going to go do a lookup based on some business rules, say on an event somewhere else. And now I want to be able to have a control button, a command button that does something. Well, you can't drag and drop yet, because we're still using the designer files that are XML. But we will have support for the drag and drop WYSIWYG designer. You can go in and basically party on the designer file using your familiar code, and just add those controls. You then go in and basically, in using C-sharp, just handle the events like you're used to handling them. And then over on the client side, you take the name of the control as you've done. You just add the HTML. You add the class and the CSS. And you're pretty much done. And we'll have a blog and a video on that in a couple of weeks. So people who want to come back to our website, mobilize.net, want to see how that's done. I'm going to build one of those as well. And then if you do get to the point where you know Angular and TypeScript and all that fairly well, you can go straight to those files. You can go to those file snapchanges. So let's say that you hire a web developer. They're not going to know this. They're going to go like, wait, this doesn't look like what I'm familiar with. Some of it does. They see your packages and your components and all that. But I want to do it my way. You can do that. The way we've designed our RESTful end points is we're building a GUID that attaches to them. So you're going to work a little around that. So maybe you build a new endpoint on the server. Maybe it's a microserver. Maybe it's a serverless function, an Azure function. And then you just go in and you write whatever UI code you want and handle it using normal thing. You may have people that say, well, you're using Kendo. I want to use a different control set. Sure, just take those libraries and bring them in and then use those components as well. Should work just perfectly. Cool. Cool, cool, cool. Good stuff. Get moves customers fast. Yes, you don't have to wait until you've learned all the web technology before you can build the app. You can do this. You've got a huge amount of plumbing code behind the scenes doing the mapping, which coincidentally is also the name of the product. Weird, huh? Thanks for that. You don't like to have one. You save all the good stuff, right? Because we don't break the business logic. We just move it forward and repurpose it, right? So that stuff that's been sorted out over all those years, we don't break that. We just keep it forward. So it's a fast way for people to get forward. So people can go to the site. There's a trial version of this. They can actually take an app and give it a shot and see what happens. And then it's a nice path forward if that's something you need to do. Yeah, as opposed to, so we've heard you talk a lot about the containers and virtualization, which are all great options. But this is the option for when you really do have a valuable app that you want to get. You really don't want the old stuff. So like the scenario where you want to keep the desktop, there are a lot of customers who really do want to adopt Azure fully and want to adopt the latest technologies and really ditch the old stuff. So this is the scenario where you can get rid of all of your old stuff. We just did a show with Nishinil. And we took a WPF app. And then originally this started out. You have your WPF app. You can cloud enable it. So I put the WCF service in the cloud, the data in the cloud, but keep the front end. And then what he did was he took that front end and made a Xamarin app out of it. But the idea there is you're not necessarily never again going to use the desktop app. You just like to be able to work with expenses on your phone in addition to doing the primary work in the desktop app. So that's kind of a companion app. Here, you're basically saying, we don't want to have to maintain this WinForm app anymore. We want to move to web, but we don't want to have to start from scratch and write the whole thing from scratch. And all that valuable business logic, which the customers we deal with, and a lot of Microsoft customers who have old stuff that they've been working on for years, and they've tuned it, and they're just kind of stuck. And so we can very quickly get them unstuck and on to the cloud and on to Azure. And actually, we can help them use GitHub and get open source. Like a lot of customers are now in block from using open source and all that kind of stuff. This is a web app, so we can run internally. It can run in a container. It can run in Azure. Yeah, yeah, exactly. All right. Cool. Good stuff. That's great stuff. Thanks for coming on and showing us that. We're always glad to see you, Robert. A day without Robert Green is a day without sunshine, so. Oh, stop. So I hope you enjoyed that. That's a really nice thing to look into if you're in this situation. Thanks for coming on the show. And we will see you next time on Visual Studio Toolbox. Thanks, man.