You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
238 lines
8.8 KiB
238 lines
8.8 KiB
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.Linq;
|
|
using System.Management;
|
|
using System.Net;
|
|
using System.Net.Http;
|
|
using System.Net.NetworkInformation;
|
|
using System.Net.Sockets;
|
|
using System.Text.RegularExpressions;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Application.Models;
|
|
using Infrastructure.Extensions;
|
|
using Infrastructure.Models;
|
|
using Microsoft.AspNetCore.Hosting;
|
|
using Microsoft.Extensions.Configuration;
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
namespace WinService
|
|
{
|
|
public class WindowsService : IDisposable
|
|
{
|
|
private readonly IHostingEnvironment _env;
|
|
private readonly IConfiguration _configuration;
|
|
private readonly IHttpClientFactory _httpClientFactory;
|
|
private readonly ILogger<WindowsService> _logger;
|
|
private CancellationTokenSource _tokenSource;
|
|
private static readonly object thisLock = new object();
|
|
|
|
public WindowsService(IHostingEnvironment env, IConfiguration configuration, IHttpClientFactory httpClientFactory, ILogger<WindowsService> logger)
|
|
{
|
|
this._env = env;
|
|
this._configuration = configuration;
|
|
this._httpClientFactory = httpClientFactory;
|
|
this._logger = logger;
|
|
}
|
|
|
|
public void Start()
|
|
{
|
|
this._tokenSource = new CancellationTokenSource();
|
|
Task.Run(async () =>
|
|
{
|
|
while (!_tokenSource.IsCancellationRequested)
|
|
{
|
|
try
|
|
{
|
|
Console.WriteLine("...");
|
|
Update(this.GetModel());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
ex.PrintStack();
|
|
}
|
|
await Task.Delay(this._configuration.GetValue<int>("timer.seconds") * 1000);
|
|
}
|
|
});
|
|
}
|
|
|
|
public NotifyModel GetModel()
|
|
{
|
|
lock (thisLock)
|
|
{
|
|
var list = Search("select CSName,Caption,FreePhysicalMemory from Win32_OperatingSystem");
|
|
var physicalMemory = double.Parse(Search("select Capacity from Win32_PhysicalMemory")["Capacity"].ToString());
|
|
var cpu = int.Parse((Search("select PercentIdleTime from Win32_PerfFormattedData_PerfOS_Processor where Name='_Total'")["PercentIdleTime"].ToString()));
|
|
var host = string.IsNullOrEmpty(this._configuration["server.ip"]) ? "localhost" : this._configuration["server.ip"];
|
|
var prot = Convert.ToInt32(Regex.Match(this._configuration["server.urls"], @"(?<=:)\d+").Value);
|
|
var timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
|
|
var model = new NotifyModel
|
|
{
|
|
CategoryName = "WindowsPC",
|
|
CategoryNumber = "00",
|
|
Name = "主机",
|
|
Number = Helper.Instance.GetMacAddress(),
|
|
Icon = "pc",
|
|
IsOnline = true,
|
|
BaseUrl = $"http://{host}:{prot}/pc",
|
|
ApiPath = "/api"
|
|
};
|
|
model.Data.Add(new DataModel
|
|
{
|
|
Type = DataValueType.Text.ToString(),
|
|
Key = "ip",
|
|
Name = "IP",
|
|
Value = host,
|
|
DisplayOrder = 1
|
|
});
|
|
model.Data.Add(new DataModel
|
|
{
|
|
Type = DataValueType.Text.ToString(),
|
|
Key = "name",
|
|
Name = "计算机名",
|
|
Value = list["CSName"].ToString(),
|
|
DisplayOrder = 2
|
|
});
|
|
model.Data.Add(new DataModel
|
|
{
|
|
Type = DataValueType.Text.ToString(),
|
|
Key = "os",
|
|
Name = "操作系统",
|
|
Value = list["Caption"].ToString(),
|
|
DisplayOrder = 3
|
|
});
|
|
model.Data.Add(new DataModel
|
|
{
|
|
Key = "cpu",
|
|
Type = DataValueType.Int.ToString(),
|
|
Name = "CPU",
|
|
Value = (100 - cpu).ToString(),
|
|
Unit = "%",
|
|
DisplayOrder = 4
|
|
});
|
|
var freePhysicalMemory = double.Parse(list["FreePhysicalMemory"].ToString()) * 1024;
|
|
var memoryUsage = (physicalMemory - freePhysicalMemory) / physicalMemory * 100;
|
|
model.Data.Add(new DataModel
|
|
{
|
|
Key = "memory",
|
|
Type = DataValueType.Int.ToString(),
|
|
Name = "内存",
|
|
Value = ((int)memoryUsage).ToString(),
|
|
Unit = "%",
|
|
Description = $"{((physicalMemory - freePhysicalMemory) / 1024 / 1024 / 1024.0).ToString("F1")}/{(physicalMemory / 1024 / 1024 / 1024.0).ToString("f1")} GB",
|
|
DisplayOrder = 5
|
|
});
|
|
var (send, received) = this.GetSpeed();
|
|
model.Data.Add(new DataModel
|
|
{
|
|
Key = "send",
|
|
Type = DataValueType.Text.ToString(),
|
|
Name = "发送",
|
|
Value = Math.Round(((double)send) / 1024.0, 1).ToString(),
|
|
Unit = "K/s",
|
|
DisplayOrder = 6
|
|
});
|
|
model.Data.Add(new DataModel
|
|
{
|
|
Key = "received",
|
|
Type = DataValueType.Text.ToString(),
|
|
Name = "接收",
|
|
Value = Math.Round(((double)received) / 1024.0, 1).ToString(),
|
|
Unit = "K/s",
|
|
DisplayOrder = 7
|
|
});
|
|
return model;
|
|
}
|
|
}
|
|
|
|
public void Update(NotifyModel model)
|
|
{
|
|
var url = $"http://{this._configuration["node.url"]}/Notify";
|
|
Console.WriteLine(url);
|
|
try
|
|
{
|
|
var hc = this._httpClientFactory.CreateClient();
|
|
var task = this._httpClientFactory.CreateClient().PostAsync(url, new FormUrlEncodedContent(model.ToList()));
|
|
task.Wait();
|
|
using (var response = task.Result)
|
|
{
|
|
using (var content = response.Content)
|
|
{
|
|
var value = content.ReadAsStringAsync().Result;
|
|
Console.WriteLine($"end:{url}:{value}");
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
ex.PrintStack();
|
|
}
|
|
}
|
|
|
|
public void Shutdown()
|
|
{
|
|
if (this._env.IsDevelopment())
|
|
{
|
|
Process.Start("mshta", "vbscript:msgbox(\"测试关机\",64,\"title\")(window.close)");
|
|
}
|
|
else
|
|
{
|
|
Process.Start("shutdown.exe", "-s -t 1");
|
|
}
|
|
}
|
|
|
|
private (long send, long reveived) GetSpeed()
|
|
{
|
|
var send1 = 0L;
|
|
var received1 = 0L;
|
|
var interfaces = NetworkInterface.GetAllNetworkInterfaces();
|
|
|
|
foreach (var ni in interfaces)
|
|
{
|
|
send1 += ni.GetIPStatistics().BytesSent;
|
|
received1 += ni.GetIPStatistics().BytesReceived;
|
|
}
|
|
Thread.Sleep(1000);
|
|
var send2 = 0L;
|
|
var received2 = 0L;
|
|
var interfaces2 = NetworkInterface.GetAllNetworkInterfaces();
|
|
|
|
foreach (var ni in interfaces2)
|
|
{
|
|
send2 += ni.GetIPStatistics().BytesSent;
|
|
received2 += ni.GetIPStatistics().BytesReceived;
|
|
}
|
|
return ((send2 - send1), (received2 - received1));
|
|
}
|
|
|
|
public static Dictionary<string, object> Search(string command)
|
|
{
|
|
var result = new Dictionary<string, object>();
|
|
using (var mos = new ManagementObjectSearcher(command))
|
|
{
|
|
using (var molist = mos.Get())
|
|
{
|
|
foreach (ManagementObject mo in molist)
|
|
{
|
|
foreach (var property in mo.Properties)
|
|
{
|
|
if (property.Value != null && !result.Any(o => o.Key == property.Name))
|
|
{
|
|
result.Add(property.Name, property.Value);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
Console.WriteLine("OnvifService dispose...");
|
|
this._tokenSource.Cancel();
|
|
}
|
|
}
|
|
} |