Happy, Happy, Joy, Joy!  Now I've Got My Auto Deploy!

By Anthony Hart


One of the exciting things about the .NET revolution is Microsoft's apparent attempts to combine the power of Windows programming with the flexibility and reach of Internet programming.  I see this as a very positive effort that has the potential of changing (for the better) many of the programming paradigms that have developed over the past several years.  This article will deal with some of my findings regarding a technique in .NET that Microsoft has dubbed, "auto deployment".

Downsizing
I started developing software using C/C++. A company I worked for later used Delphi for everything (and a Paradox databases aptly named, in my opinion).  None of the projects I had worked on had anything at all to do with the Internet. All I knew of Internet "programming" was a little HTML.  I was really pretty clueless.
You can imagine my elation when I was introduced to ASP!  I could actually program for the Internet! Wow! My elation was soon tempered, however, as I became increasingly aware of some of the limitations of the medium.
In the C/C++ world, I had developed the habit of writing small, highly-efficient, tight (and, unfortunately, sometimes even cryptic) code.  C/C++ developers are somewhat infamous for that sort of thing.  Then, in my Delphi days, a co-worker clued me in that memory was cheap and getting cheaper by the second, so it wouldn't hurt anyone's feelings if I would make my code a little easier for flesh-and-blood human beings to read.  Point taken, I unfortunately paddled to the other side of the lake: "verbosity" was my new middle name.
I had to change my thinking quite a bit in order to get used to programming for the Internet.  I had to learn that every byte matters when you're in a world that relies on transferring data over potentially large physical distances over wires, cables, and transmission signals.  I loved the exciting world of ASP, but sometimes I also missed my old desktop programming power and verbosity.



Enemy of the State
Another thing I had to get used to was state management on the Internet. In the desktop programming paradigm (or actually any compiled code paradigm), state management was a very easy thing to do: just stick values in some global variables and the problem was solved.  Anyone who has ever even touched ASP knows that state management on the Internet is not always that easy.  In order to maintain state in ASP, you have to use cookies (at times a controversial topic), session variables (almost always a controversial topic), a global.asa file, and sometimes even jump through rings of fire and eat little pieces of glass.  The issue has been made a little easier in ASP.NET, but that is beyond the scope of this article.

Face Value
One more fun little limitation that I'll mention here is the front-end interface in ASP.  We are normally stuck with using old-fashioned HTML controls for the user interface.  Sure, we can play around with JavaScript and CSS to beef up our controls, but they simply don't compare to the powerful interface controls that can be used in a Windows application.

Developer's Little Helper
Don't let my griping above mislead you.  I love ASP - but we all know how easy it is to find faults in the ones we love. ASP actually has many strengths.  For example, it makes application deployment and maintenance relatively easy. You just install your application on one server and that's it (most of the time).  Then, when it comes time for upgrades or changes, you don't have to go tell a bunch of disgruntled users that they need to download and install the latest updates to the application or better yet, that you will need to stop by personally and do it for them (yikes! I get the heebie-jeebies just thinking about it).  All you need to do is update your application on one server and away you go.  No installation files, no registry games, no caked-on dirt, no streaking, no mess and don't forget the fresh lemony scent.
Another strength of ASP applications, in my opinion, is that they are accessible from virtually anywhere and from various devices.  The user is not limited to sitting at his desk, using one particular computer to access the application.

I'll Have Some Cake and Eat It Too
For the sake of space, I won't go into the other strengths or limitations I have found in ASP (I'm certain we're all familiar with them anyway).  Believe me, I can be a long-winded ranter if I feel so inclined! Suffice it to say that ASP applications have advantages and disadvantages that desktop applications do not and vice versa.  Either we give up the power of a compiled application for the flexibility and ease of deployment of an ASP application, or we sacrifice wonderful interconnectivity in order to retain the power and dependability of a desktop application.  We have to rob Peter to pay Paul, so to speak.
At least, that was true until the advent of the .NET framework. .NET has come to the rescue by providing what they have called, "auto deployment".  Now we can build standard desktop applications utilizing WinForms that can be deployed at runtime over the Internet!  This allows us to follow a deployment model similar to that of an ASP Internet application.  We can have our cake and eat it too.

Here's the Skinny
Now, there's not a whole lot of documentation on this topic so far (at least, I had a heck of a time finding any), so consider yourself lucky if you are reading this article.  As a matter of fact, in the first part of September, I went to Microsoft's .NET Developers' Tour and they only mentioned it in passing and then moved on to another topic.  In the manual they gave us, the only semi-helpful text I could find about auto deployment was as follows:
With a Windows Forms application, it is unnecessary to deploy an application to the end user's desktop. Instead, a user can invoke the application simply by typing a URL into a browser.  The application will download to the client machine, run in a secure execution environment and it can remove itself upon completion.

Auto Deployment needs no installation:
In the applications, use Assembly.LoadFrom
The application is downloaded, form by form as needed via the HTTP Web server
It is stored in the GAC and the Internet download cache
It is only downloaded as needed or when updated
Dependent components are automatically downloaded to the client so the application "trickles" onto the client

If you use an installer, the installer can download the .NET runtime for installation.

No examples, no further explanation, no references to web sites or literature where I could learn more, so I'm here today to explain to you how this whole thing works.
First, you develop a .NET WinForms application just as you normally would.  Compile it as an EXE or DLL. In the only article I found on the subject, I read where it is recommended that we compile it as a DLL, but the author doesn't explain why.  In my own tests, I have found that an EXE and a DLL work equally well.  That said, it actually seems to make more sense to me to compile it as an EXE that way, if we ever decide to use it as a normal desktop application, we don't have to re-compile at all.  Until I hear a reasonable explanation as to why we should use DLLs instead of EXEs, I will continue to use (and recommend) EXEs for auto deployment.
Next, copy the application's files to a web server (remember that the web server must have the .NET Framework installed on it).  One of the things I really love about .NET is that installation is almost a non-issue just copy the application to where you want it and then continue reading your Spiderman comic book.
One thing to note is that in my experimentation with auto deployment, I have found that I have needed to change a setting in IIS on the web server.  In order to change this setting, open "Internet Services Manager", right-click on the virtual directory in which your application resides, and select "Properties".  Click on the "Virtual Directory" page of the Properties dialog and you will find the "Execute Permissions" setting.  Make sure that it is NOT set to "Scripts and Executables" (see the image below). Any other setting will do.


Once you have the application installed on a web server, you can write a very small intermediary application whose sole reason for being is to call the application residing on the web server.  This intermediary application would be simplistic, small, and very easy to distribute.  There's no reason that it couldn't be emailed out to all your enterprise-wide users or downloaded from your company's FTP site.  Keep in mind that the user receiving the intermediary application needs to have the .NET Framework installed on his machine.

Show Me Some Code Already!
Now that we've gotten this far, let's take a look at an example to better illustrate the process.  In this example, I have a "Hello World" application installed on the web server.  It is composed of a single assembly named, "HelloWorld", which contains one class (a form) named, "frmMain".  Keep in mind that a WinForm in .NET is actually a class.  If you'd like to take a look at the actual code of HelloWorld, at the end of this article there is a link to download it (but be warned: it probably won't be very entertaining).
Assuming we already have the HelloWorld application installed on the web server, we can now take a look at the intermediary application.  In our example, we'll call it, "LoadFrom" (again, there is a link at the end of this article should you wish to download this.


When the Load button is clicked, a call is made to the following code.


The process is fairly simple actually. First, an instance of the HelloWorld assembly is created.  This is done by using the Assembly.LoadFrom() method, which takes either one or two parameters.  The first parameter is the URL of the DLL or EXE residing on the web server (the HelloWorld application in our case).  The second parameter is optional and deals with security; but it is beyond the scope of this article.
Once we have created an instance of the HelloWorld assembly, we need to determine what type of object we're dealing with.  We do this by using the Assembly.GetType() method and passing it the name of the class we wish to instantiate.  In our case, it would be, "HelloWorld.frmMain".
Next, we create an instance of the class, "HelloWorld.frmMain" by sending its type to the Activator.CreateInstance() method.  That done, we can now cast the newly instantiated class to a Form object (just to play it safe) and then call the Form.Show() method to show the form.  Note that you technically could have skipped a few steps to shorten the code as shown below, but it's usually a better idea to go through the steps shown above in order to make your code more easily readable.


Under the Hood
When this application is run, it actually makes a copy of the assembly it calls and places it (and the requested class) in the "Application Download Cache".  Then, if a different class is needed from the same assembly, it is copied over also. Note that assemblies and classes are downloaded into the Application Download Cache on an as-needed basis only.  This is what is meant by the "trickling" mentioned in the quote earlier in this article.
Another really cool thing is that when an assembly is called, .NET looks for it first in the Application Download Cache.  If it is found, a check is made with the assembly on the web server to see if the two versions jibe.  If the assembly on the web server is a newer version, it is then copied into the Application Download Cache, allowing us to remain current.

Summary
So there it is! All the power of VB interfaces coupled with all the ease of Internet-based deployment.  Does life really get much better than this?

Just to summarize, here are the general steps necessary to enable auto deployment:

1.  Both the web server and the client machine must have the .NET Framework installed on them.
2.  Install a .NET application on the web server (which has been compiled as either an EXE or DLL).
3.  Make sure the "Execute Permissions" setting for your virtual directory in IIS is NOT set to "Scripts and Executables".
4.  Create a lightweight intermediary application for distribution via email, FTP, etc., which uses the Assembly.LoadFrom() method to instantiate the application which resides on the web server.

That's about all there is to it. Give it a try and you will soon be the most popular guy in your IT department! Well, maybe not, but it will be rewarding and fun either way.  If you have any questions or would like to comment on this article, feel free to email me at t_o_p_ramen@yahoo.com.

Hello Word   Load From