需求
针对一种特殊的应用, 不需要显示gui, 希望常驻在windows服务当中,在必要的时候我们可以进行启动或开机启动。
这个时候我们就可以创建windowsservice 来实现。
创建windowsservice
下面演示了使用visualstudio2019创建一个基于.netframework的windows服务
项目结构如下所示:
包含了一个启动项以及一个服务类
右键查看 service1代码, 如下所示, 包含了重写onstart方法以及onstop方法:
public partial class service1 : servicebase { public service1() { initializecomponent(); } protected override void onstart(string[] args) { } protected override void onstop() { } }
当服务被启动, 即启动onstart方法内执行的代码, 而在servicebase当中, 同样提供了多种类型的方法被重写。
当我们写完了该服务的执行代码之后, 下一步我们要为其添加一个安装程序。
双击service1.cs, 然后右键添加安装程序,如下所示:
此时, 项目结构当中新增了一个默认名:projectinstaller.cs类, 而对应的设计页面如下所示:
serviceprocessinstaller1:
查看该类的属性,如下所示:
说明:
account: 默认设置为user, 当 account 属性为时 user , username 和 password 属性用于定义用于运行服务应用程序的帐户。
username和 password 对允许服务在除系统帐户之外的其他帐户下运行。 例如,如果没有用户登录,则可以允许服务在重新启动时自动启动。 如果保留 username 或 password 为空,并且将设置 account 为 user ,则在安装时系统将提示您输入有效的用户名和密码。
还可以指定服务在本地系统帐户下运行,或以本地或网络服务运行。 serviceaccount有关帐户类型的详细信息,请参阅枚举:
serviceinstaller1:
查看该类的属性,如下所示:
注: 该类扩展 servicebase 来实现服务。 在安装服务应用程序时由安装实用工具调用该类。
说明:
- delayedautostart : 若要延迟该服务的自动启动,则为 true;否则为 false。 默认值为 false。
- description : 服务的说明。 默认值为空字符串("")。
- displayname : 与服务关联的名称,常用于交互工具。
- servicename: 要安装的服务的名称。 该值必须在安装实用工具尝试安装服务以前进行设置。
- servicesdependedon : 在与该安装程序关联的服务运行以前必须运行的一组服务。
- starttype : 表示服务的启动方式。 默认值为 manual,指定在计算机重新启动后服务将不会自动启动。
控制windowsservice
创建完成服务之后, 接下来就是针对服务进行控制, 现在,可以使用 servicecontroller 类来连接和控制现有服务的行为。
servicecontroller: 表示 windows 服务并允许连接到正在运行或者已停止的服务、对其进行操作或获取有关它的信息。
通过servicecontroller,我们可以获取本机的service服务,以及启动、暂停、延续、挂起、关闭、刷新等动作, 如下所示:
下面的示例演示如何使用 servicecontroller 类来控制 service1 服务示例。
using system; using system.serviceprocess; using system.diagnostics; using system.threading; namespace servicecontrollersample { class program { public enum simpleservicecustomcommands { stopworker = 128, restartworker, checkworker }; static void main(string[] args) { servicecontroller[] scservices; scservices = servicecontroller.getservices(); foreach (servicecontroller sctemp in scservices) { if (sctemp.servicename == "service1") { // display properties for the simple service sample // from the servicebase example. servicecontroller sc = new servicecontroller("simple service"); console.writeline("status = " sc.status); console.writeline("can pause and continue = " sc.canpauseandcontinue); console.writeline("can shutdown = " sc.canshutdown); console.writeline("can stop = " sc.canstop); if (sc.status == servicecontrollerstatus.stopped) { sc.start(); while (sc.status == servicecontrollerstatus.stopped) { thread.sleep(1000); sc.refresh(); } } // issue custom commands to the service // enum simpleservicecustomcommands // { stopworker = 128, restartworker, checkworker }; sc.executecommand((int)simpleservicecustomcommands.stopworker); sc.executecommand((int)simpleservicecustomcommands.restartworker); sc.pause(); while (sc.status != servicecontrollerstatus.paused) { thread.sleep(1000); sc.refresh(); } console.writeline("status = " sc.status); sc.continue(); while (sc.status == servicecontrollerstatus.paused) { thread.sleep(1000); sc.refresh(); } console.writeline("status = " sc.status); sc.stop(); while (sc.status != servicecontrollerstatus.stopped) { thread.sleep(1000); sc.refresh(); } console.writeline("status = " sc.status); string[] argarray = new string[] { "servicecontroller arg1", "servicecontroller arg2" }; sc.start(argarray); while (sc.status == servicecontrollerstatus.stopped) { thread.sleep(1000); sc.refresh(); } console.writeline("status = " sc.status); // display the event log entries for the custom commands // and the start arguments. eventlog el = new eventlog("application"); eventlogentrycollection elec = el.entries; foreach (eventlogentry ele in elec) { if (ele.source.indexof("service1.oncustomcommand") >= 0 | ele.source.indexof("service1.arguments") >= 0) console.writeline(ele.message); } } } } } } //this sample displays the following output if the simple service //sample is running: //status = running //can pause and continue = true //can shutdown = true //can stop = true //status = paused //status = running //status = stopped //status = running //4:14:49 pm - custom command received: 128 //4:14:49 pm - custom command received: 129 //servicecontroller arg1 //servicecontroller arg2
安装windowsservice
能够控制我们创建的服务的前提是, 该服务已安装在我们调试的设备上, 我们可以通过assemblyinstaller 类来进行安装。
安装示例
在下面的示例中, assemblyinstaller 通过调用 assemblyinstaller 构造函数来创建。 设置此对象的属性,并 install commit 调用和方法以安装 myassembly.exe 程序集。
using system; using system.configuration.install; using system.collections; using system.collections.specialized; class assemblyinstaller_example { static void main() { idictionary mysavedstate = new hashtable(); console.writeline( "" ); try { // set the commandline argument array for 'logfile'. string[] commandlineoptions = new string[ 1 ] {"/logfile=example.log"}; // create an object of the 'assemblyinstaller' class. assemblyinstaller myassemblyinstaller = new assemblyinstaller( "myassembly.exe" , commandlineoptions ); myassemblyinstaller.usenewcontext = true; // install the 'myassembly' assembly. myassemblyinstaller.install( mysavedstate ); // commit the 'myassembly' assembly. myassemblyinstaller.commit( mysavedstate ); } catch (exception e) { console.writeline( e.message ); } } }
卸载示例
下面的示例演示的 uninstall 方法 installer 。 uninstall方法在的派生类中被重写 installer 。
// override 'uninstall' method of installer class. public override void uninstall( idictionary mysavedstate ) { if (mysavedstate == null) { console.writeline("uninstallation error !"); } else { base.uninstall( mysavedstate ); console.writeline( "the uninstall method of 'myinstallersample' has been called" ); } }
到此这篇关于c#创建控制windows服务的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持。