CPU Features.GetCount return CPU 核心数不正确

CPU Features.GetCount return incorrect number for CPU Cores

我正在使用 CPU 功能插件来获取 CPU 核心,这是代码:

${CPUFeatures.GetCount} $CPUCore

显然,有一台计算机有 12 CPU 个内核,而 $CPUCore 显示只有 1 个内核。我想也许 $CPUCore 可能只有 return 第一个数字,但我怎么能确定呢?

或者,还有其他方法可以得到 CPU 核心数字吗?

我不知道为什么插件会失败,但你可以问 Windows 这样的问题:

!include LogicLib.nsh
!ifndef ERROR_INSUFFICIENT_BUFFER
!define ERROR_INSUFFICIENT_BUFFER 122
!endif
!define RelationProcessorCore 0

!if "${NSIS_PTR_SIZE}" <= 4
Function GetProcessorPhysCoreCount
System::Store S
StrCpy  0 ; 0 if we fail
System::Call 'kernel32::GetLogicalProcessorInformationEx(i${RelationProcessorCore},i,*i0r2)i.r0?e'
Pop 
${If}  = ${ERROR_INSUFFICIENT_BUFFER}
${AndIf}  <> 0
    System::Alloc 
    System::Call 'kernel32::GetLogicalProcessorInformationEx(i${RelationProcessorCore},isr1,*ir2r2)i.r0'
    Push 
    ${If} [=10=] <> 0
    loop_7:
        IntOp   + 1
        System::Call *(i,i.r3)
        IntOp   + 
        IntOp   - 
        IntCmp  0 "" loop_7 loop_7
    ${EndIf}
    Pop 
    System::Free 
${Else}
    System::Call 'kernel32::GetLogicalProcessorInformation(i,*i0r2)i.r0?e'
    Pop 
    ${If}  = ${ERROR_INSUFFICIENT_BUFFER}
        System::Alloc 
        System::Call 'kernel32::GetLogicalProcessorInformation(isr1,*ir2r2)i.r0'
        Push 
        ${If} [=10=] <> 0
        loop_v:
            System::Call *(i,i.r3)
            ${If}  = ${RelationProcessorCore}
                IntOp   + 1
            ${EndIf}
            IntOp   + 24
            IntOp   - 24
            IntCmp  0 "" loop_v loop_v
        ${EndIf}
        Pop 
        System::Free 
    ${EndIf}
${EndIf}
Push 
System::Store L
FunctionEnd

Function CountSetBits32
Exch [=10=]
Push 
Push 
Push 
StrCpy  0
StrCpy  0
loop:
    IntOp  1 << 
    IntOp   & [=10=]
    ${IfThen}  <> 0 ${|} IntOp   + 1 ${|}
    IntOp   + 1
    StrCmp  32 "" loop
StrCpy [=10=] 
Pop 
Pop 
Pop 
Exch [=10=]
FunctionEnd

Function GetProcessorLogicalCoreCount
System::Store S
StrCpy  0 ; 0 if we fail
System::Call 'kernel32::GetLogicalProcessorInformationEx(i${RelationProcessorCore},i,*i0r2)i.r0?e'
Pop 
${If}  = ${ERROR_INSUFFICIENT_BUFFER}
${AndIf}  <> 0
    System::Alloc 
    System::Call 'kernel32::GetLogicalProcessorInformationEx(i${RelationProcessorCore},isr1,*ir2r2)i.r0'
    Push 
    ${If} [=10=] <> 0
    loop_7:
        System::Call *(i,i.r3,&i22,&i2,i.r5)
        Push 
        Call CountSetBits32
        Pop 
        IntOp   + 
        IntOp   + 
        IntOp   - 
        IntCmp  0 "" loop_7 loop_7
    ${EndIf}
    Pop 
    System::Free 
${Else}
    System::Call 'kernel32::GetLogicalProcessorInformation(i,*i0r2)i.r0?e'
    Pop 
    ${If}  = ${ERROR_INSUFFICIENT_BUFFER}
        System::Alloc 
        System::Call 'kernel32::GetLogicalProcessorInformation(isr1,*ir2r2)i.r0'
        Push 
        ${If} [=10=] <> 0
        loop_v:
            System::Call *(i,i.r3)
            ${If}  = ${RelationProcessorCore}
                System::Call *(i.r3)
                Push 
                Call CountSetBits32
                Pop 
                IntOp   + 
            ${EndIf}
            IntOp   + 24
            IntOp   - 24
            IntCmp  0 "" loop_v loop_v
        ${EndIf}
        Pop 
        System::Free 
    ${EndIf}
${EndIf}
Push 
System::Store L
FunctionEnd
!endif

Section
Call GetProcessorPhysCoreCount
Pop [=10=]
Call GetProcessorLogicalCoreCount
Pop 
DetailPrint PhysCores=[=10=],LogicalCores=
SectionEnd

您仍应使用 ${CPUFeatures.GetCount} 作为后备方案,因为 GetLogicalProcessorInformation[Ex] 并不存在于所有版本的 Windows...

我尝试使用此 forum 中的代码并对其进行了一些修改,因此我只获得了处理器核心编号:

!include "LogicLib.nsh" 

!define ERROR_INSUFFICIENT_BUFFER 122 

; Size of SYSTEM_LOGICAL_PROCESSOR_INFORMATION on 32-bit systems 
!define SYS_LOG_PROC_INFO_SIZE    24 
; Offset of Relationship in the SYSTEM_LOGICAL_PROCESSOR_INFORMATION structure 
!define RELATIONSHIP_OFFSET       4 
; Enum value of Relationship identifying Processor Core 
!define RELATIONPROCESSORCORE     0 

; Count the number of bits set in given value 
; Parameters: value 
; Returns: number of bits set in given value 
Function countbits 
   Exch [=10=] 
   Push  
   Push  

   ; Set initial value for number of bits set in [=10=] 
   StrCpy  0 

   ${While} [=10=] > 0 
      ; Clear least significant bit set 
      IntOp  [=10=] - 1 
      IntOp [=10=] [=10=] &  
      ; Increment number of bits set 
      IntOp   + 1 
   ${EndWhile} 

   ; Return number of bits set 
   StrCpy [=10=]  

   Pop  
   Pop  
   Exch [=10=] 
FunctionEnd 

; Evaluate processor information 
; Paramaters: buffer, length 
; Returns: number of cores 
Function evalcpuinfo 
   Exch [=10=] ; length 
   Exch 
   Exch  ; buffer 
   Push  
   Push  
   Push  
   Push  ; Processor Cores 
   Push  ; Logical Processors 

   ; Set buffer offset at the end of the buffer 
   StrCpy  [=10=] 

   ; Initialize number of Processor Cores and Logical Processors 
   StrCpy  0 
   StrCpy  0 

   ; Iterate through buffer starting from end 
   ${While}  >= ${SYS_LOG_PROC_INFO_SIZE} 
       ; Calculate start address of an element 
       IntOp   - ${SYS_LOG_PROC_INFO_SIZE} 
       IntOp   +  
       ; Get ProcessorMask value from element 
       System::Call "*(i.r4)" 
       Push  
       IntOp   + ${RELATIONSHIP_OFFSET} 
       ; Get Relationship value from element 
       System::Call "*(i.r4)" 
       ${If}  == ${RELATIONPROCESSORCORE} 
           ; Increment Processor cores 
           IntOp   + 1 
           ; Determine number of Logical Processor by counting the bits 
           ; set in the value of ProcessorMask 
           Call countbits 
           Pop  
           ; Sum up Logical Processors 
           IntOp   +  
       ${Else} 
           Pop  
       ${EndIf} 
   ${EndWhile} 

   ; Set processor information as return value 
   StrCpy [=10=] 

   Pop  
   Pop  
   Pop  
   Pop  
   Pop  
   Pop  
   Exch [=10=] 
FunctionEnd 

; Get processor information 
; Returns: number of Processor Cores and Logical Processors 
Function getcpuinfo 
  Push [=10=] 
  Push  
  Push  
  Push  
  Push  

  ; GetLogicalProcessorInformation is only available on  
  ; Windows XP SP3 or its successors. 

  ; Initialize buffer and its length 
  StrCpy  0 
  StrCpy  0 

  ; Determine required length of buffer 
  System::Call "kernel32::GetLogicalProcessorInformation(ir1, *ir2r2) i.r3 ? e" 
  Pop  
  ${If}  == 0 
     ${If}  == ${ERROR_INSUFFICIENT_BUFFER} 
         ; Allocate buffer 
         System::Alloc  
         Pop  
         ${If}  != 0 
             ; Get processor information 
             System::Call "kernel32::GetLogicalProcessorInformation(ir1, *ir2r2) i.r3 ? e" 
             Pop  
             ${If}  != 1 
                 StrCpy [=10=] "Error: " 
             ${Else} 
                 Push  ; buffer 
                 Push  ; length 
                 Call evalcpuinfo 
                 Pop [=10=] 
             ${EndIf} 
             ; Deallocate buffer 
             System::Free  
         ${Else} 
             StrCpy [=10=] "Error: memory allocation failed!" 
         ${EndIf} 
     ${Else} 
         StrCpy [=10=] "Error: " 
     ${EndIf} 
  ${Else} 
     StrCpy [=10=] "GetLogicalProcessorInformation is not available on your system!" 
  ${EndIf} 

  Pop  
  Pop  
  Pop  
  Pop  
  Exch [=10=] 
FunctionEnd  

我觉得代码和Anders的代码很相似。我已经在三台不同的 PC 上进行了尝试,并获得了正确的处理器核心编号。