Deployment



Deployment

Objectives and Contents

[pic]

Objectives

This module introduces the new Features for Deployment in .NET.

What You Will Learn

• Overview of common deployment tasks.

• Overview of the new features.

• Changes to the previous ways of deployment.

Related Topics Covered in This Lesson

• How does .NET Deployment allow you to fully leverage the power of .NET

Recommended Reading

• MSDN: Simplifying Deployment and Solving DLL Hell with the .NET Framework

• MSDN: .NET Framework: Building, Packaging, Deploying, and Administering Applications and Types

• MSDN: .NET Framework: Building, Packaging, Deploying, and Administering Applications and Types—Part 2

Section 1: Looking Back

[pic]

Section 1: Looking Back

DLL Hell

Probably every Windows developer has got in contact with the phenomenon called ‘DLL Hell’. After your setup program installed your software in a fully functional state, the user installs some other application and suddenly your program behaves unpredictable or does not work at all. In most cases, this is because at least one DLL was replaced with a different version.

Version Conflicts

Version conflicts often occurred when a DLL was replaced with an older version, or, even worse, with a newer version that has unintended or unanticipated functionality changes. Maybe it simply contains a new bug or it corrects a problem that you were relying on.

Installation Process

Though the setup process for a single, locally installed program may seem simple to the user, the administration team has a tough job to deploy a new software or an update to all the computers in the corporation. First of all they have to test it very thoroughly to figure out all possible side effects to or incompatibilities with existing installations. The next stage in this drama is to physically deliver the software to the target computer. Traditional methods via CD or floppy disk are expensive. You need a lot of manpower and you have to pay for media, shipping and much more. The alternative to that is electronic delivery that in most cases also requires manual actions. It is cheaper in terms of materials, but requires a lot of preparations. In a corporate network, Microsoft System Management Server (SMS) and a handful of third party tools are available, but they never really solved all problems based in the system and its structure.

Uninstallation

Often underestimated, deinstallation of an application is also a frequent reason for ‘DLL Hell’ and similar problems. Most installation programs have problems removing all components, directories, registry entries an so forth. Sometimes this can lead to a deleted shared component with the well-known effects. Or imagine replacing a vital component with an older version.

Microsoft addressed these problems with the .NET strategy and you will see how this eases deployment.

Section 2: Basic Deployment

[pic]

Section 2: Basic Deployment

In this section we will see the basics of deployment with a short overview of assemblies and how the components of an application can be deployed. Also we will have a look at the possible configurations, how simple it is to deploy applications and finally the support through the Microsoft Windows Installer.

Assemblies

[pic]

Assemblies

Assemblies: The Building Blocks

Assemblies are the building blocks used by the .NET Framework to solve the versioning and deployment issues. Assemblies are the deployment unit for types and resources. In many ways an assembly equates to a DLL in today's world; in essence, assemblies are "logical DLLs”, that can consist of more than one file, but are always treated as one unit.

Each assembly has a manifest that contains information about the assembly, e.g. version, strong name, and referenced assemblies. The manifest also contains a complete description of all types that are defined in the assembly. This is called the metadata. Just as .NET uses metadata to describe types, it also uses metadata to describe the assemblies that contain the types.

Assemblies are about much more than deployment. For example, versioning in .NET is done at the assembly level - nothing smaller, like a module or a type, is versioned. Also, assemblies are used to share code between applications. The assembly that a type is contained in is part of the identity of the type.

The code access security system uses assemblies at the core of its permissions model. The author of an assembly records in the manifest the set of permissions required running the code, and the administrator grants permissions to code based on the assembly in which the code is contained.

Assemblies are also core to the type system and the run-time system in that they establish a visibility boundary for types and serve as a run-time scope for resolving references to types.

Private assemblies are only used by the application that they belong to. Usually they are located in the applications main directory or in a subdirectory. Private Assemblies do not need strong names.

Shared Assemblies can be used by multiple applications and are therefore stored in a special folder, the Global Assembly Cache (GAC). It requires some special considerations to develop and deploy shared assemblies, e.g. strong names.

Private Assemblies

[pic]

Private Assemblies

Private assemblies are the most common case for .NET applications. They are only visible for one application and can therefore not interfere with any other application. The only locations where private assemblies can be stored are the applications main folder or any subfolder. If a private assembly is placed in a subfolder with a different name than the assembly itself, the application needs a configuration file with the path to this component to locate it.

As a private assembly cannot be seen from any other application no changes to the system can break this application.

Obviously any private assembly needs a unique name within the application because you cannot have two files with the same name. But this is the only requirement for private assemblies.

Shared Assemblies

[pic]

Shared Assemblies

In .NET, sharing code between applications is an explicit decision. Assemblies that are shared have some additional requirements. Specifically, shared assemblies support side-by-side execution so multiple versions of the same assembly can be installed and run on the same machine, or even within the same process, at the same time. In addition, shared assemblies have stricter naming requirements. For example, an assembly that is shared must have a name that is globally unique.

Also, the system must provide for "protection of the name" - that is, preventing someone from reusing another's assembly name. For example, say you're a vendor of a grid control and you've released version 1 of your assembly. As an author you need assurance that no one else can release an assembly claiming to be version 2 of your grid control. The .NET Framework supports these naming requirements through a technique called strong names.

Strong Names are created by the compiler using a public/ private key pair and a version number. The key pair can be created with the SDK tool SN.exe:

SN.exe –k keyfile.snk

The compiler will sign the assembly as part of the compilation process. The public key is recorded in the manifest, the resulting file is signed with the private key and the signature is stored in a special section of the file.

The command for the compiler may look like this:

Csc /t:library mylib.cs /a.keyfile:keyfile.snk

/a.version:1.0.0.0

Shared assemblies are typically deployed to the global assembly store. The global assembly store is a machine-wide store for assemblies that are used by more than one application. Using the store is not a requirement, but there are some advantages in doing so. For example, side-by-side storage of multiple versions of an assembly is provided automatically. Also, administrators can use the store to deploy bug fixes or security patches that they want every application on the machine to use. In this sense, deploying an assembly to the global assembly store can affect multiple applications on the same machine.

Adding an assembly to the store requires explicit administrator action - in fact, the process doing the install must have "admin rights." Assemblies never end up in the store as a side effect of running an application, nor is any caching of a shared assembly currently done.

The .NET SDK includes two tools for working with the assembly store. The first is a tool called GACUTIL that allows you to add assemblies to the store. GACUTIL is convenient in development and test scenarios where you do not want to create an entire Windows Installer package to add an assembly to the store. Use the /install switch to add an assembly to the store:

GACUTIL –i myassembly.dll

The second tool is a Windows Shell Extension that allows you to manipulate the store using the Windows Explorer. It shows the installed assemblies with their version, culture and originator information and gives you the possibility to remove assemblies from the GAC.

“XCopy” Deployment

[pic]

“XCopy” Deployment

One of the main goals of .NET was to simplify deployment. This goal was reached, as you can easily ‘xcopy’ your application’s assemblies and all referenced assemblies to the destination folder. There is nothing else to be done.

The application can also be deployed by making it available on some central file server. In this case, it is even more simple to apply updates or bug fixes.

The only obvious requirement is that the .NET Runtime is installed on the user’s computer.

Uninstallation is as simple as this deployment process. Just delete all files or the whole directory. No registry keys will be left on the system and no unused files will remain in any shared directory like %WINDIR%\System 32.

Avoiding DLL Hell

[pic]

Avoiding DLL Hell

It is not necessary for a .NET application to register its private assemblies anywhere. Even shared assemblies are not registered, but installed in the global assembly cache.

No files of your .NET application should ever be needed in a system directory like %windir%\system32, where it could overwrite a different, maybe newer, version or remain there forever when your application has been removed.

As the global assembly cache allows multiple versions of one shared component to coexist on one computer, there is no need to replace any version. The global assembly cache never gets cleaned automatically, thus your application can rely on the fact that its required assembly does exist. Only an administrator can explicitly remove a shared component.

All this makes it easy to avoid DLL Hell, as you cannot overwrite any shared components or delete files needed by other applications. The .NET framework protects you from these possible pitfalls.

Packaging

[pic]

Packaging

Now we will have a look at some of the tasks that are required for packaging an application.

Then we explore the support that configuration files offer to customize the behavior of your application.

Finally you will get a brief description of the algorithms the .NET Framework uses to locate an assembly you reference in your application.

Packaging a .NET Application

[pic]

Packaging the Application

Since the Common Language Runtime assemblies are self-describing and define the relationships of their components, application installation and deployment is greatly simplified. Runtime applications do not require any registry entries; deploying a runtime application can be as simple as copying the assemblies that constitute an application to a directory structure on disk. The runtime can then launch the application and resolve all references directly from the file system. Since each assembly describes where to locate the classes it contains, there is no need to make registry entries of any kind.

To deploy runtime files, you can create either Microsoft Installer files (‘.msi’) and Merge Modules (‘.msm’) for use with the Windows Installer or ‘.cab’ files for distribution by downloading or copying. If you intend to deploy files from a website, assemblies are downloaded automatically into the download cache when they are referenced. This proceeding minimizes the network download size of an application to the actually required files. The download cache is located in a directory below the Global Assembly Cache. Any assembly in the download cache is only available to the application that initiated the download.

Configuration Files

[pic]

Configuration Files (1/4)

The Common Language Runtime configuration system allows administrators and developers to configure those aspects of an application that are either specific to the deployment environment, or can logically be changed after the application was built. By default, all information that the runtime needs to locate, load, and execute an application is available either implicitly (e.g., the location where you started the application establishes the default search path) or within the manifest for each assembly that is loaded as a part of that application. For example, by default each assembly binds to the highest compatible versions of its dependencies it was compiled with as specified in its manifest. A configuration file can be used to change these default settings.

Ease of use is provided for these configuration files by the fact that they are simple human readable and modifiable XML files.

It is important that you understand that configuration only applies at the application level. For example, it is not possible to configure a specific assembly to use a specific version of a dependent assembly on an assembly-by-assembly basis. The configuration files apply to all assembly binding done in the scope of a single application.

Two Types

There are two important types of configuration files that can be used to customize the behavior of one or all .NET applications.

The application configuration file, sometimes referred to as app.cfg, is an XML file containing several attributes that can control the binding behavior of the application.

The terminology used in the application configuration file is consistent with the other configuration files. A collection defines the beginning of a set of rows, and is delineated by start and end tags, such as: and . A row is an entry inside a collection, containing specific settings in the form of name-value pairs. A property is a name-value pair inside a row containing the setting information.

The outer-most collection that defines the application configuration file is the Configuration collection. Each of the sub-collections and rows described below appears between the start and end tags of the Configuration collection.

The application configuration file must be located in the applications location to be effective.

An administrator can create a configuration file that overrides any other configuration file on the machine it resides on. This XML-based configuration file can set policy for access to data as well as assembly binding policies. This configuration file needs to be placed in the %windir% directory, usually C:\WINNT.

Configuration Files

[pic]

Configuration Files (2/4)

There are several application settings that can be configured either on an application-by-application basis, or at the machine level for all applications launched on that machine. There are rules for how settings at each of these levels are merged to obtain a single set of configuration settings for a given application.

The available configuration settings are:

• Application specific search path

• AppDomain

The path that the runtime uses to locate assemblies that are referenced during the execution of an application. The application specific search path is relative to the application path. It can consist of several subdirectories that will be searched in addition to the standard search paths one after the other when the runtime tries to locate a referenced assembly.

Configuration Files

[pic]

Configuration Files (3/4)

Version policy

• BindingMode and BindingPolicy

For a given application, it is possible to specify as policy what version of a particular assembly should be used or specify that the application should run in "safe mode" using exactly those versions that it was compiled with.

• AppBindingMode

‘Normal’ sets the normal version policy including Quick Fix Engineering (QFE) mode; ‘Safe’ causes the runtime to bind to exactly the version the assembly was build against.

• BindingRedir

The BindingRedir property redirects one version of an assembly to another. This version redirection only applies to shared assemblies.

Codebase

• CodeBaseHint

A configuration can supply Codebases, providing locations for particular assemblies. If a codebase is specified for an assembly, the runtime will load the assembly directly from that codebase and not search for it on disk.

Configuration Files

[pic]

Configuration Files (4/4)

Sample

This sample shows the use of the app.cfg file:

The AppDomain Node tells the CLR to search assemblies in the ‘bin’ and the ‘mycode’ folders.

The BindingMode ‘normal’ causes the use of the newest compatible version.

BindingRedir assures that no matter what version of MyCode.dll is requested, the given version will be loaded.

Finally the CodeBaseHint directs to a location, that supplies the required version. If this tag is used, the assembly will not be searched on disk but will directly be loaded from the specified location.

Locating Assemblies

[pic]

How The Runtime Locates Assemblies

The process of locating an assembly, often referred to as ‘probing’, begins when the runtime is asked to resolve a reference to another assembly.

Step 1:

First it tries to evaluate the application specific configuration file, if it exists. If this file can be found, the runtime merges the information from the reference with the information from the configuration file and figures out the desired assembly version and location.

If the CodeBaseHint specifies a location, this file is used. When the file at the given code base is loaded, the runtime checks to be sure that the name, version, culture and originator match what is in the reference. By default, the revision and build numbers can be higher than what is requested. If no match is found, the bind fails and no further steps are taken. If the runtime finds a match, it continues to Step 3.

Step 2:

In the absence of a code base describing the location of the assembly, the runtime probes for the assembly under the AppBase. Note that the version of the assembly probed for may differ from the original reference if rules in the application configuration file redirected the original bind to a different version.

By default, the assemblies that are actually deployed in the application directory need not match the bind reference exactly. It is possible for an application author to deploy new assemblies in the application directory that will still satisfy the bind, provided the newer assemblies only contain updates in the revision and/or build number of the assembly.

The runtime always probes for the name of the assembly concatenated with three extensions, .MCL, .DLL, and .EXE.

The runtime always begins probing in the AppBase directory. That is, the first probing URLs generated will always be the concatenation of the AppBase, the assembly name and extension.

If the assembly is not found in the AppBase, probing continues in the directories on the assembly search path. The search path is specified using the tag in the application configuration file.

In addition to the subdirectories given in the configuration file, the runtime always prepends a directory corresponding to the name of the assembly being probed for.

If the reference did not contain an originator (e.g. was to a private assembly), the binding process stops at this point. If a match is found, that assembly is loaded. If no match was found, an error is raised. This error ends up as a TypeLoadException in managed code.

Step 3:

If the reference was to an assembly with a strong name, the binding process continues by looking in the global assembly cache.

If an assembly was found via probing or through a code base and QFE policy has not been turned off, the runtime looks in the global assembly cache to see if any QFE’s exist for that assembly. If there is a version of the assembly in the cache that has a higher build and/or revision number, this assembly is loaded instead of the one found by probing.

If no assembly was found via probing or through a code base, the runtime looks in the global cache for an assembly that matches the criteria. If automatic QFE policy has not been turned off, the runtime takes the match that has the higher build/revision number.

The final step in this process is to apply any version policy specified by the administrator in a configuration file named “admin.cfg”.

Administrator policy is the strongest form of policy. The version determined by the administrator policy file is final, and cannot be overridden.

Again, if still no match is found, an exception is raised.

Section 3: Advanced Tasks

[pic]

Advanced Tasks

Now we will have a look at some of the more advanced tasks that may be required for an application. This includes the installation of additional resources like performance counters, message queues or services. It may also be important to make a .NET component available to be called via standard COM mechanisms.

Finally we will see some simple points about maintaining and administrating a previously deployed application.

Installation Components

[pic]

Installation Components (1/2)

In the Microsoft .NET Framework, an application consists not only of the traditional program files but also of associated resources, such as message queues, event logs, and performance counters that must be created on the deployment destination as well. You can configure your application to create these resources when your application is installed and to remove them if your application is uninstalled, using what are called installation components.

For example, suppose you are deploying an application that writes to a custom performance counter. The counter must be installed when the application is deployed. Using an installation component, you can set up the application so that it automatically creates and configures the necessary performance counter on a remote computer when the application is installed.

After you add the first installation component to your application, create an application installation class. Each subsequent installation component you want to associate with the application should be added to that class.

Installation components are associated on a one-to-one basis with the components that need them. For example, if you have an instance of the MessageQueue component in your project and it requires your deployed application to have a queue installed and configured, you create an installation component to handle the task. If you then add an instance of the EventLog component to your project and want to configure the event log in use, you must add a second installation component to perform that processing.

All of the installation components in a project are stored within classes marked with the RunInstallerAttribute=True. By default, a class named ProjectInstaller that contains this attribute is added to your project when you add an installation component, but you can use another class if you want to. For more information on what happens during the installation process, see Installation Process.

The Microsoft .NET Framework ships five pre-defined installation components that you can use in your projects:

• The EventLog installer (based on the System.Diagnostics.EventLogInstaller class) allows you to install and configure a custom event log that your application needs in order to run.

• The MessageQueue installer (based on the System.Messaging.MessageQueueInstaller class) allows you to install and configure a queue that your application needs in order to run.

• The PerformanceCounter installer (based on the System.Diagnostics.PerformanceCounterInstaller class) allows you to install and configure a custom performance counter that your application needs in order to run.

• The Service and ServiceProcess installers (based on the System.ServiceProcess.ServiceInstaller and System.ServiceProcess.ServiceProcessInstaller classes) are used together to allow you to install services and their associated processes.

Installation Components

[pic]

Installation Components (2/2)

Save state

During installation of components, the ProjectInstaller class (or any class with the RunInstallerAttribute value set to true) writes a file with the extension .InstallState to the deployment computer. This file is used to store information about the original state of the system before your resources were installed, and the changes that were made during installation. This file is used in each of the installation component's methods:

The Install method accesses a blank copy of this file in the stateSaver parameter, and uses it to write information about all of the successful installations it performs.

The Commit method receives information from the file in the savedState parameter. You can work with the contents of this file using the IDictionary object if you want to.

The Rollback method receives information from the file in the savedState parameter, and uses it to undo previous transactions if an error occurs in the Install method. After rollback completes, the state file is deleted.

The Uninstall method receives information from the file in the savedState parameter and uses the file to return the system to its original state.

The InstallState file is saved on the deployment computer to the same directory in which your project's DLL is installed.

Transactional

Resource installation is transactional. That is, the installation processes iterates through each installer in your application installer class (or any class with the RunInstallerAttribute value set to true) and makes sure that no errors occur before committing the installation as final. If any errors occur along the way, all of the resources that have previously been installed are uninstalled in a rollback transaction. Rollback is performed in the reverse order of install.

COM Components

[pic]

COM Components

You must register the assembly with COM using the RegAsm utility before you can invoke an object contained in the assembly. The installer can take care of this for you, if you set the ‘Register’ property to the appropriate value.

Using RegAsm with the /tlb: flag generates a type library in addition to registering the types in an assembly. You'll need a type library to bind to .NET objects. The type libraries generated by RegAsm and TlbExp are identical.

Use the COM CoCreateInstance API to activate the .NET object, as you would do with any other COM component.

You can call methods on the .NET object as you would call methods on any unmanaged type. The runtime marshals each call for you.

It is necessary to locate the assembly in the path of the application. If the runtime cannot find the specified assembly it will throw an exception.

The registry entry under the InprocServer32 key then looks like this:

[HKEY_CLASSES_ROOT\CLSID\{GUID}\InprocServer32]

@="C:\\WINNT\\System32\\MSCorEE.dll"

"ThreadingModel"="Both"

"Class"="MyNamespace.MyClass "

"Assembly"="myAssembly, Ver=1.0.0.0, Loc=\"\",

SN=32ab4ba45e0a69a1"

Serviced Components

[pic]

Serviced Components

A serviced component is a .NET Framework component that derives from the ServicedComponent class and is automatically serviced by Microsoft Windows 2000 Component Services (COM+ Services). A serviced component is typically hosted in a COM+ library as an in-process server.

Using Dynamic Registration

Dynamic registration is a technique that uses XCOPY to automatically register all classes that derive from the ServicedComponent class with COM+.

The first time a serviced component is called from managed code, the runtime automatically registers it with the COM+ application. If the COM+ application does not already exist, the runtime will create it.

Since serviced components are managed by the .NET Framework, they have the same system of versioning that other managed code has. The runtime has a notion of compatible and incompatible versions. A client will automatically use the highest compatible version of a component to the one it was compiled with unless the client specifically requests a different version to load. If there is a higher incompatible version installed on the system the client will ignore it.

Using RegSvcs

An alternative way to explicitly register an assembly as a serviced component is to use the Services Registration Tool (RegSvcs.exe). This tool reduces the effort of loading, generating a type library, registering and configuring by combining them into a single command line tool.

For a ComEmulate class, that is, a class with the attribute ‘ComEmulate’, you must invoke RegSvcs on the command line to register its assembly with COM+ Services.

Especially if you want to use this component from unmanaged code, dynamic registration does not work and you have to register it via RegSvcs.

Deployment

[pic]

Deployment

The new features in the .NET framework allow a much easier deployment of applications.

The web server does not lock any files, even assemblies that are used. Therefore you can just replace a DLL on a running server and the web server will automatically pick up the new file when new requests come in. Requests that are already running keep their assemblies in memory and will use them until these requests are finished. This feature eliminates many scenarios that you previously had to restart the web server, thus making it unavailable for a period of time. Additionally, there is no registration necessary as well as you do not need local server access.

This is also valid for all additional components, WebServices and configuration data like Dynamic Properties.

Using Installation Services

[pic]

Windows Installer

The Windows Installer beginning with version 1.5 supports all features of the .NET framework, especially assemblies.

This means that you can use all the helpful features of the windows installer, as there are:

▪ Local Installations

▪ Remote Installations from e.g. an administrator

▪ Resiliency, also known as Application Repair

▪ Installation-On-Demand

▪ Maintenance Installation

All of these Features can be used together with Microsoft System Management Server (SMS) and with the Microsoft IntelliMirror technology introduced with Windows 2000.

Maintenance

[pic]

Maintenance

Maintenance of .NET applications is as simple as installing new versions to the appropriate locations.

If you want to apply a QuickFix Version to a private assembly you can either replace the private assembly with the new version or you can install the new version in the Global Assembly Cache.

In the first case it is totally in the developers responsibility to assure compatibility between the new assembly and the application. But no other application can be affected by this operation.

In the second case it depends on the version policy of the application whether the new assembly will be used or not. This new version may influence more than one application.

A new version of a shared assembly will be installed side by side with previous versions in the Global Assembly Cache. Whether an application uses this new version is determined by the configuration files of the applications or by the administrator’s configuration file admin.cfg.

Administration

[pic]

Administration (1/2)

Deleting Shared Assemblies

Only a few tasks apart from applying updates and hotfixes can be done to administer one or more already deployed applications. One of them is to remove a shared assembly from the Global Assembly Cache (GAC).

Sometimes it may be necessary to remove an application including all shared assemblies that were installed or used by that application. If you remove a shared assembly from the GAC it is your responsibility to assure that no other application will be broken by that action. This may especially be useful for testing and development purposes.

The .NET runtime supplies two tools for this task.

The first is a command line utility called Global Assembly Cache Utility (gacutil.exe). This tool allows to install a shared assembly and to list the contents of the global assembly cache. To remove a specific version from the GAC you can select ‘uninstall’ and provide the version, locale and key information of the target assembly.

During the installation of the .NET Framework the second utility should have been installed. This Windows Explorer Shell Extension is used to display the contents of the GAC in a readable manner that would otherwise look like a pile of unidentifiable temporary folders and files.

With a right click on any entry you can view the properties or you can remove this shared assembly.

For all actions concerning the Global Assembly Cache you need administrative privileges.

Administration

[pic]

Administration (2/2)

Clearing Download Cache

An assembly that was downloaded and is now located in the download cache usually does not need to be removed manually because the download cache will regularly be cleared on a Least Recently Used Policy.

Only for development purposes it may be useful to remove one or more entries.

You can use the same utilities for the download cache as for the Global Assembly Cache, gacutil and the Windows Explorer Shell Extension.

Moving Applications

In some cases it may be necessary to move a whole application to a different location. Usually it should be sufficient just to move the complete folder structure to the new location.

If this application uses registry entries or any other configuration methods that contain path information you obviously have to adjust them.

If you want to move an assembly between subfolders of the application you my need to supply or modify application specific configuration files. If you omit this step the application may no longer find its components and throw an exception.

Managing Applications After Deployment

DynamicProperties allow you to configure your application so that some or all of its property values are stored in an external configuration file rather than in the application's compiled code. This can reduce the total cost of maintaining an application after the application has been deployed, by providing administrators with the means to update property values that may need to change over time. The property settings you store are saved to a configuration file.

This configuration file is in standard XML format to make it easy to modify.

The next time the application starts the new property settings are applied without recompiling the application.

Section 4: Putting it all together

[pic]

Demo

Now let us see some samples about this.

Creating a simple Application Package

First, a quite simple application that just uses one other assembly.

Sample 1 consists of a client application that uses an assembly named Foo in the subdirectory Foo. It does not need any configuration file because the runtime automatically searches in a subdirectory with the same name as the assembly. The Foo.dll returns a simple string that is print out by the client.

To build this sample, just run build.bat then execute client.exe.

To deploy this ‘application’ just copy client.exe and the subfolder Foo with the Foo.dll wherever you want.

Creating a complex SetupProject

Now we will go through the process of creating a more complex sample in the Visual environment.

This will be a simple windows program that is packaged into a Windows Installer Package.

• Create a new Project and select a C# WindowsApplication named DeployDemo.

• Put a button on the form and give it the caption “Greetings!”

• Double click on the button and write a simple message box:

MessageBox.Show( "Hello User!", "Greetings", MessageBox.IconInformation);

Now you have a simple C# application that you can compile and test.

To deploy our simple application we create a setup project and test the deployment.

• From the File menu click ‘Add Project’, select ‘Deploy Wizard’ from Setup and Deployment Projects and name it DeployDemoSetup.

• In the following wizard select ‘rich client application’ in step 2.

• In step 3 we need only the primary output from DeployDemo.

• Skip step 4.

• Select the option to deploy the project later on step 5.

• Finish the wizard.

Now we have a complete Setup.

A right click on the Setup project in the solution explorer on ‘View’ brings us to some windows where all necessary steps can be customized.

• You can put an icon on the user’s desktop with ‘File System\User’s Desktop’.

• You can create your own registry keys in the registry view.

• Or register your own file types, customize the setup user interface, add custom actions or make the setup dependent on existing files, registry keys and much more.

To finish our solution select ‘Build Solution’ from the build menu.

When it’s finished, you can find a windows installer package in your file system under the Setup project that contains all files that your application may need.

You can also start the deployment by right clicking on the setup project in the solution explorer and selecting ‘Deploy’

Summary

[pic]

Summary

We have seen that though some points may sound quite complex or unusual the .NET framework does a great job simplifying the deployment of any .NET application.

It makes hardly any difference if you want to deploy an application locally by copying to any folder, remote via Remote Installation Services, SMS or IntelliMirror, or as a web based application.

Although the dreaded DLL Hell will not completely disappear as long as we have to deal with COM and it’s registry entries, it is now much less likely to occur if you are using .NET.

The support for creating setup packages and deploying applications in .NET and especially Visual may seem to make third party installers redundant, there will be enough left to be done.

................
................

In order to avoid copyright disputes, this page is only a partial summary.

Google Online Preview   Download