Python 拿 CPU 型号,以及 Windows 注册表里的 CPU 信息

想在 Python 里拿到完整的 CPU 型号——比如 Intel(R) Xeon(R) CPU E5-2680 v4 @ 2.40GHz12th Gen Intel(R) Core(TM) i5-12400。看着简单,跨平台其实要三条路径。

首选:platform.processor()

标准库一行:

import platform
print(platform.processor())

Linux/macOS 通常能给出可读的字符串。Windows 上经常返回空或者只有个 Intel64 Family 6 Model 158 Stepping 10——CPUID 的原始编码,不是人看的。

Windows:WMI 或注册表

方式 1:wmic

import subprocess

out = subprocess.check_output("wmic cpu get name", shell=True, text=True)
name = out.split("\n")[1].strip()
print(name)   # 12th Gen Intel(R) Core(TM) i5-12400

注意 wmic 在 Windows 11 24H2 之后被标注为已弃用(虽然还能用一段时间)。

方式 2:PowerShell

out = subprocess.check_output(
    ["powershell", "-Command", "(Get-CimInstance Win32_Processor).Name"],
    text=True,
)
print(out.strip())

这个在新版 Windows 上更稳。

方式 3:读注册表

Windows 启动时会把 CPUID 结果缓存到注册表:

HKLM\HARDWARE\DESCRIPTION\System\CentralProcessor\0
    ProcessorNameString    REG_SZ    12th Gen Intel(R) Core(TM) i5-12400
    VendorIdentifier       REG_SZ    GenuineIntel

Python 读:

import winreg

with winreg.OpenKey(
    winreg.HKEY_LOCAL_MACHINE,
    r"HARDWARE\DESCRIPTION\System\CentralProcessor\0",
) as k:
    name, _ = winreg.QueryValueEx(k, "ProcessorNameString")
print(name)

三种方式底层都来自 CPUID 指令,注册表算是”启动时缓存好的解析结果”,速度最快,也不依赖外部命令。

Linux:/proc/cpuinfo

with open("/proc/cpuinfo") as f:
    for line in f:
        if line.startswith("model name"):
            print(line.split(":", 1)[1].strip())
            break

或者 shell 一行:

grep "model name" /proc/cpuinfo | head -1
lscpu | grep "Model name"

macOS:sysctl

import subprocess
out = subprocess.check_output(
    ["sysctl", "-n", "machdep.cpu.brand_string"], text=True
)
print(out.strip())   # Apple M2 Pro / Intel(R) Core(TM) i7-...

跨平台通用函数

import os
import platform
import subprocess


def get_cpu_name() -> str:
    system = platform.system()

    if system == "Windows":
        try:
            import winreg
            with winreg.OpenKey(
                winreg.HKEY_LOCAL_MACHINE,
                r"HARDWARE\DESCRIPTION\System\CentralProcessor\0",
            ) as k:
                name, _ = winreg.QueryValueEx(k, "ProcessorNameString")
            return name.strip()
        except Exception:
            pass
        try:
            out = subprocess.check_output(
                ["powershell", "-Command", "(Get-CimInstance Win32_Processor).Name"],
                text=True,
            )
            return out.strip()
        except Exception:
            return platform.processor() or "unknown"

    if system == "Darwin":
        try:
            return subprocess.check_output(
                ["sysctl", "-n", "machdep.cpu.brand_string"], text=True,
            ).strip()
        except Exception:
            return platform.processor() or "unknown"

    # Linux / *BSD
    try:
        with open("/proc/cpuinfo") as f:
            for line in f:
                if line.startswith("model name"):
                    return line.split(":", 1)[1].strip()
    except Exception:
        pass
    return platform.processor() or "unknown"


if __name__ == "__main__":
    print(get_cpu_name())

CPU 信息会被缓存吗

有个常见疑问:“CPU 型号会不会被系统缓存到什么地方?” 答案分两层:

  • CPU 本身没有”存型号信息”——型号信息是 CPUID 指令的返回值,来自硬件里的固化电路
  • 操作系统会缓存 CPUID 的解析结果:Windows 存在 HKLM\HARDWARE\DESCRIPTION\System\CentralProcessor 注册表下、Linux 通过 /proc/cpuinfo 动态生成、macOS 通过 sysctl 暴露

所以你读注册表 / /proc/cpuinfo 拿的是”系统解析过一次的缓存”,实时性和 CPUID 指令等价,但在虚拟机 / 容器里可能被覆盖或伪造——CPU 型号做设备指纹是很弱的信号,容易被伪装。

一句话总结

跨平台就 Windows 读注册表、Linux 读 /proc/cpuinfo、macOS sysctlplatform.processor() 在 Linux/macOS 上够用,Windows 上不行。做指纹别只靠 CPU 型号,太容易伪装。