饭饭TXT > 学习管理 > 《Visual Studio 2010 高级编程(英文出书版)》作者:Nick Randolph/等【完结】 > [Visual.Studio.2010.高级编程].Professional.Visual.Studio.2010.txt

第 141 页

作者:Nick Randolph/等 当前章节:15438 字 更新时间:2026-6-18 14:51

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 you can find in

the documentation for the Windows Installer SDK:

.

ComputerName: Target computer name

.

VersionNT: Version of Windows on the target computer

.

VersionNT64: The same value as VersionNT but this property is only set for 64-bit operating

systems

.

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 48-13, enables you to customize the screens that

the user sees as part of the installation process.

fiGure 48-13

970 .

chaPter 48 pAckAging And deploymenT

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 before 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 and 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 installed

only if the checkbox is enabled.

adding custom actions

It is often necessary to perform some actions either before 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 under the General node. The new class (added to the SharedResources project)

opens using the component designer, as shown in Figure 48-14.

fiGure 48-14

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:

Windows installers .

971

c#

using System.ComponentModel;

using System.Configuration.Install;

using System.Windows.Forms;

public partial class InstallerActions

{

public InstallerActions()

{

InitializeComponent()

}

private void InstallerActions_AfterInstall(object sender, InstallEventArgs e)

{

MessageBox.Show("Installation process completed!");

}

}

Code snippet SharedResources\InstallerActions.cs

Vb

Imports System.ComponentModel

Imports System.Configuration.Install

Imports System.Windows.Forms

Public Class InstallerActions

Public Sub New()

MyBase.New()

InitializeComponent()

End Sub

Private Sub InstallerActions_AfterInstall(ByVal sender As Object, _

ByVal e As InstallEventArgs) _

Handles Me.AfterInstall

MessageBox.Show("Installation process completed!")

End Sub

End Class

Code snippet SharedResources\InstallerActions.vb

As with forms and other components, the rest of this class is stored in a designer class file where

the partial InstallerActions 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 InstallerActions class you have just created was added to the SharedResources assembly.

For the events to be wired up to the InstallerActions class, the installer needs to know that there

is a class that contains custom actions. To make this association, add the SharedResources assembly

972 .

chaPter 48 pAckAging And deploymenT

to the Custom Actions view for the deployment project by right-clicking any of the nodes shown in

Figure 48-15 and selecting Add Custom Action from the context menu. In this case, you want to

wire up the SharedResources. In Figure 48-15, this association has been made only 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 48-15

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 48-15), 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:

c#

private void CustomActions_AfterInstall(object sender, InstallEventArgs e)

{

MessageBox.Show("Number: " + this.Context.Parameters["PhoneNumber"].ToString());

}

Code snippet SharedResources\CustomActions.cs

Vb

Private Sub CustomActions_AfterInstall(ByVal sender As Object, _

ByVal e As InstallEventArgs) _

Handles Me.AfterInstall

MessageBox.Show("Number: " & Me.Context.Parameters("PhoneNumber").ToString)

End Sub

Code snippet SharedResources\CustomActions.vb

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 textbox.

Windows installers .

973

the service installer

You can create an installer for a Windows Service the same way you would create an installer

for a Windows application. However, a Windows Service installer not only needs to install the

files into the appropriate location, but it also needs to register the service so it appears in the services

list. You can do this using the ServiceInstaller and ServiceProcessInstaller components

from the System.ServiceProcess namespace (you’ll probably need to add these to the Toolbox,

because they are not visible by default). An instance of each of these components needs to be

dragged onto the designer surface of a custom installer, as shown in Figure 48-16.

fiGure 48-16

The ServiceInstaller class is used to specify the display name (the name of the service as it

will appear in the Windows services list), the service name (the name of the service class that will

be executed when the service is run), and the startup type (whether it is manually started or

automatically started when Windows starts up). For each service you want to install, you need to

create a separate instance of the ServiceInstaller class, specifying a different display and service

name. Only a single instance of the ServiceProcessInstaller class is required, which is used

to specify the account information that the service(s) will run as. In the following example, the

InstallerForService constructor specifies that the class Service1 should be installed as a service,

and that it should automatically start using the NetworkService account:

c#

[RunInstaller(true)]

public partial class InstallerForService : System.Configuration.Install.Installer

{

const string SERVICE_DISPLAY_NAME = "My Generic Service";

const string START_AFTER_INSTALL = "STARTAFTERINSTALL";

const string NET_PROCESS_NAME = "Net";

const string NET_START = "Start \"{0}\"";

const int NET_WAIT_TIMEOUT = 5000;

const string NET_WAIT_ERROR = "WARNING: Process took longer than " +

"expected to start, it may need to be restarted manually";

public InstallerForService()

974 .

chaPter 48 pAckAging And deploymenT

{

InitializeComponent();

serviceInstaller1.DisplayName = SERVICE_DISPLAY_NAME;

serviceInstaller1.ServiceName = typeof(Service1).ToString();

serviceInstaller1.StartType = ServiceStartMode.Automatic;

serviceProcessInstaller1.Account = ServiceAccount.NetworkService;

}

private void InstallerForService_AfterInstall(object sender, InstallEventArgs e)

{

var startString = Context.Parameters[START_AFTER_INSTALL];

if (startString == "") return;

var shouldStart = Boolean.Parse(startString);

if (!shouldStart) return;

var proc = Process.Start(CreateNetStartProcessInfo());

if (!proc.WaitForExit(NET_WAIT_TIMEOUT))

MessageBox.Show(NET_WAIT_ERROR);

}

private ProcessStartInfo CreateNetStartProcessInfo()

{

return new ProcessStartInfo(NET_PROCESS_NAME,

String.Format(NET_START, SERVICE_DISPLAY_NAME))

{

WindowStyle = ProcessWindowStyle.Hidden

};

}

}

Code snippet Windows Service\InstallerForService.cs

Vb

Public Class InstallerForService

Const SERVICE_DISPLAY_NAME = "My Generic Service"

Const START_AFTER_INSTALL = "STARTAFTERINSTALL"

Const NET_PROCESS_NAME = "Net"

Const NET_START = "Start ""{0}"""

Const NET_WAIT_TIMEOUT = 5000

Const NET_WAIT_ERROR = "WARNING: Process took longer than " &

"expected to start, it may need to be restarted manually"

Public Sub New()

MyBase.New()

’This call is required by the Component Designer.

Windows installers .

975

InitializeComponent()

’Add initialization code after the call to InitializeComponent

ServiceInstaller1.DisplayName = SERVICE_DISPLAY_NAME

ServiceInstaller1.ServiceName = GetType(Service1).ToString

ServiceInstaller1.StartType = ServiceStartMode.Automatic

ServiceProcessInstaller1.Account = ServiceAccount.NetworkService

End Sub

Private Sub InstallerForService_AfterInstall(ByVal sender As System.Object,

ByVal e As System.Configuration.Install.InstallEventArgs) _

Handles MyBase.AfterInstall

Dim startString = Context.Parameters(START_AFTER_INSTALL)

If startString = "" Then Return

Dim shouldStart = Boolean.Parse(startString)

If Not shouldStart Then Return

Dim proc = Process.Start(CreateNetStartProcessInfo())

If Not proc.WaitForExit(NET_WAIT_TIMEOUT) Then

MessageBox.Show(NET_WAIT_ERROR)

End If

End Sub

Private Function CreateNetStartProcessInfo() As ProcessStartInfo

Dim startInfo = New ProcessStartInfo(NET_PROCESS_NAME,

String.Format(NET_START, SERVICE_DISPLAY_NAME))

startInfo.WindowStyle = ProcessWindowStyle.Hidden

Return startInfo

End Function

End Class

Code snippet Windows Service\InstallerForService.vb

Also included in this listing is an event handler for the AfterInstall event that is used to start

the service on completion of the installation process. By default, even when the startup is set to

automatic, the service will not be started by the installer. However, when uninstalling the service,

the installer does attempt to stop the service.

The user interface for this deployment project includes a Checkboxes (A) dialog using the User

Interface view for the project. Refer to Figure 48-13 for a view of the default user interface. Right-

目录
设置
设置
阅读主题
字体风格
雅黑 宋体 楷书 卡通
字体大小
适中 偏大 超大
保存设置
恢复默认
手机
手机阅读
扫码获取链接,使用浏览器打开
书架同步,随时随地,手机阅读
首 页 < 上一章 章节列表 下一章 > 尾 页