You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

不依赖WMI获取CPU物理处理器、核心及逻辑处理器数的方法

不依赖WMI的CPU信息获取方案

直接调用Windows Kernel32.dll提供的原生GetLogicalProcessorInformationEx接口即可完全绕开WMI,不存在WMI服务偶发故障导致调用失败的问题。该接口从Windows 7/Windows Server 2008 R2开始支持所有主流Windows版本,返回结果和原WMI查询的数值完全一致,还能正确适配多物理CPU、超过64逻辑核的多CPU组、大小核架构、虚拟机运行等特殊场景。

对应字段获取逻辑

需要的三个字段可以通过遍历接口返回的结构体直接统计得到:

  • 物理处理器(CPU封装)总数:遍历RelationProcessorPackage类型的返回条目,条目计数就是对应数值,等价于原WMI查询Win32_ComputerSystem拿到的NumberOfProcessors
  • 物理核心总数:遍历RelationProcessorCore类型的返回条目,条目计数就是对应数值,等价于原WMI查询Win32_Processor拿到的NumberOfCores
  • 逻辑处理器总数:统计所有RelationProcessorCore条目下处理器掩码的置位总数,等价于原WMI查询Win32_Processor拿到的NumberOfLogicalProcessors

VB.NET 实现代码

Imports System.Runtime.InteropServices

Private Enum LOGICAL_PROCESSOR_RELATIONSHIP
    RelationProcessorCore = 0
    RelationProcessorPackage = 3
End Enum

<StructLayout(LayoutKind.Sequential)>
Private Structure GROUP_AFFINITY
    Public Mask As IntPtr
    Public Group As UShort
    <MarshalAs(UnmanagedType.ByValArray, SizeConst:=3)>
    Public Reserved As UShort()
End Structure

<StructLayout(LayoutKind.Sequential)>
Private Structure SYSTEM_LOGICAL_PROCESSOR_INFO_EX
    Public Relationship As LOGICAL_PROCESSOR_RELATIONSHIP
    Public Size As UInteger
    Public Processor As GROUP_AFFINITY
End Structure

<DllImport("kernel32.dll", SetLastError:=True)>
Private Shared Function GetLogicalProcessorInformationEx(
    RelationshipType As LOGICAL_PROCESSOR_RELATIONSHIP,
    Buffer As IntPtr,
    ByRef ReturnedLength As UInteger
) As Boolean
End Function

Private Sub GetCpuInfoWithoutWmi()
    Dim bufferLength As UInteger = 0
    GetLogicalProcessorInformationEx(LOGICAL_PROCESSOR_RELATIONSHIP.RelationProcessorPackage, IntPtr.Zero, bufferLength)
    Dim packageBuffer As IntPtr = Marshal.AllocHGlobal(CInt(bufferLength))
    Try
        If GetLogicalProcessorInformationEx(LOGICAL_PROCESSOR_RELATIONSHIP.RelationProcessorPackage, packageBuffer, bufferLength) Then
            Dim offset As Integer = 0
            Dim packageCount As Integer = 0
            While offset < bufferLength
                Dim info = Marshal.PtrToStructure(Of SYSTEM_LOGICAL_PROCESSOR_INFO_EX)(packageBuffer + offset)
                packageCount += 1
                offset += CInt(info.Size)
            End While
            _NumberOfPhysicalProcessors = packageCount
        End If

        bufferLength = 0
        GetLogicalProcessorInformationEx(LOGICAL_PROCESSOR_RELATIONSHIP.RelationProcessorCore, IntPtr.Zero, bufferLength)
        Dim coreBuffer As IntPtr = Marshal.AllocHGlobal(CInt(bufferLength))
        Try
            If GetLogicalProcessorInformationEx(LOGICAL_PROCESSOR_RELATIONSHIP.RelationProcessorCore, coreBuffer, bufferLength) Then
                Dim offset As Integer = 0
                Dim coreCount As Integer = 0
                Dim logicalCount As Integer = 0
                While offset < bufferLength
                    Dim info = Marshal.PtrToStructure(Of SYSTEM_LOGICAL_PROCESSOR_INFO_EX)(coreBuffer + offset)
                    coreCount += 1
                    Dim mask As ULong = info.Processor.Mask.ToInt64()
                    While mask > 0
                        logicalCount += CInt(mask And 1UL)
                        mask >>= 1
                    End While
                    offset += CInt(info.Size)
                End While
                _NumberOfPhysicalCores = coreCount
                _NumberOfLogicalCores = logicalCount
            End If
        Finally
            Marshal.FreeHGlobal(coreBuffer)
        End Try
    Finally
        Marshal.FreeHGlobal(packageBuffer)
    End Try
End Sub

注意事项

  • 不要使用读取注册表HKLM\HARDWARE\DESCRIPTION\System\CentralProcessor下键值的方案,该方案在多CPU组、超过64逻辑核、部分虚拟化环境下返回结果不准确。
  • 如果使用.NET 7及以上版本,可以直接调用框架内置的System.Runtime.InteropServices.RuntimeInformation提供的CPU信息接口,底层同样基于上述原生系统API实现,不需要自行编写P/Invoke代码,且完全不依赖WMI。

内容的提问来源于stack exchange,提问作者CTZStef

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 04:39:36