1) 操作流程
Vs2008中,“新建系统服务”,如上图
右键“添加安装程序”(vs2010中可以系统服务文件上添加),如上图
添加后的安装程序中会有2个控件,如上图
编译后生成一个xx.EXE的文件
服务注册和卸载代码片段:
注:服务的安装与卸载需要,windows中一个自带的程序“InstallUtil.exe”(我也记不起在什么地有这个程序了,搜了一下C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727这里有。)放在Bin文件夹下!
方法一:
/// <summary> ///iType: 1=注册服务 /// </summary> bool InstallOrUinstallService ( string sFileName , int iType ) { bool isSucc = true; ProcessStartInfo objProcessInf = new ProcessStartInfo ( ); objProcessInf.FileName = Application.StartupPath + "\\InstallUtil.exe "; objProcessInf.CreateNoWindow = false; objProcessInf.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden; if ( iType == 1 )//1=注册服务 objProcessInf.Arguments = "\"" + Application.StartupPath + "\\" + sFileName + "\" -i"; else objProcessInf.Arguments = "\"" + Application.StartupPath + "\\" + sFileName + "\" -u"; try { System.Diagnostics.Process objProcess = System.Diagnostics.Process.Start ( objProcessInf ); objProcess.WaitForExit ( ); } catch { isSucc = false; } return isSucc; }方法二:
System.Diagnostics.Process uiProcess = new Process ( ); ProcessStartInfo uiPSI = new ProcessStartInfo ( Application.StartupPath + "\\InstallUtil.exe" ); /// <summary> /// 安装服务 /// </summary> /// <param name="ServicePath">服务文件路径</param> public bool installService ( string ServicePath , ref StreamReader sr ) { try { uiPSI.CreateNoWindow = false; uiPSI.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden; uiPSI.Arguments = ServicePath; uiProcess.StartInfo = uiPSI; uiProcess.Start ( ); uiProcess.WaitForExit ( ); return true; } catch { return false; } } /// <summary> /// 卸载服务 /// </summary> /// <param name="ServicePath">服务文件路径</param> public bool uinstillService ( string ServicePath ) { try { uiPSI.CreateNoWindow = false; uiPSI.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden; uiPSI.Arguments = "/u " + ServicePath; uiProcess.StartInfo = uiPSI; uiProcess.Start ( ); uiProcess.WaitForExit ( ); return true; } catch { return false; } }2) 服务类、属性
Ø ServiceProcessInstaller 类
安装一个可执行文件,该文件包含扩展 ServiceBase 的类。该类由安装实用工具(如 InstallUtil.exe)在安装服务应用程序时调用。
命名空间:System.ServiceProcess
当 InstallUtil.exe 运行时,该实用工具在服务程序集内查找 RunInstallerAttribute 设置为 true 的类。通过将类添加到与项目安装程序关联的 Installers 集合来向服务程序集添加类。如果 RunInstallerAttribute 为 false,安装实用工具将忽略项目安装程序。
ServiceProcessInstaller 成员
Account 获取或设置运行该服务应用程序时所使用的帐户类型、指定该服务是在计算机的系统帐户、本地或网络服务帐户还是用户帐户下运行
设置为 User,则在安装时将提示您输入有效的用户名和密码。
如果是本地服务建议使用:LocalSystem
Installer.Parent 获取或设置包含该安装程序所属的集合的安装程序。 如果 Installer 的此实例是安装程序集合的一部分,则 Parent 属性设置为包含该集合的 Installer 实例。
Modifiers 和 GenerateMember 属性
GenerateMember 属性指定 Windows 窗体设计器何时为组件生成成员变量。
Modifiers 属性是指定给该成员变量的访问修饰符。
如果 GenerateMember 属性的值为 false,则 Modifiers 属性没有效果。
ServiceInstaller 类
安装一个类,该类扩展 ServiceBase 来实现服务。在安装服务应用程序时由安装实用工具调用该类。
ServiceInstaller 执行特定于其所关联服务的操作。它由安装实用工具用来将与服务关联的注册表值写入 HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services 注册表项内的子项。服务由它在该子键内的“服务名”(ServiceName) 标识。该子键还包含服务所属的可执行文件或 .dll 的名称。
ServiceName 与从 ServiceBase 派生的类的 ServiceBase.ServiceName 相同至关重要。(也就是在创建服务项时输入的服务名称)通常,服务的 ServiceBase.ServiceName 属性的值在该服务应用程序可执行文件中的 Main() 函数中设置。“服务控制管理器”使用 ServiceInstaller.ServiceName 属性在此可执行文件中定位服务。
DisplayName
用在“服务控制管理器”中为服务提供用户可读的描述性名称。DisplayName 是一个注册表值,但从不用作注册表项。因此,对 ServiceName 属性值的限制并不适用。ServiceName 用作 HKEY_LOCAL_MACHINES\System\CurrentControlSet\Services 注册表项,因此它是受限制的。
安装实用工具从不使用显示名称来标识服务,因此对名称选择没有像对 ServiceName 属性一样的限制。
Description 获取或设置服务的说明。
ServicesDependedOn 指示为使该服务能够运行而必须正在运行的服务。
服务可以要求在其能够启动之前其他服务处于运行状态。该属性中的信息写入注册表中的项。当用户(或自动启动情况下的系统)尝试运行服务时,“服务控制管理器”(SCM) 将验证数组中的每个服务是否都已启动。
如果数组中有任何服务未运行,则 SCM 尝试启动它们。这包括具有 ManualStartType 的服务。
如果该服务依赖的任何服务启动失败,则该服务不会启动。
Ø ServiceBase 类
当在服务应用程序中定义服务类时从 ServiceBase 派生。任何有用的服务均将重写 OnStart 和 OnStop 方法。对于其他功能,可以用特定行为重写 OnPause 和 OnContinue 来响应服务状态的更改。
服务是长时间运行的可执行文件,它不支持用户界面,在登录的用户帐户下可能无法运行。服务可以在没有任何用户登录计算机的情况下运行。
一个可执行文件可以包含多项服务,但对每项服务均必须包含一个单独的 ServiceInstaller。ServiceInstaller 实例在系统中注册服务。安装程序还将每项服务与一个事件日志关联,您可以使用该日志记录服务命令。可执行文件中的 main() 函数定义哪些服务应该运行。服务的当前工作目录是系统目录,而不是可执行文件所位于的目录。
当启动某项服务时,系统将定位相应的可执行文件,并运行该服务的 OnStart 方法(它包含在可执行文件内)。但是,运行服务与运行可执行文件并不相同。可执行文件仅加载服务。服务则通过“服务控制管理器”访问(例如启动和停止)。
当您对服务首次调用“开始”时,可执行文件调用 ServiceBase 派生类的构造函数。在构造函数执行之后将立即调用 OnStart 命令处理方法。在服务首次加载之后,构造函数不会再次执行,因此有必要将构造函数执行的处理和 OnStart 执行的处理分开。可以由 OnStop 释放的任何资源都应在 OnStart 中创建。如果服务在 OnStop 释放资源后再次启动,那么,在构造函数中创建资源会妨碍这些资源的正确创建。
在 main() 中设置的服务名称必须与服务安装程序的 ServiceName 属性完全匹配。
可以指定“应用程序”事件日志之外的日志来接收服务调用通知,但 AutoLog 和 EventLog 属性都不能写入自定义日志。如果不想使用自动记录,请将 AutoLog 设置为 false。
AutoLog 指示是否在事件日志中报告“开始”、“停止”、“暂停”以及“继续”命令。
CanHandlePowerEvent 获取或设置一个值,该值指示服务是否可以处理计算机电源状态更改通知。
CanHandleSessionChangeEvent 获取或设置一个值,该值指示服务是否可以处理从终端服务器会话接收到的会话更改事件。
CanPauseAndContinue 获取或设置指示服务是否可以暂停并再继续的值。
CanShutdown 获取或设置一个值,该值指示系统关闭时是否应通知服务。
CanStop 获取或设置一个值,该值指示服务启动后是否可以停止。
ExitCode 获取或设置服务的退出代码。
在停止服务前将 ExitCode 属性设置为一个非零值,以向服务控制管理器指出存在错误。
ServiceName 获取或设置用于向系统标识服务的简短名称。
本文详细介绍了如何在VS2008中创建系统服务,包括操作流程、安装与卸载代码实现以及服务类、属性的使用。重点讲解了如何利用`InstallUtil.exe`进行服务的注册与卸载,以及服务类如`ServiceProcessInstaller`、`ServiceInstaller`和`ServiceBase`的属性配置。提供了具体的代码示例,帮助开发者轻松实现系统服务的开发与管理。




被折叠的 条评论
为什么被折叠?



