CPU功能.GetCount返回的CPU内核数不正确



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

${CPUFeatures.GetCount} $CPUCore

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

或者,有其他方法可以获得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 $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]。。。

我尝试使用这个论坛中的代码,并对其进行了一点修改,所以我只得到处理器核心编号:

!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  

我认为代码与安德斯代码非常相似。我已经在三台不同的电脑上试用过,并得到了处理器核心的正确数字。

最新更新