openhardwaremonitor 读不到 cpu 温度需先以管理员身份运行并调用 computer.open();再遍历 hardware.hardware,对 hardwaretype.cpu 调用 update(),最后筛选 sensortype.temperature 且含“package”的传感器读取值。

OpenHardwareMonitor 读不到 CPU 温度?检查 HardwareType.CPU 是否被忽略
OpenHardwareMonitor 默认只加载部分硬件,CPU 类型的传感器常被跳过,尤其在没有显式启用时。它不自动扫描所有传感器,而是依赖你主动调用 Update() 并遍历匹配的 HardwareType。
实操建议:
- 初始化后必须调用
computer.Open(),否则所有Hardware列表为空 - 遍历
computer.Hardware时,先判断hardware.HardwareType == HardwareType.CPU,再调用hardware.Update() -
CPU下的温度传感器通常在SensorType.Temperature子节点,不是直接挂在hardware.Sensors顶层——得递归进SubHardware或逐层查hardware.Sensors - 某些主板或 OEM 系统(如联想、戴尔笔记本)会屏蔽 SMBus/ISA 访问,即使代码正确也返回 0 或 NaN
为什么 sensor.Value 总是 null 或 0.0?确认传感器是否已启用并更新
sensor.Value 不是实时可读的“属性”,它是上一次 hardware.Update() 后缓存的值。没调用更新,就读不到真实数据;调用太频繁(如循环里每毫秒一次),反而可能触发驱动限流或返回旧值。
常见错误现象:
- 直接访问
computer.Hardware[0].Sensors[0].Value—— 此时Hardware还没Update(),Sensors数组虽存在,但内部值未刷新 - 只对
computer调用Update(),但 OpenHardwareMonitor 的设计是:必须对每个Hardware实例单独调用Update() - 读取前未检查
sensor.SensorType == SensorType.Temperature && sensor.Name.Contains("Package"),误把电压或功耗当温度
推荐写法片段(C#):
computer.Open();
foreach (var hardware in computer.Hardware)
{
if (hardware.HardwareType == HardwareType.CPU)
{
hardware.Update(); // 关键:必须在这儿调
foreach (var sensor in hardware.Sensors)
{
if (sensor.SensorType == SensorType.Temperature && sensor.Name.Contains("Package"))
Console.WriteLine($"{sensor.Name}: {sensor.Value?.ToString("F1")}°C");
}
}
}
Win10/Win11 上权限不足导致温度读数为 0 —— 必须以管理员身份运行
OpenHardwareMonitor 底层依赖 WMI + 直接端口 I/O(如通过 inportb 读取 Super I/O 芯片),Windows 默认禁止非管理员进程访问这些资源。普通用户权限下,computer.Hardware 可能有对象,但所有 sensor.Value 恒为 null 或 0.0,且无异常抛出,极难排查。
验证与解决:
- 右键程序 → “以管理员身份运行”,立刻能读到数值,就基本锁定是权限问题
- 不要试图用
App.manifest自动提权——.NET Core/.NET 5+ 应用中该设置常失效,仍需手动右键 - 若打包成服务,需在服务安装时显式设
ServiceProcessInstaller.Account = ServiceAccount.LocalSystem - WSL 或远程桌面会话中,即使管理员权限也可能受限,建议在本地交互式会话中测试
替代方案:不用 OpenHardwareMonitor 也能读 CPU 温度?试试 WMI 的 MSAcpi_ThermalZoneTemperature
OpenHardwareMonitor 功能强但重、权限要求高、兼容性差(尤其新平台)。如果只要一个粗略的 CPU 区域温度(非核心级),WMI 是更轻量、无需额外 DLL、且默认支持的路径。
注意点:
-
MSAcpi_ThermalZoneTemperature返回的是绝对温标(单位为 Kelvin ×10),需换算:(value / 10.0) - 273.15 - 不是所有 BIOS 都实现该 WMI 类,部分品牌机(尤其是 ARM 设备或 Surface)返回空结果
- 它反映的是主板热区温度,不是 CPU Package 或 Core 温度,数值通常偏低 5–15°C
- 查询速度比 OpenHardwareMonitor 快,但刷新间隔建议 ≥2 秒,避免 WMI 查询队列阻塞
示例(使用 System.Management):
using (var searcher = new ManagementObjectSearcher("root\WMI", "SELECT CurrentTemperature FROM MSAcpi_ThermalZoneTemperature"))
{
foreach (ManagementObject obj in searcher.Get())
{
var temp = (ulong)obj["CurrentTemperature"];
double celsius = (temp / 10.0) - 273.15;
Console.WriteLine($"Mainboard temp: {celsius:F1}°C");
}
}
实际用的时候,最麻烦的往往不是代码怎么写,而是不确定当前系统到底开放了哪一层访问——BIOS 设置里的 “Hardware Monitor”、“ACPI Fan Control”、“Secure Boot” 开关,都可能静默拦截底层读取。别急着改代码,先看设备管理器里有没有黄色感叹号,再查主板手册里温度传感器型号是否被 OpenHardwareMonitor 支持列表覆盖。










