需求:应客户需求,现场服务器和客户端之间网络总是不稳定。导致客户端总是和服务器断开连接。为了监测网络,且为了不容易让用户误操作停止监测,所以采用控制台程序打包成windows服务的方式实现。并且加一个winform程序,让客户安装卸载此服务。
实现不间断ping服务器IP,并记录日志
public async Task StartAsync()
{
Serilog.Log.Information($"Service Started");
List<string> addressesToPing = _configuration.GetSection("Ips").Get<List<string>>();
await Task.WhenAll(addressesToPing.Select(PingAddressAsync));
}
public void Stop()
{
Serilog.Log.Information($"Service Stoped");
}
private async Task PingAddressAsync(string address)
{
using var ping = new System.Net.NetworkInformation.Ping();
while (true)
{
try
{
Serilog.Log.Information($"Pinging {address}... ");
var reply = await ping.SendPingAsync(address);
if (reply.Status == IPStatus.Success)
{
Serilog.Log.Information($"来自 {reply.Address} 的回复: 时间={reply.RoundtripTime}ms TTL={reply.Options.Ttl}");
}
else
{
Serilog.Log.Information($"Ping {address} : {reply.Status}");
}
// 为了控制输出频率和资源占用,添加短暂停顿
await Task.Delay(700); // 每秒发送一次
}
catch (System.Exception ex)
{
Serilog.Log.Error($"异常:{ex.Message}");
}
}
}
Winform程序使用Nssm安装windows服务
也是用了topshelf,但是在使用中发现了一些问题没有解决,顾采用Nssm。
/// <summary>
/// 安装服务
/// </summary>
private void InstallService()
{
List<string> cmdArray = new List<string>();
var cmd = $@"{nssm} install {ServiceName} {CurrentDirectory}Ping.exe";
//::执行安装服务指令5008
cmdArray.Add(cmd);
//::监控日志
cmd = $@"{nssm} set {ServiceName} AppStdout {CurrentDirectory}nssm.log";
cmdArray.Add(cmd);
cmd = $@"{nssm} set {ServiceName} AppStderr {CurrentDirectory}nssm.log";
cmdArray.Add(cmd);
//::详情Tab(例如:服务的描述信息)
cmd = $@"{nssm} set {ServiceName} DisplayName {ServiceName}";
cmdArray.Add(cmd);
cmd = $@"{nssm} set {ServiceName} Description {Description}";
cmdArray.Add(cmd);
cmd = $@"{nssm} set {ServiceName} Start SERVICE_AUTO_START";
cmdArray.Add(cmd);
//::安装完成后,启动前的服务状态
cmd = $@"{nssm} status {ServiceName}";
cmdArray.Add(cmd);
cmd = $@"{nssm} start {ServiceName}";
cmdArray.Add(cmd);
//::启动服务后的服务状态
cmd = $@"{nssm} status {ServiceName}";
cmdArray.Add(cmd);
ExcuteDosCommand(cmdArray);
}
/// <summary>
/// 执行cmd命令
/// </summary>
/// <param name="cmdArray"></param>
private void ExcuteDosCommand(List<string> cmdArray)
{
Process p = new Process();
p.StartInfo.FileName = "cmd";
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardInput = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.CreateNoWindow = false;
p.OutputDataReceived += new DataReceivedEventHandler(sortProcess_OutputDataReceived);
p.ErrorDataReceived += sortProcess_OutputDataReceived;
try
{
p.Start();
using (StreamWriter cmdWriter = p.StandardInput)
{
p.BeginOutputReadLine();
p.BeginErrorReadLine();
foreach (var cmd in cmdArray)
{
p.StandardInput.WriteLine(cmd);
}
}
p.WaitForExit();
//if (p.ExitCode == 0)
//{
// MessageBox.Show("操作成功。");
//}
//else
//{
// MessageBox.Show($"服务安装失败 with exit code {p.ExitCode}.");
//}
}
catch (Exception ex)
{
MessageBox.Show("执行命令失败,请检查输入的命令是否正确!");
}
finally
{
p.Close();
}
}
private void sortProcess_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
if (!String.IsNullOrEmpty(e.Data))
{
this.BeginInvoke(new Action(() =>
{
richTextBox1.AppendText(e.Data + Environment.NewLine);
}));
}
}
/// <summary>
/// 刷新服务列表
/// </summary>
private void RefWindowsServices()
{
// 获取系统服务列表
ServiceController[] services = ServiceController.GetServices();
var service = services.FirstOrDefault(t => t.ServiceName == ServiceName);
if (service != null)
{
this.label1.Text = "服务状态:" + service.Status.ToString();
}
else
{
this.label1.Text = "未发现服务";
}
}
附下载源码地址:源码