转自:https://blog.csdn.net/Code_May/article/details/123909870
c#应用Windows服务
背景
最近接到了一个有关进程通信的项目,主要实现的是客户的控制系统进程通过我们提供的接口向我们的软件发送消息执行动作,实现一个自动化的控制过程。通信模块主要是基于ZeroMQ实现的,在方案评审中大佬提出了,如果将通信模块直接加入我们的主工程会导致我们的软件和客户的进程耦合度较高。因此,需要添加一个中间层,将通信模块做成一个服务,然后提供一个单独的dll提供业务服务的接口。后续对接时,如果有业务上的变更,只需要维护这个dll即可。(说实话其实只理解了一半,具体这个服务和这个dll有什么关系还需要进一步了解windows服务这个东西之后才能有粗略的概念)
一、创建windows服务
1.创建windows服务工程项
2.修改服务的实现文件service1.cs
这个是创建工程之后自动生成的服务实现文件,需要重写void OnStart(string[] args)和void OnStop()函数,实现启动服务和停止服务的具体内容。
3.配置服务信息
- 双击cs文件进入设计界面
- 右键点击空白处,添加安装程序,可以看到新加入的projectinstaller.cs
- 将serviceProcessInstaller1的属性中的账户类型设置为localsystem
- 修改服务名称和服务描述
以上就完成了服务的编写,在安装该服务后,启用该服务、停止该服务会调用对应的函数。另说明:该服务工程项目编译完成后是一个exe,在安装时需要使用这个exe的路径。
二、安装、启动、停止、卸载服务
以下的serviceFilePath为服务的exe路径
1.安装服务
using (AssemblyInstaller installer = new AssemblyInstaller())
{
installer.UseNewContext = true;
installer.Path = serviceFilePath;
IDictionary savedState = new Hashtable();
installer.Install(savedState);
installer.Commit(savedState);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
2.启动服务
using (ServiceController control = new ServiceController(serviceName))
{
if (control.Status == ServiceControllerStatus.Stopped)
{
control.Start();
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
3.停止服务
using (ServiceController control = new ServiceController(serviceName))
{
if (control.Status == ServiceControllerStatus.Running)
{
control.Stop();
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
4.卸载服务
using (AssemblyInstaller installer = new AssemblyInstaller())
{
installer.UseNewContext = true;
installer.Path = serviceFilePath;
installer.Uninstall(null);
}
- 1
- 2
- 3
- 4
- 5
- 6
5.补充
由于操作服务需要一定的计算机访问权限,所以需要给安装服务的工程项目中添加一个应用程序清单文件,设置应用程序的访问权限。
右键点击工程项目->添加->应用程序清单文件
修改控制级别为下图所示:
三、总结
- 基于以上简单的例子可以了解如何实现一个服务,如何安装、应用服务。服务的入口主要有两个:启动、停止。
- windows服务还有以下几个特点:后台运行、即插即用、可开机自动启用,可长时间运行不影响其他在同一个计算机上的用户。
- 基于以上了解,感觉服务应该是一个轻量级的东西,解决方案生成的文件没有dll。应用方式应该是将服务与dll关联起来,让程序能够动态的加载这个模块(以上是个人猜想,后续可以再深入了解一下将dll注册到服务里的相关内容,理解这样的方式是解决什么问题的,需要哪些步骤)。
c#应用Windows服务
背景
最近接到了一个有关进程通信的项目,主要实现的是客户的控制系统进程通过我们提供的接口向我们的软件发送消息执行动作,实现一个自动化的控制过程。通信模块主要是基于ZeroMQ实现的,在方案评审中大佬提出了,如果将通信模块直接加入我们的主工程会导致我们的软件和客户的进程耦合度较高。因此,需要添加一个中间层,将通信模块做成一个服务,然后提供一个单独的dll提供业务服务的接口。后续对接时,如果有业务上的变更,只需要维护这个dll即可。(说实话其实只理解了一半,具体这个服务和这个dll有什么关系还需要进一步了解windows服务这个东西之后才能有粗略的概念)
一、创建windows服务
1.创建windows服务工程项
2.修改服务的实现文件service1.cs
这个是创建工程之后自动生成的服务实现文件,需要重写void OnStart(string[] args)和void OnStop()函数,实现启动服务和停止服务的具体内容。
3.配置服务信息
- 双击cs文件进入设计界面
- 右键点击空白处,添加安装程序,可以看到新加入的projectinstaller.cs
- 将serviceProcessInstaller1的属性中的账户类型设置为localsystem
- 修改服务名称和服务描述
以上就完成了服务的编写,在安装该服务后,启用该服务、停止该服务会调用对应的函数。另说明:该服务工程项目编译完成后是一个exe,在安装时需要使用这个exe的路径。
二、安装、启动、停止、卸载服务
以下的serviceFilePath为服务的exe路径
1.安装服务
using (AssemblyInstaller installer = new AssemblyInstaller())
{
installer.UseNewContext = true;
installer.Path = serviceFilePath;
IDictionary savedState = new Hashtable();
installer.Install(savedState);
installer.Commit(savedState);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
2.启动服务
using (ServiceController control = new ServiceController(serviceName))
{
if (control.Status == ServiceControllerStatus.Stopped)
{
control.Start();
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
3.停止服务
using (ServiceController control = new ServiceController(serviceName))
{
if (control.Status == ServiceControllerStatus.Running)
{
control.Stop();
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
4.卸载服务
using (AssemblyInstaller installer = new AssemblyInstaller())
{
installer.UseNewContext = true;
installer.Path = serviceFilePath;
installer.Uninstall(null);
}
- 1
- 2
- 3
- 4
- 5
- 6
5.补充
由于操作服务需要一定的计算机访问权限,所以需要给安装服务的工程项目中添加一个应用程序清单文件,设置应用程序的访问权限。
右键点击工程项目->添加->应用程序清单文件
修改控制级别为下图所示:
三、总结
- 基于以上简单的例子可以了解如何实现一个服务,如何安装、应用服务。服务的入口主要有两个:启动、停止。
- windows服务还有以下几个特点:后台运行、即插即用、可开机自动启用,可长时间运行不影响其他在同一个计算机上的用户。
- 基于以上了解,感觉服务应该是一个轻量级的东西,解决方案生成的文件没有dll。应用方式应该是将服务与dll关联起来,让程序能够动态的加载这个模块(以上是个人猜想,后续可以再深入了解一下将dll注册到服务里的相关内容,理解这样的方式是解决什么问题的,需要哪些步骤)。