SystemInfo.cs 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703
  1. using Masuit.Tools.Logging;
  2. using System;
  3. using System.Collections;
  4. using System.Collections.Generic;
  5. using System.Diagnostics;
  6. using System.Linq;
  7. using System.Management;
  8. using System.Net;
  9. using System.Net.NetworkInformation;
  10. using System.Net.Sockets;
  11. using System.Runtime.InteropServices;
  12. using System.Text;
  13. using System.Threading.Tasks;
  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 PerformanceCounter PcCpuLoad; //CPU计数器
  28. private static readonly PerformanceCounter MemoryCounter = new PerformanceCounter();
  29. private static readonly PerformanceCounter CpuCounter = new PerformanceCounter();
  30. private static readonly PerformanceCounter DiskReadCounter = new PerformanceCounter();
  31. private static readonly PerformanceCounter DiskWriteCounter = new PerformanceCounter();
  32. private static readonly string[] InstanceNames;
  33. private static readonly PerformanceCounter[] NetRecvCounters;
  34. private static readonly PerformanceCounter[] NetSentCounters;
  35. #endregion 字段
  36. #region 构造函数
  37. /// <summary>
  38. /// 静态构造函数
  39. /// </summary>
  40. static SystemInfo()
  41. {
  42. //初始化CPU计数器
  43. PcCpuLoad = new PerformanceCounter("Processor", "% Processor Time", "_Total")
  44. {
  45. MachineName = "."
  46. };
  47. PcCpuLoad.NextValue();
  48. //CPU个数
  49. ProcessorCount = Environment.ProcessorCount;
  50. //获得物理内存
  51. try
  52. {
  53. using var mc = new ManagementClass("Win32_ComputerSystem");
  54. using var moc = mc.GetInstances();
  55. foreach (var mo in moc)
  56. {
  57. using (mo)
  58. {
  59. if (mo["TotalPhysicalMemory"] != null)
  60. {
  61. PhysicalMemory = long.Parse(mo["TotalPhysicalMemory"].ToString());
  62. }
  63. }
  64. }
  65. var cat = new PerformanceCounterCategory("Network Interface");
  66. InstanceNames = cat.GetInstanceNames();
  67. NetRecvCounters = new PerformanceCounter[InstanceNames.Length];
  68. NetSentCounters = new PerformanceCounter[InstanceNames.Length];
  69. for (int i = 0; i < InstanceNames.Length; i++)
  70. {
  71. NetRecvCounters[i] = new PerformanceCounter();
  72. NetSentCounters[i] = new PerformanceCounter();
  73. }
  74. CompactFormat = false;
  75. }
  76. catch (Exception e)
  77. {
  78. LogManager.Error(e);
  79. }
  80. }
  81. #endregion 构造函数
  82. private static bool CompactFormat { get; set; }
  83. #region CPU核心
  84. /// <summary>
  85. /// 获取CPU核心数
  86. /// </summary>
  87. public static int ProcessorCount { get; }
  88. #endregion CPU核心
  89. #region CPU占用率
  90. /// <summary>
  91. /// 获取CPU占用率 %
  92. /// </summary>
  93. public static float CpuLoad => PcCpuLoad.NextValue();
  94. /// <summary>
  95. /// 获取当前进程的CPU使用率(至少需要0.5s)
  96. /// </summary>
  97. /// <returns></returns>
  98. public static async Task<double> GetCpuUsageForProcess()
  99. {
  100. var startTime = DateTime.UtcNow;
  101. using var p1 = Process.GetCurrentProcess();
  102. var startCpuUsage = p1.TotalProcessorTime;
  103. await Task.Delay(500);
  104. var endTime = DateTime.UtcNow;
  105. using var p2 = Process.GetCurrentProcess();
  106. var endCpuUsage = p2.TotalProcessorTime;
  107. var cpuUsedMs = (endCpuUsage - startCpuUsage).TotalMilliseconds;
  108. var totalMsPassed = (endTime - startTime).TotalMilliseconds;
  109. return cpuUsedMs / (Environment.ProcessorCount * totalMsPassed) * 100;
  110. }
  111. #endregion CPU占用率
  112. #region 可用内存
  113. /// <summary>
  114. /// 获取可用内存
  115. /// </summary>
  116. public static long MemoryAvailable
  117. {
  118. get
  119. {
  120. try
  121. {
  122. using var mc = new ManagementClass("Win32_OperatingSystem");
  123. using var moc = mc.GetInstances();
  124. foreach (var mo in moc)
  125. {
  126. using (mo)
  127. {
  128. if (mo["FreePhysicalMemory"] != null)
  129. {
  130. return 1024 * long.Parse(mo["FreePhysicalMemory"].ToString());
  131. }
  132. }
  133. }
  134. return 0;
  135. }
  136. catch (Exception)
  137. {
  138. return 0;
  139. }
  140. }
  141. }
  142. #endregion 可用内存
  143. #region 物理内存
  144. /// <summary>
  145. /// 获取物理内存
  146. /// </summary>
  147. public static long PhysicalMemory { get; }
  148. #endregion 物理内存
  149. #region 查找所有应用程序标题
  150. /// <summary>
  151. /// 查找所有应用程序标题
  152. /// </summary>
  153. /// <param name="handle">应用程序标题范型</param>
  154. /// <returns>所有应用程序集合</returns>
  155. public static ArrayList FindAllApps(int handle)
  156. {
  157. var apps = new ArrayList();
  158. int hwCurr = GetWindow(handle, GwHwndfirst);
  159. while (hwCurr > 0)
  160. {
  161. int IsTask = WsVisible | WsBorder;
  162. int lngStyle = GetWindowLongA(hwCurr, GwlStyle);
  163. bool taskWindow = (lngStyle & IsTask) == IsTask;
  164. if (taskWindow)
  165. {
  166. int length = GetWindowTextLength(new IntPtr(hwCurr));
  167. StringBuilder sb = new StringBuilder(2 * length + 1);
  168. GetWindowText(hwCurr, sb, sb.Capacity);
  169. string strTitle = sb.ToString();
  170. if (!string.IsNullOrEmpty(strTitle))
  171. {
  172. apps.Add(strTitle);
  173. }
  174. }
  175. hwCurr = GetWindow(hwCurr, GwHwndnext);
  176. }
  177. return apps;
  178. }
  179. #endregion 查找所有应用程序标题
  180. #region 获取CPU的数量
  181. /// <summary>
  182. /// 获取CPU的数量
  183. /// </summary>
  184. /// <returns>CPU的数量</returns>
  185. public static int GetCpuCount()
  186. {
  187. try
  188. {
  189. using var m = new ManagementClass("Win32_Processor");
  190. using var moc = m.GetInstances();
  191. return moc.Count;
  192. }
  193. catch (Exception)
  194. {
  195. return 0;
  196. }
  197. }
  198. #endregion 获取CPU的数量
  199. #region 获取CPU信息
  200. private static readonly Lazy<List<ManagementBaseObject>> CpuObjects = new Lazy<List<ManagementBaseObject>>(() =>
  201. {
  202. using var mos = new ManagementObjectSearcher("SELECT * FROM Win32_Processor");
  203. using var moc = mos.Get();
  204. return moc.AsParallel().Cast<ManagementBaseObject>().ToList();
  205. });
  206. /// <summary>
  207. /// 获取CPU信息
  208. /// </summary>
  209. /// <returns>CPU信息</returns>
  210. public static List<CpuInfo> GetCpuInfo()
  211. {
  212. try
  213. {
  214. return CpuObjects.Value.Select(mo => new CpuInfo
  215. {
  216. CpuLoad = CpuLoad,
  217. NumberOfLogicalProcessors = ProcessorCount,
  218. CurrentClockSpeed = mo.Properties["CurrentClockSpeed"].Value.ToString(),
  219. Manufacturer = mo.Properties["Manufacturer"].Value.ToString(),
  220. MaxClockSpeed = mo.Properties["MaxClockSpeed"].Value.ToString(),
  221. Type = mo.Properties["Name"].Value.ToString(),
  222. DataWidth = mo.Properties["DataWidth"].Value.ToString(),
  223. SerialNumber = mo.Properties["ProcessorId"].Value.ToString(),
  224. DeviceID = mo.Properties["DeviceID"].Value.ToString(),
  225. NumberOfCores = Convert.ToInt32(mo.Properties["NumberOfCores"].Value),
  226. Temperature = GetCPUTemperature()
  227. }).ToList();
  228. }
  229. catch (Exception)
  230. {
  231. return new List<CpuInfo>();
  232. }
  233. }
  234. #endregion 获取CPU信息
  235. #region 获取内存信息
  236. /// <summary>
  237. /// 获取内存信息
  238. /// </summary>
  239. /// <returns>内存信息</returns>
  240. public static RamInfo GetRamInfo()
  241. {
  242. return new RamInfo
  243. {
  244. MemoryAvailable = GetFreePhysicalMemory(),
  245. PhysicalMemory = GetTotalPhysicalMemory(),
  246. TotalPageFile = GetTotalVirtualMemory(),
  247. AvailablePageFile = GetTotalVirtualMemory() - GetUsedVirtualMemory(),
  248. AvailableVirtual = 1 - GetUsageVirtualMemory(),
  249. TotalVirtual = 1 - GetUsedPhysicalMemory()
  250. };
  251. }
  252. #endregion 获取内存信息
  253. #region 获取CPU温度
  254. /// <summary>
  255. /// 获取CPU温度
  256. /// </summary>
  257. /// <returns>CPU温度</returns>
  258. public static float GetCPUTemperature()
  259. {
  260. try
  261. {
  262. using var mos = new ManagementObjectSearcher(@"root\WMI", "select * from MSAcpi_ThermalZoneTemperature");
  263. using var moc = mos.Get();
  264. foreach (var mo in moc)
  265. {
  266. using (mo)
  267. {
  268. //这就是CPU的温度了
  269. var temp = (float.Parse(mo.Properties["CurrentTemperature"].Value.ToString()) - 2732) / 10;
  270. return (float)Math.Round(temp, 2);
  271. }
  272. }
  273. }
  274. catch (Exception)
  275. {
  276. return 0;
  277. }
  278. return 0;
  279. }
  280. #endregion 获取CPU温度
  281. #region WMI接口获取CPU使用率
  282. /// <summary>
  283. /// WMI接口获取CPU使用率
  284. /// </summary>
  285. /// <returns></returns>
  286. public static string GetProcessorData()
  287. {
  288. float d = GetCounterValue(CpuCounter, "Processor", "% Processor Time", "_Total");
  289. return CompactFormat ? (int)d + "%" : d.ToString("F") + "%";
  290. }
  291. #endregion WMI接口获取CPU使用率
  292. #region 获取虚拟内存使用率详情
  293. /// <summary>
  294. /// 获取虚拟内存使用率详情
  295. /// </summary>
  296. /// <returns></returns>
  297. public static string GetMemoryVData()
  298. {
  299. float d = GetCounterValue(MemoryCounter, "Memory", "% Committed Bytes In Use", null);
  300. var str = d.ToString("F") + "% (";
  301. d = GetCounterValue(MemoryCounter, "Memory", "Committed Bytes", null);
  302. str += FormatBytes(d) + " / ";
  303. d = GetCounterValue(MemoryCounter, "Memory", "Commit Limit", null);
  304. return str + FormatBytes(d) + ") ";
  305. }
  306. /// <summary>
  307. /// 获取虚拟内存使用率
  308. /// </summary>
  309. /// <returns></returns>
  310. public static float GetUsageVirtualMemory()
  311. {
  312. return GetCounterValue(MemoryCounter, "Memory", "% Committed Bytes In Use", null);
  313. }
  314. /// <summary>
  315. /// 获取虚拟内存已用大小
  316. /// </summary>
  317. /// <returns></returns>
  318. public static float GetUsedVirtualMemory()
  319. {
  320. return GetCounterValue(MemoryCounter, "Memory", "Committed Bytes", null);
  321. }
  322. /// <summary>
  323. /// 获取虚拟内存总大小
  324. /// </summary>
  325. /// <returns></returns>
  326. public static float GetTotalVirtualMemory()
  327. {
  328. return GetCounterValue(MemoryCounter, "Memory", "Commit Limit", null);
  329. }
  330. #endregion 获取虚拟内存使用率详情
  331. #region 获取物理内存使用率详情
  332. /// <summary>
  333. /// 获取物理内存使用率详情描述
  334. /// </summary>
  335. /// <returns></returns>
  336. public static string GetMemoryPData()
  337. {
  338. string s = QueryComputerSystem("totalphysicalmemory");
  339. float totalphysicalmemory = Convert.ToSingle(s);
  340. float d = GetCounterValue(MemoryCounter, "Memory", "Available Bytes", null);
  341. d = totalphysicalmemory - d;
  342. s = CompactFormat ? "%" : "% (" + FormatBytes(d) + " / " + FormatBytes(totalphysicalmemory) + ")";
  343. d /= totalphysicalmemory;
  344. d *= 100;
  345. return CompactFormat ? (int)d + s : d.ToString("F") + s;
  346. }
  347. /// <summary>
  348. /// 获取物理内存总数,单位B
  349. /// </summary>
  350. /// <returns></returns>
  351. public static float GetTotalPhysicalMemory()
  352. {
  353. string s = QueryComputerSystem("totalphysicalmemory");
  354. return s.TryConvertTo<float>();
  355. }
  356. /// <summary>
  357. /// 获取空闲的物理内存数,单位B
  358. /// </summary>
  359. /// <returns></returns>
  360. public static float GetFreePhysicalMemory()
  361. {
  362. return GetCounterValue(MemoryCounter, "Memory", "Available Bytes", null);
  363. }
  364. /// <summary>
  365. /// 获取已经使用了的物理内存数,单位B
  366. /// </summary>
  367. /// <returns></returns>
  368. public static float GetUsedPhysicalMemory()
  369. {
  370. return GetTotalPhysicalMemory() - GetFreePhysicalMemory();
  371. }
  372. #endregion 获取物理内存使用率详情
  373. #region 获取硬盘的读写速率
  374. /// <summary>
  375. /// 获取硬盘的读写速率
  376. /// </summary>
  377. /// <param name="dd">读或写</param>
  378. /// <returns></returns>
  379. public static float GetDiskData(DiskData dd) => dd == DiskData.Read ? GetCounterValue(DiskReadCounter, "PhysicalDisk", "Disk Read Bytes/sec", "_Total") : dd == DiskData.Write ? GetCounterValue(DiskWriteCounter, "PhysicalDisk", "Disk Write Bytes/sec", "_Total") : dd == DiskData.ReadAndWrite ? GetCounterValue(DiskReadCounter, "PhysicalDisk", "Disk Read Bytes/sec", "_Total") + GetCounterValue(DiskWriteCounter, "PhysicalDisk", "Disk Write Bytes/sec", "_Total") : 0;
  380. #endregion 获取硬盘的读写速率
  381. #region 获取网络的传输速率
  382. /// <summary>
  383. /// 获取网络的传输速率
  384. /// </summary>
  385. /// <param name="nd">上传或下载</param>
  386. /// <returns></returns>
  387. public static float GetNetData(NetData nd)
  388. {
  389. if (InstanceNames.Length == 0)
  390. {
  391. return 0;
  392. }
  393. float d = 0;
  394. for (int i = 0; i < InstanceNames.Length; i++)
  395. {
  396. float receied = GetCounterValue(NetRecvCounters[i], "Network Interface", "Bytes Received/sec", InstanceNames[i]);
  397. float send = GetCounterValue(NetSentCounters[i], "Network Interface", "Bytes Sent/sec", InstanceNames[i]);
  398. switch (nd)
  399. {
  400. case NetData.Received:
  401. d += receied;
  402. break;
  403. case NetData.Sent:
  404. d += send;
  405. break;
  406. case NetData.ReceivedAndSent:
  407. d += receied + send;
  408. break;
  409. default:
  410. d += 0;
  411. break;
  412. }
  413. }
  414. return d;
  415. }
  416. #endregion 获取网络的传输速率
  417. /// <summary>
  418. /// 获取网卡硬件地址
  419. /// </summary>
  420. /// <returns></returns>
  421. public static IList<string> GetMacAddress()
  422. {
  423. //获取网卡硬件地址
  424. try
  425. {
  426. IList<string> list = new List<string>();
  427. using var mc = new ManagementClass("Win32_NetworkAdapterConfiguration");
  428. using var moc = mc.GetInstances();
  429. foreach (var mo in moc)
  430. {
  431. using (mo)
  432. {
  433. if ((bool)mo["IPEnabled"])
  434. {
  435. list.Add(mo["MacAddress"].ToString());
  436. }
  437. }
  438. }
  439. return list;
  440. }
  441. catch (Exception)
  442. {
  443. return new List<string>();
  444. }
  445. }
  446. /// <summary>
  447. /// 获取当前使用的IP
  448. /// </summary>
  449. /// <returns></returns>
  450. public static IPAddress GetLocalUsedIP()
  451. {
  452. return GetLocalUsedIP(AddressFamily.InterNetwork);
  453. }
  454. /// <summary>
  455. /// 获取当前使用的IP
  456. /// </summary>
  457. /// <returns></returns>
  458. public static IPAddress GetLocalUsedIP(AddressFamily family)
  459. {
  460. return NetworkInterface.GetAllNetworkInterfaces().OrderByDescending(c => c.Speed).Where(c => c.NetworkInterfaceType != NetworkInterfaceType.Loopback && c.OperationalStatus == OperationalStatus.Up).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);
  461. }
  462. /// <summary>
  463. /// 获取本机所有的ip地址
  464. /// </summary>
  465. /// <returns></returns>
  466. public static List<UnicastIPAddressInformation> GetLocalIPs()
  467. {
  468. var interfaces = NetworkInterface.GetAllNetworkInterfaces().OrderByDescending(c => c.Speed).Where(c => c.NetworkInterfaceType != NetworkInterfaceType.Loopback && c.OperationalStatus == OperationalStatus.Up); //所有网卡信息
  469. return interfaces.SelectMany(n => n.GetIPProperties().UnicastAddresses).ToList();
  470. }
  471. #region 将速度值格式化成字节单位
  472. /// <summary>
  473. /// 将速度值格式化成字节单位
  474. /// </summary>
  475. /// <param name="bytes"></param>
  476. /// <returns></returns>
  477. public static string FormatBytes(this double bytes)
  478. {
  479. int unit = 0;
  480. while (bytes > 1024)
  481. {
  482. bytes /= 1024;
  483. ++unit;
  484. }
  485. string s = CompactFormat ? ((int)bytes).ToString() : bytes.ToString("F") + " ";
  486. return s + (Unit)unit;
  487. }
  488. #endregion 将速度值格式化成字节单位
  489. #region 查询计算机系统信息
  490. /// <summary>
  491. /// 获取计算机开机时间
  492. /// </summary>
  493. /// <returns>datetime</returns>
  494. public static DateTime BootTime()
  495. {
  496. var query = new SelectQuery("SELECT LastBootUpTime FROM Win32_OperatingSystem WHERE Primary='true'");
  497. using var searcher = new ManagementObjectSearcher(query);
  498. using var moc = searcher.Get();
  499. foreach (var mo in moc)
  500. {
  501. using (mo)
  502. {
  503. return ManagementDateTimeConverter.ToDateTime(mo.Properties["LastBootUpTime"].Value.ToString());
  504. }
  505. }
  506. return DateTime.Now - TimeSpan.FromMilliseconds(Environment.TickCount & int.MaxValue);
  507. }
  508. /// <summary>
  509. /// 查询计算机系统信息
  510. /// </summary>
  511. /// <param name="type">类型名</param>
  512. /// <returns></returns>
  513. public static string QueryComputerSystem(string type)
  514. {
  515. try
  516. {
  517. var mos = new ManagementObjectSearcher("SELECT * FROM Win32_ComputerSystem");
  518. using var moc = mos.Get();
  519. foreach (var mo in moc)
  520. {
  521. using (mo)
  522. {
  523. return mo[type].ToString();
  524. }
  525. }
  526. }
  527. catch (Exception e)
  528. {
  529. return "未能获取到当前计算机系统信息,可能是当前程序无管理员权限,如果是web应用程序,请将应用程序池的高级设置中的进程模型下的标识设置为:LocalSystem;如果是普通桌面应用程序,请提升管理员权限后再操作。异常信息:" + e.Message;
  530. }
  531. return string.Empty;
  532. }
  533. #endregion 查询计算机系统信息
  534. #region 获取环境变量
  535. /// <summary>
  536. /// 获取环境变量
  537. /// </summary>
  538. /// <param name="type">环境变量名</param>
  539. /// <returns></returns>
  540. public static string QueryEnvironment(string type) => Environment.ExpandEnvironmentVariables(type);
  541. #endregion 获取环境变量
  542. #region 获取磁盘空间
  543. private static readonly List<DiskInfo> DiskInfos = new();
  544. /// <summary>
  545. /// 获取磁盘可用空间
  546. /// </summary>
  547. /// <returns></returns>
  548. public static List<DiskInfo> GetDiskInfo()
  549. {
  550. try
  551. {
  552. if (DiskInfos.Count > 0)
  553. {
  554. return DiskInfos;
  555. }
  556. using var mc = new ManagementClass("Win32_DiskDrive");
  557. using var moc = mc.GetInstances();
  558. foreach (var mo in moc)
  559. {
  560. using (mo)
  561. {
  562. DiskInfos.Add(new DiskInfo()
  563. {
  564. Total = float.Parse(mo["Size"].ToString()),
  565. Model = mo["Model"].ToString(),
  566. SerialNumber = mo["SerialNumber"].ToString(),
  567. });
  568. }
  569. }
  570. return DiskInfos;
  571. }
  572. catch (Exception)
  573. {
  574. return new List<DiskInfo>();
  575. }
  576. }
  577. #endregion 获取磁盘空间
  578. private static float GetCounterValue(PerformanceCounter pc, string categoryName, string counterName, string instanceName)
  579. {
  580. pc.CategoryName = categoryName;
  581. pc.CounterName = counterName;
  582. pc.InstanceName = instanceName;
  583. return pc.NextValue();
  584. }
  585. #region Win32API声明
  586. #pragma warning disable 1591
  587. [DllImport("User32")]
  588. public static extern int GetWindow(int hWnd, int wCmd);
  589. [DllImport("User32")]
  590. public static extern int GetWindowLongA(int hWnd, int wIndx);
  591. [DllImport("user32.dll")]
  592. public static extern bool GetWindowText(int hWnd, StringBuilder title, int maxBufSize);
  593. [DllImport("user32", CharSet = CharSet.Auto)]
  594. public static extern int GetWindowTextLength(IntPtr hWnd);
  595. #pragma warning restore 1591
  596. #endregion Win32API声明
  597. }
  598. }