Add start-service.bat script for Resource Monitor Service v2.0

- Introduced a batch script to simplify the startup process for the Resource Monitor Service.
- Included checks for .NET 9.0 Runtime installation.
- Added build and run commands for the service with appropriate error handling.
- Provided user instructions and API documentation links in the script output.
This commit is contained in:
Phoenix
2025-08-07 02:39:54 +08:00
parent 294438145a
commit 823e467078
17 changed files with 10419 additions and 363 deletions
+217
View File
@@ -0,0 +1,217 @@
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using ResourceMonitorService.Configuration;
using ResourceMonitorService.Models;
using System.Diagnostics;
using System.Management;
namespace ResourceMonitorService.Services
{
public interface ISystemInfoService
{
Task<SystemInfo> GetSystemInfoAsync();
Task<bool> IsVirtualMachineAsync();
Task<string> GetHypervisorVendorAsync();
Task<DateTime> GetBootTimeAsync();
Task<string> GetCpuNameAsync();
}
public class SystemInfoService : ISystemInfoService
{
private readonly ILogger<SystemInfoService> _logger;
private readonly MonitoringSettings _settings;
private SystemInfo? _cachedSystemInfo;
private DateTime _lastCacheUpdate = DateTime.MinValue;
private readonly TimeSpan _cacheExpiration = TimeSpan.FromMinutes(5);
public SystemInfoService(ILogger<SystemInfoService> logger, IOptions<MonitoringSettings> settings)
{
_logger = logger;
_settings = settings.Value;
}
public async Task<SystemInfo> GetSystemInfoAsync()
{
if (_cachedSystemInfo != null && DateTime.Now - _lastCacheUpdate < _cacheExpiration)
{
_cachedSystemInfo.Uptime = DateTime.Now - _cachedSystemInfo.BootTime;
return _cachedSystemInfo;
}
try
{
var systemInfo = new SystemInfo
{
MachineName = Environment.MachineName,
OSVersion = System.Runtime.InteropServices.RuntimeInformation.OSDescription,
OSArchitecture = System.Runtime.InteropServices.RuntimeInformation.OSArchitecture.ToString(),
ProcessorCount = Environment.ProcessorCount,
TotalPhysicalMemory = await GetTotalPhysicalMemoryAsync(),
CPUName = await GetCpuNameAsync(),
BootTime = await GetBootTimeAsync(),
Domain = Environment.UserDomainName,
IsVirtualMachine = await IsVirtualMachineAsync(),
HypervisorVendor = await GetHypervisorVendorAsync()
};
systemInfo.Uptime = DateTime.Now - systemInfo.BootTime;
_cachedSystemInfo = systemInfo;
_lastCacheUpdate = DateTime.Now;
return systemInfo;
}
catch (Exception ex)
{
_logger.LogError(ex, "Error getting system information");
throw;
}
}
public async Task<bool> IsVirtualMachineAsync()
{
try
{
return await Task.Run(() =>
{
// Check for common VM indicators
var queries = new[]
{
"SELECT * FROM Win32_ComputerSystem WHERE Manufacturer LIKE '%VMware%' OR Manufacturer LIKE '%VirtualBox%' OR Manufacturer LIKE '%Microsoft Corporation%' OR Model LIKE '%Virtual%'",
"SELECT * FROM Win32_BIOS WHERE SerialNumber LIKE '%VMware%' OR SerialNumber LIKE '%VirtualBox%' OR Version LIKE '%VBOX%'",
"SELECT * FROM Win32_SystemEnclosure WHERE Manufacturer LIKE '%VMware%' OR Manufacturer LIKE '%VirtualBox%'"
};
foreach (var query in queries)
{
#pragma warning disable CA1416 // Validate platform compatibility
using var searcher = new ManagementObjectSearcher(query);
using var collection = searcher.Get();
if (collection.Count > 0)
return true;
#pragma warning restore CA1416 // Validate platform compatibility
}
return false;
});
}
catch (Exception ex)
{
_logger.LogWarning(ex, "Could not determine if running in virtual machine");
return false;
}
}
public async Task<string> GetHypervisorVendorAsync()
{
try
{
return await Task.Run(() =>
{
#pragma warning disable CA1416 // Validate platform compatibility
using var searcher = new ManagementObjectSearcher("SELECT * FROM Win32_ComputerSystem");
using var collection = searcher.Get();
foreach (ManagementObject obj in collection)
{
var manufacturer = obj["Manufacturer"]?.ToString() ?? "";
var model = obj["Model"]?.ToString() ?? "";
if (manufacturer.Contains("VMware"))
return "VMware";
if (manufacturer.Contains("Microsoft Corporation") && model.Contains("Virtual"))
return "Hyper-V";
if (manufacturer.Contains("QEMU"))
return "QEMU/KVM";
if (manufacturer.Contains("VirtualBox"))
return "VirtualBox";
if (manufacturer.Contains("Xen"))
return "Xen";
}
#pragma warning restore CA1416 // Validate platform compatibility
return "Unknown";
});
}
catch (Exception ex)
{
_logger.LogWarning(ex, "Could not determine hypervisor vendor");
return "Unknown";
}
}
public async Task<DateTime> GetBootTimeAsync()
{
try
{
return await Task.Run(() =>
{
#pragma warning disable CA1416 // Validate platform compatibility
using var searcher = new ManagementObjectSearcher("SELECT LastBootUpTime FROM Win32_OperatingSystem");
using var collection = searcher.Get();
foreach (ManagementObject obj in collection)
{
var bootTime = obj["LastBootUpTime"]?.ToString();
if (!string.IsNullOrEmpty(bootTime))
{
return ManagementDateTimeConverter.ToDateTime(bootTime);
}
}
#pragma warning restore CA1416 // Validate platform compatibility
return DateTime.Now.AddMilliseconds(-Environment.TickCount64);
});
}
catch (Exception ex)
{
_logger.LogWarning(ex, "Could not get boot time from WMI, using tick count");
return DateTime.Now.AddMilliseconds(-Environment.TickCount64);
}
}
public async Task<string> GetCpuNameAsync()
{
try
{
return await Task.Run(() =>
{
#pragma warning disable CA1416 // Validate platform compatibility
using var searcher = new ManagementObjectSearcher("SELECT Name FROM Win32_Processor");
using var collection = searcher.Get();
foreach (ManagementObject obj in collection)
{
return obj["Name"]?.ToString()?.Trim() ?? "Unknown CPU";
}
#pragma warning restore CA1416 // Validate platform compatibility
return "Unknown CPU";
});
}
catch (Exception ex)
{
_logger.LogWarning(ex, "Could not get CPU name");
return "Unknown CPU";
}
}
private async Task<ulong> GetTotalPhysicalMemoryAsync()
{
try
{
return await Task.Run(() =>
{
#pragma warning disable CA1416 // Validate platform compatibility
using var searcher = new ManagementObjectSearcher("SELECT TotalPhysicalMemory FROM Win32_ComputerSystem");
using var collection = searcher.Get();
foreach (ManagementObject obj in collection)
{
return (ulong)obj["TotalPhysicalMemory"];
}
#pragma warning restore CA1416 // Validate platform compatibility
return (ulong)0;
});
}
catch (Exception ex)
{
_logger.LogWarning(ex, "Could not get total physical memory");
return 0;
}
}
}
}