Deploying Contemporary Applications with ClickOnce
Visual Basic 6.0
Visual Basic 2005
Visual Basic 2005 Express Edition
Summary: This article looks at ClickOnce deployment from the perspective of a Visual Basic 6.0 developer, and compares it to Visual Basic 6.0 deployment methods. (13 printed pages)
The Package and Deployment Wizard
.NET Deployment Options
Visual Basic was designed as a desktop, not enterprise, development language. If you will step with me into the Great Train to Yesteryear, you'll remember that the TSO and mainframe computers—running COBOL programs and CICS screens against DB2 databases, largely—were the norm when Visual Basic was starting to take ownership of the desktop. The enterprise had no need for the PC back then.
Today, in this world of scalability, the PC is the only way to do business. We have them on our desks, we carry them on trips, and we even use PCs with an attitude as servers. This enterprise architecture brings flexibility. It's what everyone wants.
What this means, though, is that a programming language that was designed to write desktop applications is now one of the most popular languages for writing middle-tier enterprise software. As a language, Visual Basic isn't too bad at that—it's quick, readable, and designed to manage information. As enterprise architecture, though, it has a lot to be desired; Visual Basic just wasn't designed to be used that way.
Visual Basic in the .NET era is designed from the ground up to support internetworking as part of the language. Visual Basic 2005 is designed from the ground up to support internetworking as a deployment platform.
In the old days, applications were monolithic, or self-contained. All of the program code was in one big executable file. The problem was that you couldn't share program logic—a massive waste of space, time, and effort.
In early Windows, Microsoft introduced something called Dynamic Linking, which allowed code modules to be shared by applications. Code modules—or libraries—that can be shared this way are called Dynamic Link Libraries, or DLLs.
COM, or Component Object Model (the name for this idea) deployment is hard, because DLLs have to be in the registry. Because COM DLLs are name-based, only one version at a time can be hanging around. If you reinstall an older version of a common DLL, you can break your entire Windows installation. If you try to install a common DLL that is in use, your package may stop. There are a lot of problems with this system the way it was under COM.
So Visual Basic 6 is a COM development environment. The "DLL Hell" problem follows Visual Basic 6 wherever it goes—whether to Windows or to the Web. No matter how you deploy your applications, you face these problems without exerting significant control. The built-in tool to exert that control is the Package and Deployment Wizard (PDW).
The Package and Deployment Wizard
Two deployment options are offered in the Visual Studio tool called the Package and Deployment Wizard. The PDW offers the ability to package the project up into an installer, and then to make an Internet deployment project out of it and deploy it from a Web server.
Package deployment for COM projects is fairly well known. The installer extracts the program file and related controls, puts them where they belong, and then uses regsvr32 to register them in the registry.
Deployment of this file is the problem, especially when you have to install your mail management project in 1800 stores. You don't want to have to send your techs to each store. A possible solution is to post the installation package on the Web server. The PDW handles this as well.
Problems surface, though. The Web server needs to have the Visual Studio Server Package. There is no facility for the software to be easily updated. Most importantly, we still deal with "DLL Hell," as well as the possibility that our little mail management application could break a client machine if it happened to have an up-to-date Outlook already installed, for instance.
To really demonstrate this, one needs to take a walk through the process of deploying a Visual Basic 6 application by using IIS. After compiling, the Package and Deployment Wizard is run from the Visual Studio tools directory, and the project is selected.
After selecting a Standard setup, you have the option to handle items without dependency information (see Figure 1). This is a common problem in COM applications, because you can't directly interrogate the structure of the library like you can a .NET component.
Figure 1. Handling missing dependency information
All of the files that will be included in the package are listed for your approval, and you have the option to change them. Then, you can break your install into floppy disk–sized chunks. If that doesn't date this program, nothing will. I don't think I even own any floppy disks anymore.
After naming the install package, you can set up the Start menus by using a dialog box. Then, you have the option to change all of the file locations for the package (see Figure 2).
Figure 2. Modifying file locations for the install package
Finally, you are asked to set up shared files. Remember the last time you uninstalled a COM application in Windows 98 (for example), and it mentioned that there are files that might be no longer used, and that you should be able to remove them without harm? Then, of course, when you removed them, your Office installation and twelve other applications stopped working? That's because the developer has the choice as to which components are "shared."
Congratulations: you have a setup project. Now you have to get it to the client. The next button on the PDW is Deploy (see Figure 3). That is where we are going next.
Figure 3. The Package and Deployment Wizard
To deploy, you need to have a Web server available with the Microsoft Posting Acceptor 2.0 available, which essentially cuts out any public production web servers. Then, you select the files in the package that you want to deploy, any additional files, and finally, you select the destination URL and deploy.
Wise makes a great package to deploy COM-based applications. A number of other Microsoft partners do the same. But it has the same essential three problems. It is difficult to divorce yourself from the basic problems until you move to the non-registered components of the .NET world.
.NET Deployment Options
In the world of .NET, we have several real deployment wins:
- DLL files are not stored wherever the developer puts them, and then referenced in the registry. They are stored in one place.
- All library files are versioned.
- The .NET runtime itself is versioned.
- Applications can be deployed without any registered components at all.
This leaves us with all kinds of options, as you can imagine. Since an application can be deployed and run without Admin rights on the client, you as the developer have a wide net that you can cast:
- You have the option just to copy the application to the client, using drag-and-drop or XCopy.
- You can deploy using another application, such as a Web browser.
- You can go the traditional Setup/CAB route.
The choice is yours, so let's look at a few options.
Imagine for one second that you are the enterprise architect for a retail shopping concern, and that you have the deployment of 1800 stores to manage. You could write a sophisticated piece of software that runs MSIs for you on a set schedule, or you could use one of the Microsoft enterprise management suites.
If you are working in .NET, however, you have another option: XCopy. For those of you who don't remember the DOS days, XCopy is what happens when you drag a collection of files from one folder to another. That's basically all you have to do to deploy a .NET application—move it to the client machine.
Let's look at an example. I put together a quick "Hello World" Windows forms application, using Visual Studio .NET 2005. It's just a form with a splash page that does something frameworkish (is that a word?)—in this case, listing the files in the root of the C: drive. It compiles into a single executable, but even if it didn't, this would still work. To deploy to a store, all I have to do is enter the following command.
xcopy "\\deployment\fileList\*.*" "\\mystore\program files\fileList\" /S /Q /Y
With Monad, or another shell or scripting language, I can easily write a script to connect to a store, XCopy the executable, disconnect, and then go to the next store. A 20-hour deployment project just turned into a 90-minute deployment project.
Building an MSI in Visual Studio 2005 is different from using the PDW. The setup is actually a project in the solution where the project in question resides. At first blush, this seems confusing and difficult. You will find that it is powerful and simple.
- Add a new Setup project to the Windows project:
- To get started with a Setup project, the output of your project needs to be added to the Application Folder. This will place the files that your application needs in order to run—no matter how complex—in the only place that is needed. It is pretty slick.
- In the left pane, right-click Application Folder, point to Add, and click Project Output.
- Select your project's Primary Output.
- Right-click the new Setup project and click Build. Your original project and any dependencies will compile, and then the Setup project will compile.
When you go look in the Bin directory of the Setup project, you will find a Setup.exe and an MSI. The setup is generic—it helps ensure installation of the 2.0 .NET Framework and the like. The MSI is specific to your project. There might be one or more CAB files with additional resources. That's it—it's a simple process.
Where it gets cool is in the options. Along the top of the Solution Explorer are six buttons with great options that I am not going to explain in detail. The documentation on them is quite good.
- File System Editor—The screen we just edited.
- Registry Editor—Just in case we have a COM component or two.
- File Types Editor—If you need to associate a file extension with your program.
- User Interface Editor—To change the forms in the Setup Wizard.
- Custom Actions Editor—Any functionality that isn't above.
- Launch Conditions Editor—All the if–then logic for your Setup project.
The message here is that a Setup project in Visual Studio 2005 can be as simple or as complex as you wish. It's when it comes to deployment, though, that the message gets really cool.
Since we have the opportunity to install on a client PC without registering DLLs, we have some interesting possibilities. If we agree to play within a security sandbox, we can deploy over the Internet, and keep the software up-to-date without much interaction from the user.
ClickOnce doesn't require an installer. Starting back at our original File List project, open the My Project file from Solution Explorer. You will find a Publish tab with all of the requirements for ClickOnce (see Figure 5).
Figure 5. The Publish tab
What do you need in order to publish your application using ClickOnce? Most importantly, you need an IIS Server—there must be someplace to host the compiled application You also need an understanding of what it means to have your application distributed in a sandbox—and we will cover that in a minute.
To get started, you can accept the defaults and click Publish Wizard.
First, you are asked to confirm your publish location (see Figure 6).
Figure 6. Confirming the application's publish location
If you have a local IIS server, you can accept that default item. If not, there are other options, as shown in Figure 6:
- A local file path
- A UNC file path
- An FTP Server
Next, you specify whether the application will be available online and offline, or whether it will be available online only (see Figure 7).
Figure 7. Setting the application's offline availability
If you take the first option in Figure 7, the application will behave more like a traditional program. If you choose the second, it will act more like an ActiveX control. The better news, though, is that this is the last step. Once you click Next, your application is confirmed and published.
Navigate to the URL that you have set up, and you will get access to the application (see Figure 8).
Figure 8. Accessing the application
Click Install, and Internet Explorer will validate the security situation and install the software (see Figure 9).
Figure 9. Installing the software
After this step, the security piece I mentioned comes into play. If your code base isn't signed, the application will have a much smaller sandbox (see Figure 10).
Figure 10. Security warning of an unsigned code base
The security analysis of this ClickOnce software is pretty complete. Code signing should be contemplated by anyone using ClickOnce. In fact, Visual Studio will make a key file for you so that you can get past the signing requirement, but since it is untrusted, the user will get errors (see Figure 11).
Figure 11. Examples of errors resulting from untrusted application
I advise that you invest in code signing if you are going to use ClickOnce. There is a lot of information on the MSDN website.
So, it officially takes more steps to install a ClickOnce application than it does to create one! After I agree to the install (by clicking Install), the application runs—with pretty complete trust, considering that I needed access to the C: drive (see Figure 12).
Figure 12. File list
The sandbox has a significant impact on the running of an application. Generally speaking:
- If you "Run from Web" or "Install from Web," the application will run as if it is in the Internet zone, just like an ActiveX control.
- If you "Install from Network," the application will run as if it is in the Intranet Zone.
- If you install from a CD or the local drive, you get full trust.
To update the application after changes, just use the Publish Now button. The version will be changed, and all the clients running the application from the Web will get the new version automatically.
The take-home here is rather obvious, but it is always good to have talking points, right? (See Table 1)
Table 1. Comparison of Visual Basic 6 and Visual Basic 2005 deployment methods
|Visual Basic 6 Package and Deployment Wizard||Visual Basic 2005 Deployment|
|Registers components for you.||The fact that you don't have to register components in a pure .NET application is an obvious, marked improvement, and it opens up all kinds of deployment doors.|
|Creates a Setup project.||Even just copying the files from your Project Folder to the client is an effective deployment mechanism using .NET.|
|Is a stand-alone tool.||A Setup and Deployment project offers a ton of flexible functionality that isn't offered at all by the Package and Deployment Wizard.|
|Creates a setup script.||Keeping the setup in a solution brings a lot of benefits, such as source control, developer responsibility, and project clarity.|
|Deploys packages to IIS.||ClickOnce provides very comprehensive, rather platform-neutral deployment options, including hands-off install or local install.|
It's tough for Visual Basic to compete on an even keel, because of two main points—the registry problem, and the breadth of options for .NET applications. On the other hand, Microsoft has had a lot of time to get things right.
On that topic, I should address another reality of deployment with Visual Basic 6. We have been doing it for a really, really long time, and we have existing processes in place. They do exactly what we need. Suddenly, when we go to see whether .NET Setup and Deployment projects do the same thing, we discover that they don't.
Two things come to mind. First, many of the existing processes out there use third-party products. You can do that in .NET, too—Wise 9.0 is a great installer for .NET that takes advantage of the new features but provides some of the functionality you are used to. Second, some of the features that you might be used to in your existing process might not be needed when deploying .NET applications. Keep an open mind when revising your deployment processes.
I hope that I have energized you to review and consider the baked-in options for .NET deployment. There are a lot of neat possibilities out there, and it is easy to overlook them. Take a bit of time to go over the features. I think you'll be impressed.