安装一个类,该类扩展 ServiceBase来实现服务。在安装服务应用程序时由安装实用工具调用该类。
命名空间:System.ServiceProcess
程序集:System.ServiceProcess(在 system.serviceprocess.dll 中)
ServiceInstaller 执行特定于其所关联服务的操作。它由安装实用工具用来将与服务关联的注册表值写入 HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services 注册表项内的子项。服务由它在该子键内的“服务名”(ServiceName) 标识。该子键还包含服务所属的可执行文件或 .dll 的名称。
若要安装服务,请创建从 Installer 类继承的项目安装程序类,并将该类的 RunInstallerAttribute 属性设置为 true。在项目中,为每个服务应用程序创建一个 ServiceProcessInstaller 实例,并为应用程序中的每个服务创建一个 ServiceInstaller 实例。在项目安装程序类构造函数中,使用 ServiceProcessInstaller 和 ServiceInstaller 实例设置服务的安装属性,并将这些实例添加到 Installers 集合中。
对于从 Installer 类派生的所有类,Install 和 Uninstall 方法中 Installers 集合的状态必须相同。但是,如果在自定义安装程序类构造函数中将安装程序实例添加到 Installers 集合,可以避免在 Install 和 Uninstall 方法中对集合进行维护。安装实用工具在被调用时将查找 RunInstallerAttribute 属性。如果该属性为 true,则实用工具将安装添加到 Installers 集合中、与项目安装程序关联的所有服务。如果 RunInstallerAttribute 为 false 或不存在,则安装实用工具忽略该项目安装程序。
与项目安装类关联的 ServiceProcessInstaller,安装项目中的所有 ServiceInstaller 实例的公共信息。如果该服务因故与安装项目中的其他服务分开,则由该方法安装此服务特定的信息。
注意 |
---|
ServiceName 与从 ServiceBase 派生的类的 ServiceBase.ServiceName 相同至关重要。通常,服务的 ServiceBase.ServiceName 属性的值在该服务应用程序可执行文件中的 Main() 函数中设置。“服务控制管理器”使用 ServiceInstaller.ServiceName 属性在此可执行文件中定位服务。 |
在将 ServiceInstaller 添加到项目安装程序的 Installers 集合之前或之后,均可修改其上的其他属性。例如,某服务的 StartType 可能设置为在重新启动时自动启动该服务或需要用户手动启动该服务。
通常,不在自己的代码中调用 ServiceInstaller 上的方法,这些方法通常只由安装实用工具来调用。在安装进程中,安装实用工具自动调用 ServiceProcessInstaller.Install 和 ServiceInstaller.Install 方法。必要时,它退出故障,方法是在以前安装的所有组件上调用 Rollback(或 ServiceInstaller.Rollback)。
安装实用工具调用 Uninstall 来移除对象。
使用项目安装程序的 Installer.Context,应用程序的安装例程自动维护有关已安装组件的信息。该状态信息作为 ServiceProcessInstaller 实例而持续更新,并且每个 ServiceInstaller 实例均由实用工具来安装。通常,不必通过代码显式修改此状态信息。
当安装执行时,它将自动创建一个 EventLogInstaller 来安装与 ServiceBase 派生类关联的事件日志源。该源的 Log 属性由 ServiceInstaller 构造函数设置为计算机的 Application 事件日志。当设置 ServiceInstaller 的 ServiceName(应与服务的 ServiceBase.ServiceName 相同)时,Source 自动设置为相同的值。安装失败时,源的安装与以前安装的服务一起回滚。
如果服务正在运行,则 Uninstall 方法将尝试停止该服务。无论成功与否,Uninstall 都将撤消由 Install 进行的更改。如果为事件日志创建了新源,则删除该源。
下面的示例创建名为 MyProjectInstaller 的项目安装程序,该程序从 Installer 继承。假定有一个服务可执行文件,它包含“Hello-World Service 1”和“Hello-World Service 2”两个服务。在 MyProjectInstaller 的构造函数(将被安装实用工具调用)内,ServiceInstaller 对象是为其中的每个服务创建的,ServiceProcessInstaller 是为可执行文件创建的。为使安装实用工具将 MyProjectInstaller 识别为有效安装程序,RunInstallerAttribute 属性被设置为 true。
首先在进程安装程序和服务安装程序上设置可选属性,然后向 Installers 集合添加这些安装程序。当安装实用工具访问 MyProjectInstaller 时,通过调用 InstallerCollection.Add 添加到 Installers 集合中的对象将依次安装。在该进程中,安装程序将维护状态信息,这些信息指示已安装了哪些对象,以便在发生安装失败时可依次退出各个对象。
通常,不显式创建项目安装程序类的实例。您可以创建该类并将 RunInstallerAttribute 属性添加到语法,但实际上是由安装实用工具来调用该类并初始化它。
using System; using System.Collections; using System.Configuration.Install; using System.ServiceProcess; using System.ComponentModel; [RunInstallerAttribute(true)] public class MyProjectInstaller: Installer{ private ServiceInstaller serviceInstaller1; private ServiceInstaller serviceInstaller2; private ServiceProcessInstaller processInstaller; public MyProjectInstaller(){ // Instantiate installers for process and services. processInstaller = new ServiceProcessInstaller(); serviceInstaller1 = new ServiceInstaller(); serviceInstaller2 = new ServiceInstaller(); // The services run under the system account. processInstaller.Account = ServiceAccount.LocalSystem; // The services are started manually. serviceInstaller1.StartType = ServiceStartMode.Manual; serviceInstaller2.StartType = ServiceStartMode.Manual; // ServiceName must equal those on ServiceBase derived classes. serviceInstaller1.ServiceName = "Hello-World Service 1"; serviceInstaller2.ServiceName = "Hello-World Service 2"; // Add installers to collection. Order is not important. Installers.Add(serviceInstaller1); Installers.Add(serviceInstaller2); Installers.Add(processInstaller); } }