开发 Windows 服务应用
Posted bosaidongmomo
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了开发 Windows 服务应用相关的知识,希望对你有一定的参考价值。
前言
不要用sc create 来创建windows服务了。
正经windows的安装参考msdn doc
开发 Windows 服务应用
window服务的制作教程
在Visual Studio 2015 中选择下列工程文件并创建.
会生成如下页面.
绿色部分负责安装服务,红色部分负责编写代码.
在绿色部分点属性,可以修改服务名称.
将其修改为 Account LocalSystem
https://docs.microsoft.com/zh-cn/dotnet/framework/windows-services/how-to-install-and-uninstall-services
对于 32 位版的 .NET Framework 4 或 4.5 以及更高版本,如果 Windows 安装目录是 C: \\ Windows,则默认路径是 C:\\Windows\\Microsoft.NET\\Framework\\v4.0.30319\\ InstallUtil.exe 。
对于 64 位版的 .NET Framework 4 或 4.5 以及更高版本,默认路径是 C:\\Windows\\Microsoft.NET\\Framework64\\v4.0.30319\\InstallUtil.exe。
cd C:\\Windows\\Microsoft.NET\\Framework\\v4.0.30319
installUtil "c:\\users\\administrator\\documents\\visual studio 2015\\Projects\\MyService\\MyService\\bin\\Debug\\MyService.exe"
安装
Microsoft (R) .NET Framework 安装实用工具版本 4.8.4084.0
版权所有 (C) Microsoft Corporation。保留所有权利。
正在运行事务处理安装。
正在开始安装的“安装”阶段。
查看日志文件的内容以获得 c:\\users\\administrator\\documents\\visual studio 2015\\Projects\\MyService\\MyService\\bin\\Debug\\MyService.exe 程序集的进度。
该文件位于 c:\\users\\administrator\\documents\\visual studio 2015\\Projects\\MyService\\MyService\\bin\\Debug\\MyService.InstallLog。
正在安装程序集“c:\\users\\administrator\\documents\\visual studio 2015\\Projects\\MyService\\MyService\\bin\\Debug\\MyService.exe”。
受影响的参数是:
logtoconsole =
logfile = c:\\users\\administrator\\documents\\visual studio 2015\\Projects\\MyService\\MyService\\bin\\Debug\\MyService.InstallLog
assemblypath = c:\\users\\administrator\\documents\\visual studio 2015\\Projects\\MyService\\MyService\\bin\\Debug\\MyService.exe
正在安装服务 Service1...
已成功安装服务 Service1。
正在日志 Application 中创建 EventLog 源 Service1...
“安装”阶段已成功完成,正在开始“提交”阶段。
查看日志文件的内容以获得 c:\\users\\administrator\\documents\\visual studio 2015\\Projects\\MyService\\MyService\\bin\\Debug\\MyService.exe 程序集的进度。
该文件位于 c:\\users\\administrator\\documents\\visual studio 2015\\Projects\\MyService\\MyService\\bin\\Debug\\MyService.InstallLog。
正在提交程序集“c:\\users\\administrator\\documents\\visual studio 2015\\Projects\\MyService\\MyService\\bin\\Debug\\MyService.exe”。
受影响的参数是:
logtoconsole =
logfile = c:\\users\\administrator\\documents\\visual studio 2015\\Projects\\MyService\\MyService\\bin\\Debug\\MyService.InstallLog
assemblypath = c:\\users\\administrator\\documents\\visual studio 2015\\Projects\\MyService\\MyService\\bin\\Debug\\MyService.exe
“提交”阶段已成功完成。
已完成事务处理安装。
C:\\Windows\\Microsoft.NET\\Framework\\v4.0.30319>
然后net start [服务名]就好啦。
WriteLog 日志编写
private static void WriteLog(string text)
string logPath = runtimePath + "WatchDog_" + DateTime.Now.ToString("yyyy-MM-dd") + ".log";
StreamWriter streamWriter = new StreamWriter(logPath, true);
streamWriter.WriteLine(text);
//刷新缓存
streamWriter.Flush();
//关闭流
streamWriter.Close();
ListenToStart
var list = Process.GetProcesses().ToList();
var nginx = list.Where(n => n.ProcessName.Contains("nginx")).ToList().Count;
获取进程中是否存在,如果不存在就重启。
整体代码如下。
由于windowsService不怎么好调试、建议写控制台管理程序先测试一遍,再进行处理。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Threading.Tasks;
using System.Timers;
namespace MyWindowsService
public partial class WatchDog : ServiceBase
public static string runtimePath = AppDomain.CurrentDomain.BaseDirectory;
public WatchDog()
InitializeComponent();
private static void WriteLog(string text)
string logPath = runtimePath + "WatchDog_" + DateTime.Now.ToString("yyyy-MM-dd") + ".log";
StreamWriter streamWriter = new StreamWriter(logPath, true);
streamWriter.WriteLine(text);
//刷新缓存
streamWriter.Flush();
//关闭流
streamWriter.Close();
public static void ListenToStart(object source, ElapsedEventArgs e)
string logPath = runtimePath + "WatchDog_" + DateTime.Now.ToString("yyyy-MM-dd") + ".log";
var list = Process.GetProcesses().ToList();
var nginx = list.Where(n => n.ProcessName.Contains("nginx")).ToList().Count;
// 如果nginx 在进程中存在
if (nginx > 0)
// 什么都不做
else
// 否则
// 启动进程
Process process = new Process();
process.StartInfo.FileName = runtimePath + "StartNginx.bat";
process.StartInfo.Arguments = "";
WriteLog(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + ",nginx服务重启");
process.Start();
var redis = list.Where(n => n.ProcessName.Contains("redis-server")).ToList().Count;
// 如果redis 在进程中存在
if (redis > 0)
// 什么都不做
else
// 否则
// 启动进程
Process process = new Process();
process.StartInfo.FileName = runtimePath + "StartRedis.bat";
process.StartInfo.Arguments = "";
WriteLog(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + ",redis服务重启");
process.Start();
var java = 0;
Process p = new Process();
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardInput = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.CreateNoWindow = true;
p.Start();
//查看本机端口占用情况
p.StandardInput.WriteLine("netstat -an| findstr -i \\":8088\\" | findstr -i \\"LISTENING\\"");
p.StandardInput.WriteLine("exit");
//
StreamReader reader = p.StandardOutput;//截取输出流
string strLine = reader.ReadLine();//每次读取一行
while (!reader.EndOfStream)
// strAllInfo += strLine + "\\r\\n";
strLine = reader.ReadLine();
if (strLine.Contains("TCP") || strLine.Contains("UDP"))
java = 1;
// 如果mysql 在进程中存在
if (java > 0)
// 什么都不做
else
// 否则
// 启动进程
Process process = new Process();
process.StartInfo.FileName = runtimePath + "StartJava.bat";
process.StartInfo.Arguments = "";
WriteLog(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + ",java服务重启");
process.Start();
protected override void OnStart(string[] args)
System.Timers.Timer timer = new System.Timers.Timer();
timer.Enabled = true;
timer.Interval = 60000; //执行间隔时间,单位为毫秒; 这里实际间隔为1分钟
timer.Start();
timer.Elapsed += new System.Timers.ElapsedEventHandler(ListenToStart);
protected override void OnStop()
Process p = new Process();
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardInput = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.CreateNoWindow = true;
p.Start();
//查看本机端口占用情况
p.StandardInput.WriteLine("netstat -ano | findstr 8088");
p.StandardInput.WriteLine("exit");
//
StreamReader reader = p.StandardOutput;//截取输出流
string strLine = reader.ReadLine();//每次读取一行
while (!reader.EndOfStream)
strLine = reader.ReadLine();
if (strLine.Contains("TCP") || strLine.Contains("UDP"))
string[] ee = strLine.Split(' ');
string port = ee.LastOrDefault();
Process pr = new Process();
pr.StartInfo.FileName = "cmd.exe";
pr.StartInfo.UseShellExecute = false;
pr.StartInfo.RedirectStandardInput = true;
pr.StartInfo.RedirectStandardOutput = true;
pr.StartInfo.RedirectStandardError = true;
pr.StartInfo.CreateNoWindow = true;
pr.Start();
//查看本机端口占用情况 杀死进程
pr.StandardInput.WriteLine("taskkill /pid " + port + " -t -f");
pr.StandardInput.WriteLine("exit");
以上是关于开发 Windows 服务应用的主要内容,如果未能解决你的问题,请参考以下文章
ASP.NET MVC 中应用Windows服务以及Webservice服务开发分布式定时器
适用于 Windows 8.1 应用商店应用的蓝牙低功耗服装服务设备发现和开发
如何将 elixir 应用程序从 Windows 开发机器部署到 Ubuntu 服务器