
Professional Visual Studio 2005 (2006) [eng]
.pdf
Chapter 47
Figure 47-1
After acknowledging the Setup Wizard splash screen, the first decision is specifying whether you want to create an installer or a redistributable package. For an installer, it is important to select either a Windows application or a web application installer. The basic difference is that the Windows application installer places the application in the appropriate folder within Program Files, whereas the web application installer creates a virtual directory under the root folder for the specified web site. In the case of a redistributable package, the choice is between a merge module, which can be integrated into a larger installer, or a CAB file.
Regardless of the type of deployment project you are creating, the next step in the Setup Wizard is the most important because it determines the set of files to be deployed. Figure 47-2 shows the third screen in the Setup Wizard, which prompts you to select which files or project outputs will be included in the deployment project. In this case, the primary output for our DeploymentSample application has been selected, as you want to include the main executable and any assemblies on which this executable depends. In the remaining step in the Setup Wizard, you can choose to add files that were not part of any existing project. This might include release notes or README files.
Once the deployment project has been created, it is added to the Solution Explorer, as shown in Figure 47-3. Although you didn’t explicitly add any files or output from the MainClassLibrary to the deployment project, it has been added as a calculated dependency. If the dependencies are guaranteed to exist on the target computer, they can be manually excluded from the deployment project by selecting the Exclude item from the right-click context menu. For example, if this were an add-in for another application that already has a copy of the MainClassLibrary, you could exclude that from the dependency list. The resulting installer would be smaller, and thus easier to deploy.
When a deployment project (DeploymentInstaller) is selected, a number of new icons appear across the top of the Solution Explorer window. Clicking the first icon (Properties) opens the Property Pages dialog, as shown in Figure 47-4, which can be used to customize how the deployment module is built. This dialog can also be accessed via the Properties item on the right-click context menu for the deployment project in the Solution Explorer.
666

Deployment: ClickOnce and Other Methods
Figure 47-2
Figure 47-3
Figure 47-4
667

Chapter 47
By default, the Package Files property is set to In Setup File, so all executables and associated dependencies are placed into the .msi file that is created. The deployment project also creates a Setup.exe file that checks for minimum requirements, such as the presence of the .NET Framework, prior to calling the .msi file to install the application. Although the compression can be adjusted to optimize for file size, including everything into a single distributable might be an issue for large projects. An alternative, as shown in Figure 47-4, is to package the application into a series of CAB files. In this scenario, the size
of the CAB file is limited to 100Kb, as this will aid deployment over a slow network. Another scenario where this would be useful is if you were planning to deploy your application via CD and your application exceeded the capacity of a single CD.
The final property on this page is the Installation URL. If you are planning to deploy your application via a web site, you can select to package everything into a single file, in which case you do not need to specify the Installation URL because you can simply add a reference to the Setup.exe file to the appropriate web site and a user can install the application simply by clicking on the link. Alternatively, you can package your application into smaller units that can be incrementally downloaded. To do this you must specify the Installation URL from which they will be installed.
As just discussed, the default deployment project creates a Setup.exe file. The Prerequisites button opens a dialog like the one shown in Figure 47-5, where you can configure the behavior of this file. You can indicate that a setup file should not be created, in which case the application can be installed by double-clicking the .msi file. This, of course, removes the initial check to ensure that the .NET Framework has been installed.
Figure 47-5
In addition to the .NET Framework, you can also specify that other components, such as MDAC, need to be installed. These checks will be carried out, and the user prompted to install any missing components prior to the main installer file being invoked.
668

Deployment: ClickOnce and Other Methods
Just to confuse matters, there is an additional Properties window for deployment projects that can be opened by selecting the appropriate project and pressing F4. This opens the standard Properties window, shown in Figure 47-6, which can be used to tailor the deployment for the application it is installing.
Figure 47-6
The properties for the deployment project shown on this screen configure the appearance, icons, and behavior of the installation wizard. It is highly recommended that you adjust these properties so your application is easily identifiable in the Add/Remove Programs dialog and the installation looks professional, rather than half finished.
Customizing the Installer
The remaining icons at the top of the Solution Explorer are used to customize what is included in the deployment package. In addition to the shortcut icons, these views of the deployment project can be accessed via the View item on the right-click context menu. Start with the File System view, which indicates where files will be installed on the target machine. By default, the primary output for a Windows application is added to the Application Folder, as shown in Figure 47-7. Selecting this node and looking at the Properties window shows that this folder has a default location of [ProgramFilesFolder] [Manufacturer]\[ProductName]. This location is made up of three predefined installation variables: ProgramFilesFolder, Manufacturer, and ProductName, which will be evaluated and combined during installation. As you will see later, the installation wizard allows users to change this location when they install the application.
669

Chapter 47
Earlier you saw that the DeploymentSample application had a dependency on the MainClassLibrary assembly. Here this assembly has been removed from the Application Folder and placed instead in the Global Assembly Cache Folder. When this application is installed, the main executable will be installed in the relevant directory under Program Files, but the MainClassLibrary will be installed in the Global Assembly Cache so it is available to any .NET application. To achieve this, you first need to create the new folder in the File System view by selecting the Global Assembly Cache Folder from the Add Special Folder item on the right-click context menu. You can install files to a number of other special folders as part of the installer. The next step is to move the MainClassLibrary assembly to the Global Assembly Cache by selecting the assembly in the right pane of the File System view and changing the Folder property from Application Folder to Global Assembly Cache Folder.
Figure 47-7
In addition to installing files on the target machine, you can also add keys to the registry. Some developers argue for and other developers argue against the use of the registry. Although it can provide a convenient store for per-user configuration information, the new application settings with user scope are an alternative that makes them easier to manage. The Registry view, as shown in Figure 47-8, can be used to add registry keys and values. To add a new key, right-click the appropriate node in the Registry tree and select Add Key from the context menu. To add a new value, right-click the appropriate key in the Registry tree and select the type of value from the New item on the context menu anywhere on the pane on the right of Figure 47-8. The Name and Value can then be set using the Properties window.
Figure 47-8
Figure 47-9 shows the File Types view of the deployment project. This view is used to add file extensions that should be installed. For example, in this case you are installing the extension .nic. You can specify an icon for this type of file as well as specify the executable that should be called for this file type. In most cases this will be the primary output for your application. To add a new file type, right-click the root node of the File Types tree and select Add File Types from the context menu. This creates a node for the new file type and for the default action (in bold) for that file type. For the .nic extension, the default action is Open, and it can be executed by double-clicking a file of the appropriate file type. The Open action also appears, again in bold, in the right-click context menu for a file with the .nic extension.
670

Deployment: ClickOnce and Other Methods
Other actions can be added for this file type by selecting Add Action from the right-click context menu for the file type. An alternative action can be made the default by selecting Set as Default from that action’s context menu. You can change the order in which the actions appear in the context menu by moving the action up or down in the tree.
Figure 47-9
.NET applications can be autonomous so that their list of dependencies only contains the .NET Framework. However, web applications require IIS, and more complex applications may require SQL Server to be installed. Checking for these dependencies can be done using a launch condition via the view shown in Figure 47-10. By default, the .NET Framework is added to this launch condition. Previously you saw that Setup.exe also did a check for the .NET Framework and would install it if it was not found. Launch conditions are embedded in the .msi file and, unlike conditions in the Setup.exe file, are validated even if the .msi file is installed directly. The only limitation is that the launch conditions only provide a warning message and a URL reference for more information.
Figure 47-10
Figure 47-10 shows the Launch Conditions view of the deployment project. This view is actually split into two sections. The top half of the tree is used to specify searches to be performed on the target machine. Searches can be carried out for files, for installed components or applications, and for registry values. Properties for a file search include the search folder, version and modification dates, and file size. To search for an installed component, you need to know the Component ID, which is embedded in the
.msi file used to install the product. This information can be retrieved using a product such as MSI Spy, which is included in the Windows Installer SDK that can be downloaded from the Microsoft web site (www.microsoft.com/downloads/). A registry search requires properties indicating the key, name, and value to search for. In each of these cases the search needs to be assigned a Property identifier. If the search is successful, the installer property with that identifier is True.
The Property identifiers assigned to searches on the target machine can be used by a launch condition in the lower half of the tree. As you can see in Figure 47-10, there is a condition that checks for the .NET Framework, as well as another launch condition. The Condition property is set to a logical AND operation across the three search results. If any of the searches fail, the associated property identifier is replaced with False, making the whole logical expression false. This results in the application failing to install, and a warning message will be displayed.
671

Chapter 47
Note that some other views have a Condition property for some of the tree nodes. For example, in the File System view, each file or output has a Condition property that can be specified. If this condition fails, the file is not installed on the target machine. In each of these cases the syntax of the Condition property must be valid for the MsiEvaluateCondition function that is called as part of the installation process. This function accepts standard comparison operators, such as equals (=), not equals (<>), less than (>), and greater than (<), as well as Boolean operators NOT, AND, OR, and XOR. There are also some predefined Windows installer properties that can be included in the condition property. The following is a subset of the full list, which can be found in the documentation for the Windows Installer SDK:
ComputerName: Target computer name
VersionNT: Version of Windows NT/2000 on the target computer
ServicePackLevel: The service pack that has been installed
LogonUser: The username of the current user
AdminUser: Whether the current user has administrative privileges
COMPANYNAME: The company name, as specified in the installation wizard
USERNAME: The username, as specified in the installation wizard
One of the main reasons for creating an installer is to make the process of deploying an application much smoother. To do this you need to create a simple user interface into which an end user can specify values. This might be the installation directory or other parameters that are required to configure the application. Clearly, the fewer steps in the installer the easier the application will be to install. However, it can be better to prompt for information during the installation than for the user to later sit wondering why the application is not working. The User Interface view, shown in Figure 47-11, enables you to customize the screens that the user sees as part of the installation process.
Figure 47-11
Two user interfaces are defined in this view: the standard installation and an Administrative install (not visible). Both processes follow the same structure: Start, where you typically collect information from the user prior to installing the product; Progress, used for providing a visual cue as to the installation’s progress; and End, at which point the user is presented with a summary of the installation. The
Administrative install is typically used when a network setup is required, and can be invoked by calling msiexec with the /a flag.
You can customize either of the installation processes by adding and/or removing dialogs from the user interface tree. To add a new dialog, right-click any of the three stages in the installation process and select Add Dialog from the context menu. This displays a list of the predefined dialogs from which
you can choose. Each of the dialogs has a different layout; some are used for accepting user input while
672

Deployment: ClickOnce and Other Methods
others are used to display information to the user. Input controls are allocated a property identifier so that the value entered during the installation process can be used later in the process. For example, a checkbox might be used to indicate whether the tools for a product should be installed. A condition could be placed on an output in the File System view so the tools are only installed if the checkbox is enabled.
Adding Custom Actions
It is often necessary to perform some actions either prior to or after the application is installed. To do this, you can create a custom action to be executed as part of the install or uninstall process. Adding a custom action entails creating the code to be executed and linking the appropriate installer event so that the code is executed. Custom actions use an event model similar to what Windows components use to link the code that you write to the appropriate installer event. To add a custom action to an installer event, you need to create a class that inherits from the Installer base class. This base class exposes a number of events for which you can write event handlers. Because writing custom installer actions is quite a common task, the Add New Item dialog includes an Installer Class template item. The new class opens using the component designer, as shown in Figure 47-12.
Figure 47-12
From the Events tab of the Properties window, select the installer event for which you want to add an event handler. If no event handler exists, a new event handler will be created and opened in the code window. The following code is automatically generated when an event handler is created. A simple message box is inserted to notify the user that the AfterInstall event handler has completed:
Imports System.ComponentModel
Imports System.Configuration.Install
Public Class CustomActions
Public Sub New()
MyBase.New()
InitializeComponent()
End Sub
Private Sub CustomActions_AfterInstall(ByVal sender As Object, _ ByVal e As InstallEventArgs) _
Handles Me.AfterInstall
MsgBox(“Installation process completed!”) End Sub
End Class
673

Chapter 47
As with forms and other components, the rest of this class is stored in a designer class file. The rest of the class definition is as follows:
<System.ComponentModel.RunInstaller(True)> _ Partial Class CustomActions
Inherits System.Configuration.Install.Installer
‘The Dispose and InitializeComponent methods have been omitted as they do
‘not add anything to the code sample
End Class
Here you can see that the partial CustomActions class inherits from the Installer class and is attributed with the RunInstaller attribute. This combination ensures that this class is given the opportunity to handle events raised by the installer.
The CustomActions class you have just created was added to the MainClassLibrary assembly. For the events to be wired up to the CustomActions class, the installer needs to know that there is a class that contains custom actions. To make this association, add the MainClassLibrary assembly to the Custom Actions view for the deployment project by right-clicking any of the nodes shown in Figure 47-13 and selecting Add Custom Action from the context menu. In this case, you want to wire up the MainClassLibrary. In Figure 47-13, this association has only been made for the Install action. If you want to wire up the custom action class for all of the actions, you need to add the custom action to the root Custom Actions node.
Figure 47-13
To complete this discussion, understand that it is important to be able to pass information collected from the user during the Start phase of the installation process to the custom action. Unfortunately, because the custom action is invoked after the installer has finished, you have to use a special channel to pass installer properties to the custom action event handler. In the Custom Actions view (refer to Figure 47-13), select Properties Window from the right-click context menu for the Primary output node. The CustomActionData property is used to define name/value pairs that will be sent through to the custom installer. For example, you might have /PhoneNumber= “+1 425 001 0001”, in which case you can access this value in the event handler as follows:
Private Sub CustomActions_AfterInstall(ByVal sender As Object, _ ByVal e As InstallEventArgs) _
Handles Me.AfterInstall MsgBox(“Phone number: “ & Me.Context.Parameters(“PhoneNumber”).ToString)
End Sub
674

Deployment: ClickOnce and Other Methods
Of course, hard-coded values are not a good idea and it would be better if this were a user-specified value. To use a property defined in the installer user interface, replace the specified string with the property identifier in square brackets. For example, /PhoneNumber=[TxtPhoneNumber] would include the text in the TxtPhoneNumber text box.
Web Project Installers
As mentioned earlier in this chapter, there are some slight differences when it comes to creating installers for web projects. In earlier versions of Visual Studio, the typical installer was limited to installing the application into a virtual directory on the default web site. Unfortunately, a large number of organizations support multiple web sites for applications such as SharePoint, Team Foundation Server, and other sites. A significant improvement in the template installer that comes with Visual Studio 2005 enables users to select which web site to install the web application onto, as shown in Figure 47-14.
Figure 47-14
In the past, the web site installation wizard would prompt the user to specify the name of the virtual directory into which the application was to be installed, and this directory would then be created in the default web site. If multiple web sites were hosted on the same server (often the case with products such as SharePoint installed), then this could result in the application being installed on the wrong web site. Being able to specify the web site during installation reduces any post-installation administration that would have been required in the past.
675