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 _logger; private CancellationTokenSource _tokenSource; private static readonly object thisLock = new object(); public WindowsService(IHostingEnvironment env, IConfiguration configuration, IHttpClientFactory httpClientFactory, ILogger 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("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 Search(string command) { var result = new Dictionary(); 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(); } } }