CPU Features.GetCount返回CPU核心的错误编号

时间:2015-04-28 06:07:38

标签: nsis cpu-cores

我正在使用CPU Features插件获取CPU内核,这是代码:

time

显然,有一台拥有12个CPU核心的计算机,而$ CPUCore只显示1个核心。我想也许有可能$ CPUCore只返回第一个数字,但我怎么能知道呢?

或者,有没有其他方法可以获得CPU核心数量?

2 个答案:

答案 0 :(得分:2)

我不知道为什么插件失败但你可以问这样的事情:

!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 $9 0 ; 0 if we fail
System::Call 'kernel32::GetLogicalProcessorInformationEx(i${RelationProcessorCore},i,*i0r2)i.r0?e'
Pop $3
${If} $3 = ${ERROR_INSUFFICIENT_BUFFER}
${AndIf} $2 <> 0
    System::Alloc $2
    System::Call 'kernel32::GetLogicalProcessorInformationEx(i${RelationProcessorCore},isr1,*ir2r2)i.r0'
    Push $1
    ${If} $0 <> 0
    loop_7:
        IntOp $9 $9 + 1
        System::Call *$1(i,i.r3)
        IntOp $1 $1 + $3
        IntOp $2 $2 - $3
        IntCmp $2 0 "" loop_7 loop_7
    ${EndIf}
    Pop $1
    System::Free $1
${Else}
    System::Call 'kernel32::GetLogicalProcessorInformation(i,*i0r2)i.r0?e'
    Pop $3
    ${If} $3 = ${ERROR_INSUFFICIENT_BUFFER}
        System::Alloc $2
        System::Call 'kernel32::GetLogicalProcessorInformation(isr1,*ir2r2)i.r0'
        Push $1
        ${If} $0 <> 0
        loop_v:
            System::Call *$1(i,i.r3)
            ${If} $3 = ${RelationProcessorCore}
                IntOp $9 $9 + 1
            ${EndIf}
            IntOp $1 $1 + 24
            IntOp $2 $2 - 24
            IntCmp $2 0 "" loop_v loop_v
        ${EndIf}
        Pop $1
        System::Free $1
    ${EndIf}
${EndIf}
Push $9
System::Store L
FunctionEnd

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

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

Section
Call GetProcessorPhysCoreCount
Pop $0
Call GetProcessorLogicalCoreCount
Pop $1
DetailPrint PhysCores=$0,LogicalCores=$1
SectionEnd

你仍然应该使用$ {CPUFeatures.GetCount}作为后备,因为所有版本的Windows上都不存在GetLogicalProcessorInformation [Ex] ...

答案 1 :(得分:0)

我尝试使用此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 $0 
   Push $1 
   Push $2 

   ; Set initial value for number of bits set in $0 
   StrCpy $1 0 

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

   ; Return number of bits set 
   StrCpy $0 $1 

   Pop $2 
   Pop $1 
   Exch $0 
FunctionEnd 

; Evaluate processor information 
; Paramaters: buffer, length 
; Returns: number of cores 
Function evalcpuinfo 
   Exch $0 ; length 
   Exch 
   Exch $1 ; buffer 
   Push $2 
   Push $3 
   Push $4 
   Push $5 ; Processor Cores 
   Push $6 ; Logical Processors 

   ; Set buffer offset at the end of the buffer 
   StrCpy $2 $0 

   ; Initialize number of Processor Cores and Logical Processors 
   StrCpy $5 0 
   StrCpy $6 0 

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

   ; Set processor information as return value 
   StrCpy $0 $5

   Pop $6 
   Pop $5 
   Pop $4 
   Pop $3 
   Pop $2 
   Pop $1 
   Exch $0 
FunctionEnd 

; Get processor information 
; Returns: number of Processor Cores and Logical Processors 
Function getcpuinfo 
  Push $0 
  Push $1 
  Push $2 
  Push $3 
  Push $4 

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

  ; Initialize buffer and its length 
  StrCpy $1 0 
  StrCpy $2 0 

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

  Pop $4 
  Pop $3 
  Pop $2 
  Pop $1 
  Exch $0 
FunctionEnd  

我认为代码与Anders代码非常相似。我已经在三台不同的PC上试过并获得了正确的处理器核心数。