SystemInfo.cs 29 KB

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