Windows Service 开发实例
最近写了一个需求,要求监控某款软件产生的Log日志,实时的处理txt文档内容,将数据清洗,整理之后存放到MongoDB中,用于后面分析人员使用情况。于是想到了用Windows Service进行开发。
1 新建Windows Service
直接选择新建->项目->Windows 服务
新建Windows Service
2 添加逻辑
选择项目下的Service,点击切换到代码
新增代码
在代码区域,可以看到新增的Service是继承ServiceBase类,代码中默认重写有OnStart 和OnStop两个方法,用于启动和停止是需要处理的逻辑。另外还有OnContinue ,onPause等方法,可以根据需求要求去实现代码。
代码区域
在项目中引入已经写好的实现逻辑类,WS只是调用执行即可,后期维护时只需要停止服务然后更新调用的dll文件。
namespace ProeLogWatcherWindowsService
{
public partial class ProeLogWatcherService : ServiceBase
{
public ProeLogWatcherService()
{
//服务名称
ServiceName = "ProeLogWatcherService";
InitializeComponent();
}
protected override void OnStart(string[] args)
{
try
{
EventLog.WriteEntry("启动服务");
FileWatcherHelper objWatcherHelper = new FileWatcherHelper();
objWatcherHelper.RunFileWatcher();
}
catch (Exception ex)
{
EventLog myLog = new EventLog();
myLog.Source = ServiceName;
myLog.WriteEntry(ex.Message, EventLogEntryType.Error);
myLog.Close();
}
}
protected override void OnStop()
{
EventLog.WriteEntry("停止服务");
}
}
}
EventLog.WriteEntry方法会写入信息到Windows日志中,方便管理查看,根据EventLogEntryType来指定日志级别。
EventLog
这样一个简单的Windows Service 调用逻辑完成,但是还无法安装到Windows系统中。
3 添加安装程序
点击Service回到视图页面,点击右键,选择“添加安装”
添加安装
成功后会跳到如下页面,选择Service,点击右键属性,完善在Window Service上显示的信息,
Service
选择installer,更改运行权限。
installer
安装程序完成,
4 安装到Windows 中
命令方式安装:
安装:InstallUtil.exe exe文件
卸载:InstallUtil.exe /u exe文件
InstallUtil.exe 路径:C:\Windows\Microsoft.NET\Framework64\v4.0.30319
通过ManagedInstallerClass 安装
ManagedInstallerClass 托管安装,用ServiceController判断是否已经存在,然后根据需要进行安装卸载。
ManagedInstallerClass
微软文档:https://msdn.microsoft.com/en-us/library/system.configuration.install.managedinstallerclass.aspx
Name | Description |
---|---|
InstallHelper(String[]) |
处理Installutil.exe 的方法 |
ServiceController 表示 Windows 服务并允许连接到正在运行或者已停止的服务、对其进行操作或获取有关它的信息。
微软文档:https://msdn.microsoft.com/zh-cn/library/system.serviceprocess.servicecontroller_methods(v=vs.80).aspx
常用的几个方法
Name | Description |
---|---|
Close |
断开此 ServiceController实例与服务的连接,并释放此实例分配的所有资源 |
GetDevices |
检索计算机上的设备驱动程序服务 |
GetServices |
检索计算机上的非设备驱动程序服务和不是驱动程序的服务。 |
GetServices |
检索计算机上的非设备驱动程序服务和不是驱动程序的服务。 |
Pause |
挂起服务的操作。 |
Start |
启动服务。 |
Stop |
停止该服务以及任何依赖于该服务的服务。 。 |
WaitForStatus |
等待服务达到指定状态。 |
安装类:
public class WindowServiceSetup
{
/// <summary>
/// 安装服务
/// </summary>
/// <param name="serverName"></param>
public void WindowServiceInstall(string serviceName)
{
string[] args=new string[1];
args[0] = serviceName;
try
{
ManagedInstallerClass.InstallHelper(args);
}
catch (Exception ex)
{
throw ex;
}
}
/// <summary>
/// 卸载服务
/// </summary>
/// <param name="serviceName"></param>
public void WindowServiceUnInstall(string serviceName)
{
string[] args = new string[2];
args[0] = "/u";
args[1] = serviceName;
try
{
ManagedInstallerClass.InstallHelper(args);
}
catch (Exception ex)
{
throw ex;
}
}
/// <summary>
/// 检查服务是否存在
/// </summary>
/// <param name="svcName"></param>
/// <returns></returns>
public bool ServiceIsExisted(string svcName)
{
ServiceController[] services = ServiceController.GetServices();
foreach (ServiceController s in services)
{
if (s.ServiceName == svcName)
{
return true;
}
}
return false;
}
/// <summary>
/// 启动服务
/// </summary>
/// <param name="serviceName">服务名</param>
/// <returns>是否启动成功</returns>
public bool StartService(string serviceName)
{
ServiceController sc = new ServiceController(serviceName);
if (sc.Status != ServiceControllerStatus.Running)
{
try
{
sc.Start();
sc.WaitForStatus(ServiceControllerStatus.Running); // 等待执行完成
}
catch
{
return false;
}
}
return true;
}
/// <summary>
/// 停止服务
/// </summary>
/// <param name="serviceName">服务名</param>
/// <returns>是否停止服务成功,如果服务启动后不可以停止,则抛异常</returns>
public bool StopService(string serviceName)
{
ServiceController sc =new ServiceController(serviceName);
if (!sc.CanStop)
{
throw new Exception(string.Format("服务:{0}无法停止.", serviceName));
}
if (sc.Status != ServiceControllerStatus.Stopped)
{
try
{
sc.Stop();
sc.WaitForStatus(ServiceControllerStatus.Stopped); // 等待执行完成
}
catch
{
return false;
}
}
return true;
}
}
在控制台程序中调用:
class Program
{
private static string strExePath = "";
private static string strExeName = "";
static void Main(string[] args)
{
strExePath = ConfigurationManager.AppSettings["ExePath"];
strExeName = ConfigurationManager.AppSettings["ExeName"];
try
{
WindowServiceSetup windowServiceHelper = new WindowServiceSetup();
if (WindowServiceSetup.ServiceIsExisted(strExeName))
{
Console.WriteLine("服务已存在,是否卸载服务:Y?");
string cmdu = Console.ReadLine();
if (cmdu.Trim() == "y" || cmdu.Trim() == "Y")
{
Console.WriteLine("卸载服务");
WindowServiceSetup.WindowServiceUnInstall(strExePath);
Console.WriteLine("卸载服务成功");
}
}
Console.WriteLine("是否安装服务:Y?");
string cmd = Console.ReadLine();
if (cmd.Trim() == "y" || cmd.Trim() == "Y")
{
WindowServiceSetup.WindowServiceInstall(strExePath);
//Console.WriteLine("自动开启服务");
//WindowServiceSetup.StartService(strExeName);
Console.WriteLine("安装完成,按任意键退出");
Console.Read();
}
}
catch (Exception ex)
{
Console.Write(ex.Message);
Console.WriteLine("按任意键退出");
Console.Read();
}
}
}
调试
调试使用附加进程进行调试
调试