CSCI E-143 CertPrep: Deployment (Kalani, chapter 13)
Saturday, Dec. 11, 2004
This Saturday we cover Kalani's chapter 13,
"Deploying a Windows Application".
"Deployment" here means the installation of your project on a
"target" machineone different from your own.
This may not be the most important chapter in Kalani,
but it may be the most confusing.
And the following writeup may have the most excessive and unnecessary amount of detail.
Ambiguous Terms
Here are some terms that have more than one meaning in this chapter:
Installer. There may be as many as half a dozen
meanings to this term. Here are two meanings you must distinguish
now: (The others are described under
"Installation Components", below.)
- The installation package you set up with the "Setup Project" wizard,
which you may modify with the six setup editors.
This package, when compiled, comprises a single module,
with an extension of .msi.
Kalani describes the start of such a project on pages 846-849.
- The Windows "Installer" service which runs this
.msi package.
Needless to say, the target machine must have this "Installer".
If it doesn't, we pass to the next topic:
Bootstrapper. There are two things that may be
"bootstrapped", or loaded during installation:
- The Windows Installer, #2 in the above list.
You can include this with your installation package.
(Kalani, page 849)
- The .NET Framework, which must be present on the target
machine.
You cannot, as a matter of course, include this bootstrapper
with your installation package.
Kalani discusses its installation on pages 849-850.
Invoking this Framework installation from your installation package
is not trivial. On pages 927-928,
Kalani has an example that does it.
"Cab". This term apparently has two unconnected uses:
- On page 842, Kalani says that a "Cab project" is for packaging
ActiveX components. We will not be concerned with this.
- On page 851, under the "Package files" option for
.msi output,
the "Cabinet file" option seems to control only the size of CAB files,
for instance, the size of files that can be placed onto a floppy.
Registry Editor. Distinguish these two meanings:
- The current machine's Registry Editor,
regedit, can be executed from
Start / Run
and can be used to make immediate changes in the registry on the current
machine.
- The other "Registry Editor" is one of the customizing editors for the
setup package described below, and is used to prescribe
registry settings for the installation's target machine.
Installation Packages
Types of Installation packages
XCOPY Deployment. This is of limited usefulness,
because it can only be used to copy from your media to the target machine,
in a location specified by the user.
If you want to do any of the things normally done during installation,
such as creating shortcuts, selecting optional features during installation,
using different paths on the target machine,
running routines during installation, etc., etc., etc.
(see the list on Kalani's page 840),
then you must use a custom installer.
Types of Deployment projects. There are four different kinds:
- Windows setup projects, which we are concerned with here
- Web setup projects, for deploying web-based routines,
which we will ignore
- Merge Module projects, for components shared by multiple apps;
briefly discussed at the end of the chapter
- Cab projects, which contain ActiveX components for download
over the internet, which we will also ignore.
Setting up an Installation package
You can begin either with a Setup wizard (described on pages 847-848) or with a
Setup project (described on pages 856-857).
You will be asked to specify such things as
- the output file name (for the .msi package)
- how to package the files
- whether you need to bootstrap the Windows installer
- how to compress the project
- an Authenticode signature, if any
In addition, you can customize the basic project,
using one of six editors to make various settings and perform various actions
on the target machine.
- The File System Editor (pages 853-857)
gives you mappings for the target machine, such as
Application Folder, User's Desktop, System Folder,
etc. This editor can handle
- icons
- shortcuts. To put a shortcut in a particular place on the
target machine, you first create it (with this Editor)
and then move it to the desired location (also using this same
Editor).
(Kalani, example, pp. 854-855)
- menu items.
- The Registry Editor (pages 857-858) lets you register things
on the target machine.
(Remember, this one works on the target machine,
as opposed to regedit,
which works on the current machine.)
- The File Types Editor (pages 858-859) associates
file extensions on the target machine with actions on that machine.
- The User Interface Editor (pages 860-861)
lets you do two different things:
- You may specify the order in which things are presented to the user
during installation.
This includes the presentation of dialog boxes which ask questions.
- You may ask questions of the user during installation so that actions may be
determined thereby.
(Kalani, pages 865-867.)
- The Custom Actions Editor lets you specify
which routines should be run at the end of installation on the target
machine.
(Kalani, pages 861-863.)
- These actions may be determined by the answers to questions set up by
the User Interface Editor.
- The installation is transactional; if a custom action fails,
the entire installation is rolled back.
- Such custom actions may include
- installing optional files, such as samples;
- running ngen.exe on a routine
after it has been installed;
- running SQL scripts to set up SQL tables;
- running other routines by using
ProcessStartInfo and
ProcessStart().
- The Launch Conditions Editor lets you
specify the conditions which must be met on the target machine before
installation can begin.
(Kalani, pages 864-865)
Allowing the user to decide actions during installation
(Kalani, pages 866-867)
- Use the User Interface Editor to add a Dialog to the installation process.
- Set a name for the "ButtonProperty" for the Buttons,
and set numeric values for the "ButtonValues" of this Dialog.
Such values will be remembered by the installer and associated with the
assigned names.
- In other Editors, use the Condition property to examine the value
set for the Button in the previous step.
The actions represented by the other Editors will be done at the end
of the installation if the condition is true.
Passing data into a routine run during installation
(Kalani, pages 899-901)
Using the Global Assembly Cache
Requirements for Placing a Shared Assembly into the GAC
- The GAC is a central repository for routines which will be used by several
users.
- In order to avoid naming and versioning conflicts,
routines, to be placed in it, must be strongly named.
Strong names include
- a text name,
- a version number, which consists of four parts:
- major,
- minor,
- build,
- revision.
If you use an asterisk (*) for these last twobuild and
revisionyou will cause them to be reset at each compilation:
- The build will be set to the number of days since Jan. 1, 2000, and
- The revision will be set to the number of seconds since midnight,
divided by 2.
- QUESTION: What happens if you don't specify the last two
at all?
- QUESTION: What's the easiest way to see the version number
of an assembly? ILDASM?
- culture information, and
- a public/private key.
- An assembly may also have an optional Authenticode
signature.
You can get such a signature from a third party,
or you can fake it with a utility.
You assign such a signature to an assembly with the
File Signing Tool,
signcode.exe.
If you use both this and the Strong Name Tool,
sn.exe,
you must use the Strong Name Tool first.
(Kalani, box, page 884.)
Placing Shared Assemblies into the GAC
- There are at least four ways to place assemblies into the GAC:
gacutil /ldl
There is another way of looking at the contents of the GAC:
open a DOS box and then
cd to the GAC folder,  which should be
somewhere like c:\Windows\assemblies.
If you do this, you will see that the structure is not as simple as
Windows Explorer would have you believe.
There is, in fact,
- a subdirectory for each assembly, and
- subdirectories under that for the various versions and
public keys.
This raises a serious problem for adding references to a routine that wants
to use an assembly in the GAC: it is difficult to find exactly the
location of that assembly.
Kalani (page 878) says that
- You should keep a second
copy of the assembly in a known folder, and
- This is, in fact, what .NET does:
each assembly in the GAC is also held in "the folder where the
.NET Framework is installed" (wherever that is).
Remember that the Reference needed by your routine is only to give infomation
about the methods and their parameters; it is the version in the GAC
that will be loaded, not the Reference version of the assembly.
(On pages 878-879, Kalani shows how to register the folder
outside the GAC that has the second copy of the assembly,
for purposes of Reference. Note that this is the
regedit version of the Registry Editor,
which acts on this machine, not the target machine.)
(On pages 885-886, Kalani has an example of a Merge Module project
that places a DLL in the GAC and another location outside the GAC
and registers the one outside the GAC.
This project uses the Registry Editor that registers things on the target
machine. See "Merge Modules", below.)
Remember these questions?
When can you use a direct reference instead of the GAC?
When can you deploy in the application's folder
instead of the GAC?
They came up in legacy code, chapter 9.
ONE MORE QUESTION: How does .NET know where the GAC is?
How the CLR Locates Assemblies
(Kalani, pages 880-881)
- It determines the version of the assembly to load.
It relies on the various config files
that were discussed in
Chapter 15, Configuring,
especially for the codebase and the
probing elements.
- It asks if the assembly is already loaded.
- It looks in the GAC.
- It uses the path specified in the
codebase element, if any.
See
Chapter 15, Configuring.
- If there is no culture information,
it looks in the application's installation directory and its
sub-directories, as defined by the
probing element.
See
Chapter 15, Configuring.
- If culture information is available,
it looks in the application's installation directory and its
sub-directories, using path names qualified by the cultural
information and the
probing element.
Delay-Signing
Merge Modules
(Kalani, pages 884-889)
These are used for packaging components such as DLLs.
(The description is placed here, after the explanation of the GAC,
because Merge Module contain shared assemblies you will almost certainly want to place
into the GAC.)
- Merge Modules cannot be distributed by themselves,
but must be included as part of an installation project for the routine
that uses the DLL.
- You package each version of such a DLL separately.
- Such a Merge Module package has the suffix .msm.
- Kalani's example on pages 885-886 shows a Merge Module project
that places a DLL in the GAC and another location outside the GAC
and registers the one outside the GAC.
- The DLL is placed into the GAC by the File System Editor, using
Add Special Folder /
Global Assembly Cache Folder
- QUESTION: Why does the Merge Module project need to place a version
of the DLL outside the GAC on the target machine?
Such an assembly is used for reference while assembling the the routine
that uses the DLL, but it is the version of that DLL in the GAC
that is loaded. Or does the JIT compiler need the reference?
Installation Components
It may happen during deployment that you will need to create components
on the target machine that cannot be created with the various deployment-customizing
editors described above. For instance, you may need to create
Performance Counters or Event Logs on the target machine.
To do this, you will have to write custom installation components.
We now come to the other possible meanings of the term "Installer".
Here is the complete list:
Meanings already discussed above:
- The installation package you set up with the "Setup Project" wizard,
which you may modify with the six setup editors.
This package, when compiled, comprises a single module,
with an extension of .msi.
Kalani describes the start of such a project on pages 846-849.
- The Windows "Installer" service which runs this
.msi package.
New meanings, discussed below:
- The Installer Class,
which you may instantiate to perform specific tasks during installation
of your code on a target machine.
- This Installer Class itself has a list
of Installers, which are themselves instances of the Class that install
components needed during installation of the whole.
An "Installer" may refer to any one of these.
- Your project may need a Performance Counter on the target machine.
A Performance Counter is installed by a specific routine, the
PerformanceCounterInstaller.
Each specifically designed one of these, then, is also an
"Installer".
- Install() is also the name of the principal method
in the "Installer" class.
- "Installer" may also refer to the Windows utility,
installutil.exe,
that runs your instantiation of this Installer
Class.
The Installer Class
Namespace: System.Configuration.Install
Important members:
- Installers.
A list of Installer objects required for this current Installer
to complete its work.
- Install().
The method that does the positive work of installing the component.
- Commit().
These Installers are transactional. This
Commit()
method is run if the Install() method
finished successfully.
- QUESTION: How does the system know that the
Install() has failed?
- Rollback().
Executed if the Install() method failed.
- Uninstall(). Removes an installed component
previously installed successfully by this object's
Install() method.
Distinguish it from Rollback().
Required Attribute: add
[RunInstaller(true)]
to your class definition to get your Installer object to run during a setup project.
The .InstallState file remembers the state
of the installation.
It is created by the Install()
method, and is used both by the
Rollback() and the
Uninstall() methods.
An assembly containing such Installers may be run two ways:
- With the setup and deployment projects as described above.
You add connections to the Custom Actions Editor,
as in Kalani's example on page 895.
- With the Installer tool, installutil.exe
An installed assembly may be uninstalled with this command:
installutil.exe /u Foo.dll
Here is an example of such an install module, taken from Kalani's example
on pages 899-900.
It is here just to show what the code looks like.
The code is not complete:
[RunInstaller(true)]
public class Foo : System.Configuration.Install.Installer
{
public Foo()
{
// This call is required by the Designer.
InitializeComponent();
// TODO: Add any initialization after the InitComponent call
}
public override void Install(System.Collections.IDictionary savedState)
{
// call the Install method of the base class
base.Install(savedState);
// Get the arguments pass to the class
string strArgs = this.Context.Parameters["Args"];
if (strArgs == "")
throw new InstallException("No arguments specified");
//HERE DO THE WORK TO INSTALL THE COMPONENT.
}
public override void Commit(System.Collections.IDictionary savedState)
{
// call the Commit method of the base class
base.Commit(savedState);
}
public override void Rollback(System.Collections.IDictionary savedState)
{
// call the Rollback method of the base class
base.Rollback(savedState);
}
public override void Uninstall(System.Collections.IDictionary savedState)
{
// call the Uninstall method of the base class
base.Uninstall(savedState);
}
}
When you add, say, an Event Log to your app, you will see,
in the properties window for the Event Log you have added, an option to
"Add Installer". If you do this, you will get an entire module
generated by the IDE. An example follows.
You will note that it has no
Install() or
Commit(), etc., methods.
These methods are in the base class,
System.Configuration.Install.Installer.
All that this derived class has, in the
InitializeComponent() method
at the end, is the creation of an
System.Diagnostics.EventLogInstaller
object, itself derived from the
Installer class, and the
addition of this instance to the container's
Installers property.
All of this code is here just to be informative
(if not intimidating). I doubt any of it will come up on the exam.
using System;
using System.Collections;
using System.ComponentModel;
using System.Configuration.Install;
namespace InstallTest
{
[RunInstaller(true)]
public class ProjectInstaller : System.Configuration.Install.Installer
{
private System.Diagnostics.EventLogInstaller eventLogInstaller1;
private System.ComponentModel.Container components = null;
public ProjectInstaller()
{
InitializeComponent();
// TODO: Add any initialization after the InitializeComponent call
}
protected override void Dispose( bool disposing )
{
if( disposing )
{
if(components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Component Designer generated code - do not modify
private void InitializeComponent()
{
this.eventLogInstaller1 = new System.Diagnostics.EventLogInstaller();
//
// eventLogInstaller1
//
this.eventLogInstaller1.Log = "Application";
this.eventLogInstaller1.Source = "InstallTest";
//
// ProjectInstaller
//
this.Installers.AddRange
(new System.Configuration.Install.Installer[] {this.eventLogInstaller1} );
}
#endregion
}
}
URL Remoting and Security Considerations
It is possible to set up your app on a server (one not running .NET)
and have Internet Explorer (not a Windows app) navigate to the URL
for the server, download the app, and run it.
(Kalani, example, pages 903-904)
This sort of thing obviously raises security concerns.
Such downloaded modules are stored in the download cache,
which, though not physically attached to the GAC,
can be viewed by Windows Explorer
(using shfusion.dll)
as if it were. Since the download cache remembers the source of its
modules, the system can assign code access security settings to them.
Such modules can be allowed to run, or can be prevented from running,
by modifying the security settings for the machine.
Some DLLs on the local machine are willing to operate even though
the code invoking them is not fully trusted, because they
have the AllowPartiallyTrustedCallers
attribute set.
But not all local DLLs have this setting: specifically,
System.Data.SqlCLient.SqlConnection does not.
If you want to run code from foreign sources that use such DLLs,
you will have to modify the security settings on your machine.
You do this with the .NET Framework Configuration Tool.
You can revise the settings for the machine or for a user, and for a
code source (such an Intranet or the entire Internet) or
for an individual assembly.
You may also assign levels of trust to particular trusted Internet sites.
You can assign one of four levels of trust:
None, Internet, Local Intranet, and Full Trust.
(Kalani, pp. 911-914)
Methods of Deployment
Removable media (floppies, CDs, DVDs)
may be used for deployment.
They must have their files packaged to fit,
using the "Cabinet Files" option.
Deployment may also be done over a network.
You do not have to create CAB files if you do this.
You put the compiled setup package in a shared network folder.
Deployment may also be web-based.
So far as I can tell, this is the same as network deployment,
except that the compiled setup package goes into a virtual directory on a Web server.
Administrative Installation
(Kalani, pages 917-918)
You do this when you're deploying to a large number of users.
You do two things:
- The administrator creates an "administrative installation point"
on a network by running Windows Installer from the command line:
msiexec /a Foo.msi
This is only done once.
- Users then install the app by running
setup.exe from
the administrative installation point.
This point is to cut down on installation time, and to insure
that all installations are the same. Advantages:
- One set of application files in a central location
- Standard configuration for all users
- Control over installation
- Control over upgrades
Windows Logo Program Requirements
- The Certified for Microsoft Windows Logo Program
- The Designed for Microsoft Windows XP Logo Program
- The Microsoft .NET Connected Logo Program
I think this is all guff, and I would be amazed
if you get a question about any of it.
Summary
This has been presented in far too much detail.
Here is what you should know:
- What each of the six Editors does, and the converse:
how you would do each of the things done by each Editor
- How to pass data from an Editor into a program
you want to run on the target machine
- Several things about shared assemblies.
This is the most important stuff in the chapter.
- How to put stuff into the GAC (there are four ways)
- Why put stuff in the GAC
- The requirements for putting stuff in the GAC, especially
- The components of a strong name
- When you can deploy in the application's folder instead of the GAC
- Some facts about DelaySigning
- What DelaySigning is and why you would use it
- A couple of different ways to specify it
- How you get stuff into the GAC even with it set
- How you can then full-sign an assembly and get a formerly
DelaySigned assembly into the GAC, now that it's fully signed
- Custom Installers what they are and why you would use them
- MergeModulessame questions
- What an administrative installation is, and the point of it
- As for the security considerations: these should be reviewed
along with the fuller treatment in chapter 15.
The value of chapters like this is that they're not as hard as they look,
and if you put in a little effort here,
it will bring up your grade and defend it against questions about details in, say, Controls, that you have no idea about.
The (parenthesized references)
in the above list are explained here.
Here are the relevant questions from the two tests at the end
of the "short Kalani" book:
Test 1: questions
47 (page 379; answer: page 397),
50, 52, 53.
- Test 1, question 51: Doesn't this conflict with Kalani,
page 850? .NET is already excluded.
And I still don't see what's wrong with answer C.
- Test 1, question 52: see Kalani, page 848.
Test 2: questions
47 (page 429; answer: page 447),
58, 59, 60.
- Test 2, question 47: The exclusion of "D" from the list
of correct answers has to pass as humor in these tests.
- Test 2, question 58: Note that the answers are not in order.
- Test 2, question 59: Duh.
- Test 2, question 60: WOOF!
Just how awful can a question be?
(Some of these questions may duplicate those in long Kalani.
Both texts are listed
here.)
Last revised Dec. 10, 2004