SystemInfo.cs 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035
  1. using Masuit.Tools.Logging;
  2. using Microsoft.Win32;
  3. using System.Collections.Concurrent;
  4. using System.Diagnostics;
  5. using System.IO.MemoryMappedFiles;
  6. using System.Management;
  7. using System.Net;
  8. using System.Net.NetworkInformation;
  9. using System.Net.Sockets;
  10. using System.Runtime.InteropServices;
  11. using System.Text;
  12. using System.Xml.Linq;
  13. using Masuit.Tools.Abstractions.Hardware;
  14. namespace Masuit.Tools.Hardware
  15. {
  16. /// <summary>
  17. /// 硬件信息,部分功能需要C++支持,仅支持Windows系统
  18. /// </summary>
  19. public static partial class SystemInfo
  20. {
  21. #region 字段
  22. private const int GwHwndfirst = 0;
  23. private const int GwHwndnext = 2;
  24. private const int GwlStyle = -16;
  25. private const int WsVisible = 268435456;
  26. private const int WsBorder = 8388608;
  27. private static readonly string[] InstanceNames = [];
  28. private static readonly Dictionary<string, dynamic> Cache = new();
  29. private static readonly ConcurrentDictionary<string, PerformanceCounter> Counters = [];
  30. public static bool IsWinPlatform => Environment.OSVersion.Platform is PlatformID.Win32Windows or PlatformID.Win32S or PlatformID.WinCE or PlatformID.Win32NT;
  31. #endregion 字段
  32. #region 构造函数
  33. /// <summary>
  34. /// 静态构造函数
  35. /// </summary>
  36. static SystemInfo()
  37. {
  38. if (IsWinPlatform)
  39. {
  40. //初始化CPU计数器
  41. Counters["CpuCounter"] = new PerformanceCounter("Processor", "% Processor Time", "_Total")
  42. {
  43. MachineName = "."
  44. };
  45. Counters["CpuCounter"].NextValue();
  46. //获得物理内存
  47. try
  48. {
  49. using var mc = new ManagementClass("Win32_ComputerSystem");
  50. using var moc = mc.GetInstances();
  51. foreach (var mo in moc)
  52. {
  53. using (mo)
  54. {
  55. if (mo["TotalPhysicalMemory"] != null)
  56. {
  57. PhysicalMemory = mo["TotalPhysicalMemory"].ChangeTypeTo<long>();
  58. break;
  59. }
  60. }
  61. }
  62. var cat = new PerformanceCounterCategory("Network Interface");
  63. InstanceNames = cat.GetInstanceNames();
  64. }
  65. catch (Exception e)
  66. {
  67. LogManager.Error(e);
  68. }
  69. }
  70. //CPU个数
  71. ProcessorCount = Environment.ProcessorCount;
  72. }
  73. #endregion 构造函数
  74. private static bool CompactFormat { get; set; }
  75. #region CPU相关
  76. /// <summary>
  77. /// 获取CPU核心数
  78. /// </summary>
  79. public static int ProcessorCount { get; }
  80. /// <summary>
  81. /// 获取CPU占用率 %
  82. /// </summary>
  83. public static float CpuLoad
  84. {
  85. get
  86. {
  87. if (!IsWinPlatform) return 0;
  88. return Counters["CpuCounter"].NextValue();
  89. }
  90. }
  91. /// <summary>
  92. /// 获取当前进程的CPU使用率(至少需要0.5s)
  93. /// </summary>
  94. /// <returns></returns>
  95. public static async Task<double> GetCpuUsageForProcess(CancellationToken cancellationToken = default)
  96. {
  97. var startTime = DateTime.UtcNow;
  98. using var p1 = Process.GetCurrentProcess();
  99. var startCpuUsage = p1.TotalProcessorTime;
  100. await Task.Delay(500, cancellationToken);
  101. var endTime = DateTime.UtcNow;
  102. using var p2 = Process.GetCurrentProcess();
  103. var endCpuUsage = p2.TotalProcessorTime;
  104. var cpuUsedMs = (endCpuUsage - startCpuUsage).TotalMilliseconds;
  105. var totalMsPassed = (endTime - startTime).TotalMilliseconds;
  106. return cpuUsedMs / (Environment.ProcessorCount * totalMsPassed) * 100;
  107. }
  108. /// <summary>
  109. /// 获取CPU温度
  110. /// </summary>
  111. /// <returns>CPU温度</returns>
  112. public static float GetCPUTemperature()
  113. {
  114. if (!IsWinPlatform) return 0;
  115. try
  116. {
  117. using var mos = new ManagementObjectSearcher(@"root\WMI", "select * from MSAcpi_ThermalZoneTemperature");
  118. using var moc = mos.Get();
  119. foreach (var mo in moc)
  120. {
  121. using (mo)
  122. {
  123. //这就是CPU的温度了
  124. var temp = (mo["CurrentTemperature"].ChangeTypeTo<float>() - 2732) / 10;
  125. return (float)Math.Round(temp, 2);
  126. }
  127. }
  128. return 0;
  129. }
  130. catch (Exception)
  131. {
  132. return -1;
  133. }
  134. }
  135. /// <summary>
  136. /// 获取CPU的数量
  137. /// </summary>
  138. /// <returns>CPU的数量</returns>
  139. public static int GetCpuCount()
  140. {
  141. try
  142. {
  143. return Cache.GetOrAdd(nameof(GetCpuCount), () =>
  144. {
  145. if (!IsWinPlatform)
  146. {
  147. return Environment.ProcessorCount;
  148. }
  149. using var m = new ManagementClass("Win32_Processor");
  150. using var moc = m.GetInstances();
  151. return moc.Count;
  152. });
  153. }
  154. catch (Exception)
  155. {
  156. return -1;
  157. }
  158. }
  159. private static readonly Lazy<List<ManagementBaseObject>> CpuObjects = new(() =>
  160. {
  161. using var mos = new ManagementObjectSearcher("SELECT * FROM Win32_Processor");
  162. using var moc = mos.Get();
  163. return moc.AsParallel().Cast<ManagementBaseObject>().ToList();
  164. });
  165. /// <summary>
  166. /// 获取CPU信息
  167. /// </summary>
  168. /// <returns>CPU信息</returns>
  169. public static List<CpuInfo> GetCpuInfo()
  170. {
  171. try
  172. {
  173. if (!IsWinPlatform) return [];
  174. return CpuObjects.Value.Select(mo => new CpuInfo
  175. {
  176. NumberOfLogicalProcessors = ProcessorCount,
  177. CurrentClockSpeed = mo["CurrentClockSpeed"]?.ToString(),
  178. Manufacturer = mo["Manufacturer"]?.ToString(),
  179. MaxClockSpeed = mo["MaxClockSpeed"]?.ToString(),
  180. Type = mo["Name"]?.ToString(),
  181. DataWidth = mo["DataWidth"]?.ToString(),
  182. SerialNumber = mo["ProcessorId"]?.ToString(),
  183. DeviceID = mo["DeviceID"]?.ToString(),
  184. NumberOfCores = mo["NumberOfCores"].ChangeTypeTo<int>()
  185. }).ToList();
  186. }
  187. catch (Exception e)
  188. {
  189. return [new CpuInfo
  190. {
  191. DeviceID = null,
  192. Type = e.Message,
  193. Manufacturer = null,
  194. MaxClockSpeed = null,
  195. CurrentClockSpeed = null,
  196. NumberOfCores = 0,
  197. NumberOfLogicalProcessors = 0,
  198. DataWidth = null,
  199. SerialNumber = null
  200. }
  201. ];
  202. }
  203. }
  204. #if NET5_0_OR_GREATER
  205. public static string GetCpuId()
  206. {
  207. if (System.Runtime.Intrinsics.X86.X86Base.IsSupported)
  208. {
  209. var (eax, ebx, ecx, edx) = System.Runtime.Intrinsics.X86.X86Base.CpuId(1, 0);
  210. return edx.ToString("X").PadLeft(8, '0') + eax.ToString("X").PadLeft(8, '0');
  211. }
  212. return null;
  213. }
  214. #endif
  215. /// <summary>
  216. /// 获取进程的实例名称
  217. /// </summary>
  218. /// <param name="p"></param>
  219. /// <returns></returns>
  220. public static string GetInstanceName(this Process p)
  221. {
  222. try
  223. {
  224. var pcc = new PerformanceCounterCategory("Process");
  225. var instances = pcc.GetInstanceNames();
  226. foreach (string instance in instances)
  227. {
  228. var counter = Counters.GetOrAdd(nameof(instance) + instance, () => new PerformanceCounter("Process", "ID Process", instance));
  229. if (Math.Abs(counter.NextValue() - p.Id) < 1e-8)
  230. {
  231. return instance;
  232. }
  233. }
  234. }
  235. catch (Exception ex)
  236. {
  237. }
  238. return null;
  239. }
  240. /// <summary>
  241. /// 获取进程的CPU使用率
  242. /// </summary>
  243. /// <returns></returns>
  244. public static float GetProcessCpuUsage(int pid)
  245. {
  246. using var process = Process.GetProcessById(pid);
  247. return GetProcessCpuUsage(process);
  248. }
  249. /// <summary>
  250. /// 获取进程的CPU使用率
  251. /// </summary>
  252. /// <param name="name"></param>
  253. /// <returns></returns>
  254. public static IEnumerable<(Process process, float usage)> GetProcessCpuUsage(string name)
  255. {
  256. var processes = Process.GetProcessesByName(name);
  257. return GetProcessCpuUsage(processes);
  258. }
  259. /// <summary>
  260. /// 获取进程的CPU使用率
  261. /// </summary>
  262. /// <param name="processes"></param>
  263. /// <returns></returns>
  264. public static IEnumerable<(Process process, float usage)> GetProcessCpuUsage(this Process[] processes)
  265. {
  266. return processes.Select(p => (p, GetProcessCpuUsage(p)));
  267. }
  268. /// <summary>
  269. /// 获取进程的CPU使用率
  270. /// </summary>
  271. /// <param name="process"></param>
  272. /// <returns></returns>
  273. public static float GetProcessCpuUsage(this Process process)
  274. {
  275. if (!IsWinPlatform) return 0;
  276. string instance = GetInstanceName(process);
  277. if (instance != null)
  278. {
  279. var cpuCounter = Counters.GetOrAdd("Processor Time" + instance, () =>
  280. {
  281. var counter = new PerformanceCounter("Process", "% Processor Time", instance);
  282. counter.NextValue();
  283. return counter;
  284. });
  285. //Thread.Sleep(200); //等200ms(是测出能换取下个样本的最小时间间隔),让后系统获取下一个样本,因为第一个样本无效
  286. return cpuCounter.NextValue() / Environment.ProcessorCount;
  287. }
  288. return 0;
  289. }
  290. #endregion CPU相关
  291. #region 内存相关
  292. /// <summary>
  293. /// 获取可用内存(单位:Byte)
  294. /// </summary>
  295. public static long MemoryAvailable
  296. {
  297. get
  298. {
  299. if (!IsWinPlatform) return 0;
  300. try
  301. {
  302. using var mc = new ManagementClass("Win32_OperatingSystem");
  303. using var moc = mc.GetInstances();
  304. foreach (var mo in moc)
  305. {
  306. using (mo)
  307. {
  308. if (mo["FreePhysicalMemory"] != null)
  309. {
  310. return 1024 * mo["FreePhysicalMemory"].ChangeTypeTo<long>();
  311. }
  312. }
  313. }
  314. return 0;
  315. }
  316. catch (Exception)
  317. {
  318. return -1;
  319. }
  320. }
  321. }
  322. /// <summary>
  323. /// 获取物理内存(单位:Byte)
  324. /// </summary>
  325. public static long PhysicalMemory { get; }
  326. /// <summary>
  327. /// 获取内存信息
  328. /// </summary>
  329. /// <returns>内存信息</returns>
  330. public static RamInfo GetRamInfo()
  331. {
  332. return new RamInfo
  333. {
  334. MemoryAvailable = GetFreePhysicalMemory(),
  335. PhysicalMemory = GetTotalPhysicalMemory(),
  336. TotalPageFile = GetTotalVirtualMemory(),
  337. AvailablePageFile = GetTotalVirtualMemory() - GetUsedVirtualMemory(),
  338. AvailableVirtual = 1 - GetUsageVirtualMemory(),
  339. TotalVirtual = 1 - GetUsedPhysicalMemory()
  340. };
  341. }
  342. /// <summary>
  343. /// 获取虚拟内存使用率详情
  344. /// </summary>
  345. /// <returns></returns>
  346. public static string GetMemoryVData()
  347. {
  348. if (!IsWinPlatform) return "";
  349. float d = GetCounterValue("Memory", "% Committed Bytes In Use", null);
  350. var str = d.ToString("F") + "% (";
  351. d = GetCounterValue("Memory", "Committed Bytes", null);
  352. str += FormatBytes(d) + " / ";
  353. d = GetCounterValue("Memory", "Commit Limit", null);
  354. return str + FormatBytes(d) + ") ";
  355. }
  356. /// <summary>
  357. /// 获取虚拟内存使用率
  358. /// </summary>
  359. /// <returns></returns>
  360. public static float GetUsageVirtualMemory()
  361. {
  362. return GetCounterValue("Memory", "% Committed Bytes In Use", null);
  363. }
  364. /// <summary>
  365. /// 获取虚拟内存已用大小
  366. /// </summary>
  367. /// <returns></returns>
  368. public static float GetUsedVirtualMemory()
  369. {
  370. return GetCounterValue("Memory", "Committed Bytes", null);
  371. }
  372. /// <summary>
  373. /// 获取虚拟内存总大小
  374. /// </summary>
  375. /// <returns></returns>
  376. public static float GetTotalVirtualMemory()
  377. {
  378. return GetCounterValue("Memory", "Commit Limit", null);
  379. }
  380. /// <summary>
  381. /// 获取物理内存使用率详情描述
  382. /// </summary>
  383. /// <returns></returns>
  384. public static string GetMemoryPData()
  385. {
  386. if (!IsWinPlatform) return "";
  387. string s = QueryComputerSystem("totalphysicalmemory");
  388. if (string.IsNullOrEmpty(s)) return "";
  389. var totalphysicalmemory = Convert.ToSingle(s);
  390. var d = GetCounterValue("Memory", "Available Bytes", null);
  391. d = totalphysicalmemory - d;
  392. s = CompactFormat ? "%" : "% (" + FormatBytes(d) + " / " + FormatBytes(totalphysicalmemory) + ")";
  393. d /= totalphysicalmemory;
  394. d *= 100;
  395. return CompactFormat ? (int)d + s : d.ToString("F") + s;
  396. }
  397. /// <summary>
  398. /// 获取物理内存总数,单位B
  399. /// </summary>
  400. /// <returns></returns>
  401. public static float GetTotalPhysicalMemory()
  402. {
  403. return Cache.GetOrAdd(nameof(GetTotalPhysicalMemory), () =>
  404. {
  405. var s = QueryComputerSystem("totalphysicalmemory");
  406. return s.TryConvertTo<float>();
  407. });
  408. }
  409. /// <summary>
  410. /// 获取空闲的物理内存数,单位B
  411. /// </summary>
  412. /// <returns></returns>
  413. public static float GetFreePhysicalMemory()
  414. {
  415. return GetCounterValue("Memory", "Available Bytes", null);
  416. }
  417. /// <summary>
  418. /// 获取已经使用了的物理内存数,单位B
  419. /// </summary>
  420. /// <returns></returns>
  421. public static float GetUsedPhysicalMemory()
  422. {
  423. return GetTotalPhysicalMemory() - GetFreePhysicalMemory();
  424. }
  425. /// <summary>
  426. /// 获取进程的内存使用量,单位:MB
  427. /// </summary>
  428. /// <returns></returns>
  429. public static float GetProcessMemory(int pid)
  430. {
  431. using var process = Process.GetProcessById(pid);
  432. return GetProcessMemory(process);
  433. }
  434. /// <summary>
  435. /// 获取进程的内存使用量,单位:MB
  436. /// </summary>
  437. /// <param name="name"></param>
  438. /// <returns></returns>
  439. public static IEnumerable<(Process process, float usage)> GetProcessMemory(string name)
  440. {
  441. var processes = Process.GetProcessesByName(name);
  442. return GetProcessMemory(processes);
  443. }
  444. /// <summary>
  445. /// 获取进程的内存使用量,单位:MB
  446. /// </summary>
  447. /// <param name="processes"></param>
  448. /// <returns></returns>
  449. public static IEnumerable<(Process process, float usage)> GetProcessMemory(this Process[] processes)
  450. {
  451. return processes.Select(p => (p, GetProcessMemory(p)));
  452. }
  453. /// <summary>
  454. /// 获取进程的内存使用量,单位:MB
  455. /// </summary>
  456. /// <param name="process"></param>
  457. /// <returns></returns>
  458. public static float GetProcessMemory(this Process process)
  459. {
  460. if (!IsWinPlatform) return 0;
  461. string instance = GetInstanceName(process);
  462. if (instance != null)
  463. {
  464. var ramCounter = Counters.GetOrAdd("Working Set" + instance, () => new PerformanceCounter("Process", "Working Set", instance));
  465. var mb = ramCounter.NextValue() / 1024 / 1024;
  466. return mb;
  467. }
  468. return 0;
  469. }
  470. public static long CurrentProcessMemory
  471. {
  472. get
  473. {
  474. using var process = Process.GetCurrentProcess();
  475. return (long)GetCounterValue("Process", "Working Set - Private", process.ProcessName);
  476. }
  477. }
  478. #endregion 内存相关
  479. #region 硬盘相关
  480. /// <summary>
  481. /// 获取硬盘的读写速率
  482. /// </summary>
  483. /// <param name="dd">读或写</param>
  484. /// <returns></returns>
  485. public static float GetDiskData(DiskData dd)
  486. {
  487. return dd switch
  488. {
  489. DiskData.Read => GetCounterValue("PhysicalDisk", "Disk Read Bytes/sec", "_Total"),
  490. DiskData.Write => GetCounterValue("PhysicalDisk", "Disk Write Bytes/sec", "_Total"),
  491. DiskData.ReadAndWrite => GetCounterValue("PhysicalDisk", "Disk Read Bytes/sec", "_Total") + GetCounterValue("PhysicalDisk", "Disk Write Bytes/sec", "_Total"),
  492. _ => 0
  493. };
  494. }
  495. private static List<DiskInfo> _diskInfos = [];
  496. /// <summary>
  497. /// 获取磁盘可用空间
  498. /// </summary>
  499. /// <returns></returns>
  500. public static List<DiskInfo> GetDiskInfo()
  501. {
  502. try
  503. {
  504. if (!IsWinPlatform || _diskInfos.Count > 0)
  505. {
  506. return _diskInfos;
  507. }
  508. using var mc = new ManagementClass("Win32_DiskDrive");
  509. using var moc = mc.GetInstances();
  510. var list = new List<DiskInfo>();
  511. foreach (var mo in moc)
  512. {
  513. using (mo)
  514. {
  515. list.Add(new DiskInfo()
  516. {
  517. Index = mo["Index"].ChangeTypeTo<int>(),
  518. Total = mo["Size"].ChangeTypeTo<long>(),
  519. Model = mo["Model"].ToString(),
  520. MediaType = mo["MediaType"].ToString(),
  521. SerialNumber = mo["SerialNumber"].ToString(),
  522. });
  523. }
  524. }
  525. _diskInfos = list.OrderBy(x => x.Index).ToList();
  526. return _diskInfos;
  527. }
  528. catch (Exception)
  529. {
  530. return [];
  531. }
  532. }
  533. #endregion 硬盘相关
  534. #region 网络相关
  535. /// <summary>
  536. /// 获取网络的传输速率
  537. /// </summary>
  538. /// <param name="nd">上传或下载</param>
  539. /// <returns></returns>
  540. public static float GetNetData(NetData nd)
  541. {
  542. if (!IsWinPlatform) return 0;
  543. if (InstanceNames is { Length: 0 }) return 0;
  544. float d = 0;
  545. for (int i = 0; i < InstanceNames.Length; i++)
  546. {
  547. float receied = GetCounterValue("Network Interface", "Bytes Received/sec", InstanceNames[i]);
  548. float send = GetCounterValue("Network Interface", "Bytes Sent/sec", InstanceNames[i]);
  549. switch (nd)
  550. {
  551. case NetData.Received:
  552. d += receied;
  553. break;
  554. case NetData.Sent:
  555. d += send;
  556. break;
  557. case NetData.ReceivedAndSent:
  558. d += receied + send;
  559. break;
  560. default:
  561. d += 0;
  562. break;
  563. }
  564. }
  565. return d;
  566. }
  567. /// <summary>
  568. /// 获取网卡硬件地址
  569. /// </summary>
  570. /// <returns></returns>
  571. public static IEnumerable<PhysicalAddress> GetMacAddress()
  572. {
  573. return NetworkInterface.GetAllNetworkInterfaces().Where(c => c.NetworkInterfaceType != NetworkInterfaceType.Loopback && c.OperationalStatus == OperationalStatus.Up && c.GetIPProperties().UnicastAddresses.Any(temp => temp.Address.AddressFamily is AddressFamily.InterNetwork or AddressFamily.InterNetworkV6)).Select(c => c.GetPhysicalAddress());
  574. }
  575. /// <summary>
  576. /// 获取IP地址WMI
  577. /// </summary>
  578. /// <returns></returns>
  579. public static string GetIPAddressWMI()
  580. {
  581. try
  582. {
  583. if (!IsWinPlatform) return "";
  584. return Cache.GetOrAdd(nameof(GetIPAddressWMI), () =>
  585. {
  586. using var mc = new ManagementClass("Win32_NetworkAdapterConfiguration");
  587. using var moc = mc.GetInstances();
  588. foreach (var mo in moc)
  589. {
  590. if ((bool)mo["IPEnabled"])
  591. {
  592. return ((string[])mo["IpAddress"])[0];
  593. }
  594. }
  595. return "";
  596. });
  597. }
  598. catch (Exception e)
  599. {
  600. Console.WriteLine(e.Message);
  601. }
  602. return "";
  603. }
  604. /// <summary>
  605. /// 获取当前使用的IP
  606. /// </summary>
  607. /// <returns></returns>
  608. public static IPAddress GetLocalUsedIP()
  609. {
  610. return GetLocalUsedIP(AddressFamily.InterNetwork);
  611. }
  612. /// <summary>
  613. /// 获取当前使用的IP
  614. /// </summary>
  615. /// <returns></returns>
  616. public static IPAddress GetLocalUsedIP(AddressFamily family)
  617. {
  618. return NetworkInterface.GetAllNetworkInterfaces().Where(c => c.NetworkInterfaceType != NetworkInterfaceType.Loopback && c.OperationalStatus == OperationalStatus.Up).OrderByDescending(c => c.Speed).Select(t => t.GetIPProperties()).Where(p => p.DhcpServerAddresses.Count > 0).SelectMany(p => p.UnicastAddresses).Select(p => p.Address).FirstOrDefault(p => !(p.IsIPv6Teredo || p.IsIPv6LinkLocal || p.IsIPv6Multicast || p.IsIPv6SiteLocal) && p.AddressFamily == family);
  619. }
  620. /// <summary>
  621. /// 获取本机所有的ip地址
  622. /// </summary>
  623. /// <returns></returns>
  624. public static List<UnicastIPAddressInformation> GetLocalIPs()
  625. {
  626. var interfaces = NetworkInterface.GetAllNetworkInterfaces().Where(c => c.NetworkInterfaceType != NetworkInterfaceType.Loopback && c.OperationalStatus == OperationalStatus.Up).OrderByDescending(c => c.Speed); //所有网卡信息
  627. return interfaces.SelectMany(n => n.GetIPProperties().UnicastAddresses).ToList();
  628. }
  629. /// <summary>
  630. /// 获取网卡地址
  631. /// </summary>
  632. /// <returns></returns>
  633. public static string GetNetworkCardAddress()
  634. {
  635. try
  636. {
  637. if (!IsWinPlatform) return "";
  638. return Cache.GetOrAdd(nameof(GetNetworkCardAddress), () =>
  639. {
  640. using var mos = new ManagementObjectSearcher("select * from Win32_NetworkAdapter where ((MACAddress Is Not NULL) and (Manufacturer <> 'Microsoft'))");
  641. using var moc = mos.Get();
  642. foreach (var mo in moc)
  643. {
  644. return mo["MACAddress"].ToString().Trim();
  645. }
  646. return "";
  647. });
  648. }
  649. catch (Exception e)
  650. {
  651. Console.WriteLine(e.Message);
  652. }
  653. return "";
  654. }
  655. #endregion 网络相关
  656. #region 系统相关
  657. /// <summary>
  658. /// 获取计算机开机时间
  659. /// </summary>
  660. /// <returns>datetime</returns>
  661. public static DateTime BootTime()
  662. {
  663. if (!IsWinPlatform) return default;
  664. var query = new SelectQuery("SELECT LastBootUpTime FROM Win32_OperatingSystem WHERE Primary='true'");
  665. using var searcher = new ManagementObjectSearcher(query);
  666. using var moc = searcher.Get();
  667. foreach (var mo in moc)
  668. {
  669. using (mo)
  670. {
  671. return ManagementDateTimeConverter.ToDateTime(mo["LastBootUpTime"].ToString());
  672. }
  673. }
  674. return DateTime.Now - TimeSpan.FromMilliseconds(Environment.TickCount & int.MaxValue);
  675. }
  676. /// <summary>
  677. /// 查询计算机系统信息
  678. /// </summary>
  679. /// <param name="type">类型名</param>
  680. /// <returns></returns>
  681. public static string QueryComputerSystem(string type)
  682. {
  683. try
  684. {
  685. if (!IsWinPlatform) return string.Empty;
  686. var mos = new ManagementObjectSearcher("SELECT * FROM Win32_ComputerSystem");
  687. using var moc = mos.Get();
  688. foreach (var mo in moc)
  689. {
  690. using (mo)
  691. {
  692. return mo[type].ToString();
  693. }
  694. }
  695. }
  696. catch (Exception e)
  697. {
  698. return "未能获取到当前计算机系统信息,可能是当前程序无管理员权限,如果是web应用程序,请将应用程序池的高级设置中的进程模型下的标识设置为:LocalSystem;如果是普通桌面应用程序,请提升管理员权限后再操作。异常信息:" + e.Message;
  699. }
  700. return string.Empty;
  701. }
  702. /// <summary>
  703. /// 查找所有应用程序标题
  704. /// </summary>
  705. /// <param name="handle">应用程序标题范型</param>
  706. /// <returns>所有应用程序集合</returns>
  707. public static List<string> FindAllApps(int handle)
  708. {
  709. if (!IsWinPlatform) return new List<string>(0);
  710. var apps = new List<string>();
  711. int hwCurr = GetWindow(handle, GwHwndfirst);
  712. while (hwCurr > 0)
  713. {
  714. int IsTask = WsVisible | WsBorder;
  715. int lngStyle = GetWindowLongA(hwCurr, GwlStyle);
  716. bool taskWindow = (lngStyle & IsTask) == IsTask;
  717. if (taskWindow)
  718. {
  719. int length = GetWindowTextLength(new IntPtr(hwCurr));
  720. var sb = new StringBuilder(2 * length + 1);
  721. GetWindowText(hwCurr, sb, sb.Capacity);
  722. string strTitle = sb.ToString();
  723. if (!string.IsNullOrEmpty(strTitle))
  724. {
  725. apps.Add(strTitle);
  726. }
  727. }
  728. hwCurr = GetWindow(hwCurr, GwHwndnext);
  729. }
  730. return apps;
  731. }
  732. /// <summary>
  733. /// 操作系统类型
  734. /// </summary>
  735. /// <returns></returns>
  736. public static string GetSystemType()
  737. {
  738. try
  739. {
  740. return Cache.GetOrAdd(nameof(GetSystemType), () =>
  741. {
  742. if (!IsWinPlatform)
  743. {
  744. return Environment.OSVersion.Platform.ToString();
  745. }
  746. using var mc = new ManagementClass("Win32_ComputerSystem");
  747. using var moc = mc.GetInstances();
  748. foreach (var mo in moc)
  749. {
  750. return mo["SystemType"].ToString().Trim();
  751. }
  752. return "";
  753. });
  754. }
  755. catch (Exception e)
  756. {
  757. Console.WriteLine(e.Message);
  758. }
  759. return "";
  760. }
  761. #endregion 系统相关
  762. #region 主板相关
  763. /// <summary>
  764. /// 获取主板序列号
  765. /// </summary>
  766. /// <returns></returns>
  767. public static string GetBiosSerialNumber()
  768. {
  769. try
  770. {
  771. if (!IsWinPlatform) return "";
  772. return Cache.GetOrAdd(nameof(GetBiosSerialNumber), () =>
  773. {
  774. using var searcher = new ManagementObjectSearcher("select * from Win32_BIOS");
  775. using var mos = searcher.Get();
  776. foreach (var mo in mos)
  777. {
  778. return mo["SerialNumber"].ToString().Trim();
  779. }
  780. return "";
  781. });
  782. }
  783. catch (Exception e)
  784. {
  785. Console.WriteLine(e.Message);
  786. }
  787. return "";
  788. }
  789. /// <summary>
  790. /// 主板编号
  791. /// </summary>
  792. /// <returns></returns>
  793. public static BiosInfo GetBiosInfo()
  794. {
  795. if (!IsWinPlatform) return new BiosInfo();
  796. return Cache.GetOrAdd(nameof(GetBiosInfo), () =>
  797. {
  798. using var searcher = new ManagementObjectSearcher("select * from Win32_BaseBoard");
  799. using var mos = searcher.Get();
  800. using var reg = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64);
  801. using var guidKey = reg.OpenSubKey(@"SOFTWARE\Microsoft\Cryptography");
  802. using var uuidKey = reg.OpenSubKey(@"SYSTEM\HardwareConfig");
  803. string guid = null;
  804. string uuid = null;
  805. string model = null;
  806. if (guidKey != null) guid = guidKey.GetValue("MachineGuid") + "";
  807. if (uuidKey != null) uuid = (uuidKey.GetValue("LastConfig") + "").Trim('{', '}').ToUpper();
  808. var biosKey = Registry.LocalMachine.OpenSubKey(@"HARDWARE\DESCRIPTION\System\BIOS");
  809. biosKey ??= Registry.LocalMachine.OpenSubKey(@"SYSTEM\HardwareConfig\Current");
  810. if (biosKey != null)
  811. {
  812. model = (biosKey.GetValue("SystemProductName") + "").Replace("System Product Name", null);
  813. if (model.IsNullOrEmpty()) model = biosKey.GetValue("BaseBoardProduct") + "";
  814. biosKey.Dispose();
  815. }
  816. foreach (var mo in mos)
  817. {
  818. return new BiosInfo
  819. {
  820. Manufacturer = mo["Manufacturer"].ToString(),
  821. ID = mo["SerialNumber"].ToString(),
  822. Model = model,
  823. SerialNumber = GetBiosSerialNumber(),
  824. Guid = guid,
  825. UUID = uuid
  826. };
  827. }
  828. return new BiosInfo();
  829. });
  830. }
  831. #endregion 主板相关
  832. #region 公共函数
  833. /// <summary>
  834. /// 将速度值格式化成字节单位
  835. /// </summary>
  836. /// <param name="bytes"></param>
  837. /// <returns></returns>
  838. public static string FormatBytes(this double bytes)
  839. {
  840. int unit = 0;
  841. while (bytes > 1024)
  842. {
  843. bytes /= 1024;
  844. ++unit;
  845. }
  846. string s = CompactFormat ? ((int)bytes).ToString() : bytes.ToString("F") + " ";
  847. return s + (Unit)unit;
  848. }
  849. private static float GetCounterValue(string categoryName, string counterName, string instanceName)
  850. {
  851. if (!IsWinPlatform) return 0;
  852. var counter = Counters.GetOrAdd(categoryName + ":" + counterName + ":" + instanceName, () => new PerformanceCounter(categoryName, counterName, instanceName));
  853. return counter.NextValue();
  854. }
  855. #endregion 公共函数
  856. #region Win32API声明
  857. #pragma warning disable 1591
  858. [DllImport("User32")]
  859. public static extern int GetWindow(int hWnd, int wCmd);
  860. [DllImport("User32")]
  861. public static extern int GetWindowLongA(int hWnd, int wIndx);
  862. [DllImport("user32.dll")]
  863. public static extern bool GetWindowText(int hWnd, StringBuilder title, int maxBufSize);
  864. [DllImport("user32", CharSet = CharSet.Auto)]
  865. public static extern int GetWindowTextLength(IntPtr hWnd);
  866. #pragma warning restore 1591
  867. #endregion Win32API声明
  868. #region AIDA64
  869. /// <summary>
  870. /// 获取AIDA64传感器值,需要AIDA64开启共享内存
  871. /// </summary>
  872. /// <returns></returns>
  873. public static IEnumerable<SensorValue> GetAida64Values()
  874. {
  875. using var mmf = MemoryMappedFile.OpenExisting("AIDA64_SensorValues");
  876. using var stream = mmf.CreateViewStream();
  877. using BinaryReader binReader = new BinaryReader(stream);
  878. var sb = new StringBuilder((int)stream.Length);
  879. sb.Append("<root>");
  880. var c = binReader.ReadChar();
  881. while (c != '\0')
  882. {
  883. sb.Append(c);
  884. c = binReader.ReadChar();
  885. }
  886. sb.Append("</root>");
  887. var sharedMemString = sb.ToString();
  888. var document = XDocument.Parse(sharedMemString);
  889. foreach (var element in document.Root.Elements())
  890. {
  891. var v = new SensorValue
  892. {
  893. Type = SensorTypeStrings.GetTypeFromStringCode(element.Name.LocalName)
  894. };
  895. foreach (var childElement in element.Elements())
  896. {
  897. if (childElement.Name.LocalName == "id")
  898. {
  899. v.Identifier = childElement.Value;
  900. }
  901. else if (childElement.Name.LocalName == "label")
  902. {
  903. v.Name = childElement.Value;
  904. }
  905. else if (childElement.Name.LocalName == "value")
  906. {
  907. v.Value = childElement.Value;
  908. }
  909. }
  910. yield return v;
  911. }
  912. }
  913. #endregion AIDA64
  914. }
  915. }