by Christopher Goldfarb
Harness the full processing power of the desktop while still maintaining the deployment and maintenance benefits realized by Web applications
Proper installation of Windows* client applications in a corporate desktop environment has been plagued with numerous issues. These range from simple problems, like attempting to get all of the users to upgrade, to far more complicated, such as DLL versioning problems. Well, fear no more because Microsoft has developed an exciting new feature to simplify deploying and updating client applications using a Web Server. In this article, I'll first be covering the mechanics behind it, security concerns, and recommendations on what types of client apps should be deployed in that fashion.
What is .NET* Client Application "No Touch" Deployment?
.NET Client Application "No Touch" Deployment, which I'll refer to hereafter as "no touch," provides an excellent vehicle for distributing Windows Forms* applications. Using "no touch," an application developer can harness the full processing power of the desktop while still maintaining the deployment and maintenance benefits realized by Web applications.
With the .NET Framework*, Microsoft set out to bring all the deployment and maintenance advantages of the Web application to the desktop application. DLL versioning problems are eradicated, because by default, Windows Forms applications (desktop applications built using the Windows Forms classes of the .NET Framework) are completely isolated from one another, retrieving their DLLs from their own private application directories. DLLs may still be shared among multiple applications, but rather than using the system registry for this, the shared DLLs are stored in the .NET Framework global assembly cache. The global assembly cache can host multiple versions of a given DLL, as well as keeping track of which version goes with which application. As for actually deploying the applications, the .NET Framework allows system administrators to deploy applications and updates to applications just as they would Web applications, via a remote Web server.
Simply stated, with "no touch", Windows Forms applications can be downloaded, installed, and run directly on the users' machines without having to alter any of the registry or shared system components.
Why Was "No Touch" Developed?
Prior to the arrival of the .NET Framework, users often encountered two major problems when attempting to deploy and maintain rich-client applications in the Windows environment. These common problems are outlined below:
- Deployment of rich-client applications was too complex and costly, chiefly in comparison with Web applications requiring no client deployment. This problem resulted from the need to develop an installation application or a set of installation scripts, when installing Windows client-based applications that were written using either Visual Basic* or C++ with Microsoft's COM*. Because the Windows Registry* required updating with the COM components, the installation scripts often becam e very complex, and in many cases, testers were needed to check the installation, as well as the application itself.
- Applications relying on the same DLL may cease to run after a component in one of the applications is modified or updated, because DLL files routinely store COM components in the Windows environment. This problem is commonly referred to as "DLL hell." When a user installs a Windows application, the application commonly installs multiple DLL files with multiple COM components. Before, if a user overwrote an old version of a DLL file with a newer version of the file, in the process of installing the application, it could and often did break other applications that depended on that same DLL file.
Microsoft has addressed these problems as follows:
- The .NET Framework's Windows Forms are a set of class libraries and a design environment for building user interfaces. "No-touch" allows a Windows Forms application to be distributed to all of its clients by copying files to a server and distributing a URL that points to a Web page, thus activating the download of the application. In the event that the application is merely being updated, only those pieces of the application that have changed are downloaded. In most cases, this is done over a LAN or virtual private network. Therefore, no installer or installation script is needed.
- Two instances of a .NET component are automatically generated by the .NET Framework's common language runtime (CLR), thus an older version of a .NET component is executed in conjunction with the new version. In this way each application is guaranteed to receive the correct version of the .NET components it needs and that the installation of a new .NET application won't break any previous applications.
How Does It Work?
Basically, "no touch" mirrors the browser-based application deployment approach. Utilizing methods provided in the class libraries of the .NET Framework, an application can be developed to download the assemblies it requires dynamically from a remote Web server. The first time a particular assembly is referenced it is downloaded to a cache on the client and executed. Subsequently, if the assembly required is already on the client and the version on the Web server has not been modified, the local copy will be loaded. However, if the version on the Web server has been updated, that new version will be downloaded and executed. Updates are therefore automatically propagated to the client, thereby eliminating redundant downloads.
Note: Assemblies are downloaded dynamically, only as they are referenced, thus allowing applications to load quickly.
Currently, "no touch" can be implemented in three different ways.
- URL launched executable
- Assembly.LoadFrom method
- .NET Application Updater component
These mechanisms each have advantages and disadvantages, and these are discussed in detail below.
URL Launched Executable
With "no-touch", a company can distribute a Windows Forms application to all of its users by copying the executable to a Web server and distributing a URL that points to a Web page. It is this URL t hat initiates the download of the application. To do this, the .NET Framework installation provides a mechanism to hook Internet Explorer* 5.01 and above to listen for .NET assemblies being requested. During a request, the executable is downloaded to a location on disk called the assembly download cache on the client machine and launched from that location. DLLs required by the executable can be referenced as normal in the code. Unless informed otherwise, the CLR will look for the DLLs in the same directory on the Web server as the executable, and the CLR will download them into the assembly download cache from there, as they are needed. A process named IEExec then launches the application in an environment with constrained security settings.
If the application has merely been updated, then only those pieces of the application which have been altered are downloaded. This is done entirely over the Web, and the need for installers or installation scripts is eliminated. Assuming the version on the Web server has not changed, the .Net Framework will launch the version of the executable stored in the assembly download cache.
Note: The downside of the URL launched executable is that the user does not find an icon by which to launch the application, rather must navigate to the destination URL or click on a link in an HTML page every time.
In this example, you will find a simple application demonstrating a URL launched executable. This demonstration application provides two buttons. The first button displays "Hello Taskforce!" when pushed, and the second button creates and writes a file named "dangerousfile.txt" to the C drive. The code for this application is shown below in Figure 1.
Figure 1*. Demonstration Application (first example)
It is important to note the two code snippets and the significant difference between them. The first method executes code that requires minimal rights to run (just displays a simple popup dialog). The second method however executes code that the .NET runtime (rightfully) flags as high-risk. How one goes about configuring security settings in .NET are covered in the next section, but for now let's see what would happen if you were to execute the demonstration application without modifying any of the default security settings:
Figure 2*. Demonstration Application Exception (insufficient security settings)
If you were to select "Yes" in the above window, you would led through another couple windows that aren't immediately intuitive. This interface is not optimal for a client application. Users faced with such cryptic errors quickly will find an alternative rather than suffer through trouble calls, much less try to debug the issue.
Assuming the client had configured his or her .NET security settings to set the domain the application was downloaded from to a less restrictive setting, say midway between "no trust" and "full trust", the application would notify the user that it's being run in a partially-trusted context:
Figure 3*. Demonstration Application Exception (partially trusted context)
The .NET runtime will only allow the application execute those methods and functions it has rights to, given the security context. Here's the result of clicking on the "Say Hello" button in partially-trusted mode:
Figure 4*. Demonstration Application Exception (partially trusted context, "Say Hello" clicked)
If the user attempted to write to the C: drive, an exception would be generated:
Figure 5*. Demonstration Application Exception (partially trusted context, "Write to C:" clicked)
Assuming the client had configured his or her .NET security settings to set the domain the application was downloaded from to "full trust", the entire application would run as expected, without throwing errors.
A second way to implement "no touch" is to use the Assembly.LoadFrom method from the System.Reflection class. This method proves to be helpful in two situations. In the first, the initial executable was launched via a URL (as discussed above), but now needs to access DLLs that are located in a different directory on the server or perhaps on a different Web server entirely. In the second, which is perhaps a more common scenario, the application is architected in such a way that there is a small executable installed on the client machine. This executable may contain very little core logic, perhaps just referencing the DLLs it requires, which reside out on a remote Web server and which supplies all of the necessary application logic. The advantage of having the executable installed on the client machine is that the user will have an icon by which to launch the application. The code sample below gives guidance on how to use Assembly.LoadFrom method:
Figure 6*. Demonstration Launcher Application (second example)
If you were to execute the demonstration launcher application without modifying any security settings, the following exception would be thrown - a slightly different look from the URL launched app, but essentially the same:
Figure 7*. Demonstration Launcher Application Exception (second example)
.NET Application Updater Component
The third deployment mechanism, the .NET application updater component, is quite simple to use. It provides native support for offline access, as well as gives the developer greater flexibility in terms of when the Web server is polled to check for updates to the assemblies stored there. It was written using the . NET Framework and enables you to develop applications capable of automatic updating. Simply simply dropping the component into your existing .NET applications and setting a few properties, such as where to get updates accomplish this. For more information on this component, visit http://windowsclient.net/articles/appupdater.aspx*.
As seen by the above examples, with "no touch" deployment the key to protecting the desktop from the Windows Forms applications that are being downloaded is code access security. This is accomplished by matching applications to the permissions they should be assigned. The CLR gathers data on an assembly at runtime, and this data could consist of the Internet Explorer zone where the code was found (local disk, intranet, internet, trusted sites, untrusted sites), the URL the code came from, any private key assembly may be signed with, the assembly's hash value, an Authenticode publisher signature, etc.
By default, the .NET Framework ships with code groups set up around the Internet Explorer zones. The CLR uses this data to assign the assembly to an appropriate category or code group. Each code group has a permission set assigned to it. It is these permissions that dictate which permissions the assembly should acquire, for instance the ability to perform file IO access, to print, to access networked resources, to access environment variables, and so forth. For example, code coming from the intranet zone gets a very constrained set of rights and may not perform file IO access. The .NET Framework's security architecture guarantees that unauthorized code cannot access or abuse the client in any way, and gives system administrators more control over the applications running on their systems.
Developers concerned that their applications will not run properly without a certain minimum set of security permissions can specify these requirements in advance with attributes included in the assembly's metadata. The assembly will not be loaded if these permissions are not granted, so the unsuspecting user will never stumble upon the ugly security exceptions thrown above.
The .NET Framework ships with default security settings that are both safe and appropriate for most scenarios. However, system administrators have the option of modifying security permissions in order to grant more permission to existing or newly created code groups. To modify these settings, system administrators can use the .NET Framework Configuration Tool, or a scriptable command tool.
Note: It is very important to understand that modifying security settings is dangerous and should never be completely turned off. In all cases, it is highly recommended to only change the security settings necessary to make the application run.
To configure security, in addition to the .NET Framework command line tool "CasPol", a GUI tool called the .NET Framework Configuration Tool is provided via a Microsoft Management Console (MMC)* snap-in. This tool allows you to manage and configure assemblies in the global assembly cache, adjust code access security policy, and adjust remoting services. I could go into more depth on the Configuration Tool here, but it's better served in its own article. To access the NET Framework Configuration Tool, Click Start, Programs, and Administrative Tools. Click Microsoft .NET Framework Configuration.
Figure 8*. .NET Framework Configuration Tool
Finally, it's important to note how Web services fit into the security model of "no touch" client applications. When an application is being distributed via the Web server, its domain must match any of the Web services that it relies on. Thus, any Web Services being consumed are outside the scope of the application domain, and the resulting inability to match a required Web Service raises a significant limitation.
"No touch" deployment is not ideal for every scenario. In situations where user platforms are unknown or diverse, such as e-commerce, the browser-based model (or full deployment model for client applications) continues to represent the most practical approach. However, in the context of a corporate computing environment, where clients are known to be running the Windows operating system, the "no touch" deployment is the architecture of choice.
Corporations where IT provides employees with pre-built systems have a perfect opportunity. These organizations should be able to distribute machines with the appropriate security settings to enable rich client applications that are accessed on the intranet, while still prohibiting Internet-based applications full reign.
As with any technology, there are a few requirements for everything to work in harmony. The client requirements are as follows:
- Any operating system that supports the .NET Framework
- .Net Framework with SP1
- Internet Explorer 5.0.1 and above
- Access to an IIS Web server for application deployment
Keep in mind, an application can be distributed both as "no touch" and also traditionally, so that non-IE users can install the application locally. In this case, as long as the client has the .NET framework installed, mechanisms like the Assembly.LoadFrom implementation will work like a charm.
The .NET client "no touch" deployment model enables you to deploy and update Windows Form smart client applications over the network using a Web browser, using different deployment mechanisms. Remember to take into account the security considerations with this technology. "No touch" deployment not only makes deployment as simple for desktop applications as it is for Web applications, but it also saves on IT expenses by eliminating the need for installation scripts and programs, dll maintenance issues and client versioning problems. The bottom line? "No touch" opens up new doors for rich client apps.
About the Author & Additional Resources
Chris Goldfarb is a Senior Software Architect for the Intel® Software Solutions Group, and has been writing software for nine years.
.NET has been Chris' main focus since the pre-beta bits were released, and has both developed applications and trained others on the framework. He has recently traveled to the Intel office in Nizhny Novogorod, Russia to train engineers on .NET.
Chris represented Intel's .NET efforts as a speaker at the .NET Showcase Theater in the 2001 Microsoft Professional Developer's Conference in Los Angeles, and has presented .NET topics twice to over 800 engineers of the Intel Developer's User Group. He is a board member of the Intel e-Business Group .NET Taskforce.
Prior to joining Intel in January 2001, he trained Department of Defense engineers on distributed application development and engineered mission-critical applications for the United States Air Force, United States Strategic Command. These applications included nuclear readiness assessment, early warning threat detection, and ballistic missile flight path and trajectory systems. Chris participated in a joint Y2K-compliance effort between the US and Russian strategic commands by developing and executing test coverage guidelines for numerous systems.