Rishodi Posted September 30, 2010 Posted September 30, 2010 I need a way to pull information about the CPU(s) in the system on which I run my script. I've been using CompInfo.au3 for a couple of years now, but this is the first time that I've had significant trouble with it. Using the _ComputerGetProcessors function to pull data from the WMI Win32_Processor class has always worked in the past, but no longer.The workstation I'm testing my script on has an Intel Core 2 Duo T9400. However, a query of all Win32_Processor objects returns only a single object with the name "Intel Pentium III Xeon processor". Of course, that's quite wrong, though some of the other information appears correctly, such as the clock speed and L2 cache size. I haven't found anything useful in Microsoft's WMI documentation yet. How can I get the correct processor information?
BrewManNH Posted September 30, 2010 Posted September 30, 2010 You'll get that return because WMI doesn't know about the newer processors. It's reading the processor info and it must be returning the value of 176, which to the Win32_processor function, that means it's a Xeon P3. Unless Microsoft updates the returns for the newer CPUs or the manufacturers of the CPUs use different architecture codes, it won't change. If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag GudeHow to ask questions the smart way! I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from. Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays. - ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script. - Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label. - _FileGetProperty - Retrieve the properties of a file - SciTE Toolbar - A toolbar demo for use with the SciTE editor - GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI. - Latin Square password generator
Varian Posted September 30, 2010 Posted September 30, 2010 (edited) Download the WMI Code Creator here. Try the Namespace as: "root\CIMV2" and the property as "Description"EDIT: Make sure that you run "WMICodeCreator.exe" as Administrator Edited September 30, 2010 by Varian
Varian Posted October 1, 2010 Posted October 1, 2010 This works on my 2008R2...not very efficient thoughTraySetState() #include <Misc.au3> _Singleton(@ScriptName, 0) Global $wTitle = '[REGEXPTITLE:(?i)System Information; CLASS:#32770]', $Item, $Text If Not ProcessExists('msinfo32.exe') Then Run('msinfo32.exe', '', @SW_HIDE) WinWait($wTitle, '') $hWindow = WinGetHandle($wTitle, '') WinSetState($hWindow, '', @SW_HIDE) Do $Item = ControlListView($hWindow, '', 'SysListView321', 'FindItem', 'Processor') Until $Item Do $Text = ControlListView($hWindow, '', 'SysListView321', 'GetText', $Item, 1) Until $Text ProcessClose('msinfo32.exe') MsgBox(32, 'Processor', $Text)
Rishodi Posted October 1, 2010 Author Posted October 1, 2010 You'll get that return because WMI doesn't know about the newer processors. It's reading the processor info and it must be returning the value of 176, which to the Win32_processor function, that means it's a Xeon P3. Unless Microsoft updates the returns for the newer CPUs or the manufacturers of the CPUs use different architecture codes, it won't change.Yes, I presumed that the WMI information is outdated, but why? I know the correct information is somewhere on my system. My CPU shows up correctly in System Properties and Device Manager as Intel Core 2 Duo CPU T9400 @ 2.53 GHz. Shouldn't there be some way to get that information through COM objects?Download the WMI Code Creator here. Try the Namespace as: "root\CIMV2" and the property as "Description"EDIT: Make sure that you run "WMICodeCreator.exe" as AdministratorThe Description property of the lone Win32_Processor object is this: x86 Family 6 Model 23 Stepping 10. Not very useful, unfortunately.The processor info given in msinfo32 isn't helpful either. The full text field is x86 Family 6 Model 23 Stepping 10 GenuineIntel ~2527 Mhz, which doesn't give me any information I couldn't get through WMI. Those are the Description, Manufacturer, and CurrentClockSpeed properties in order.
trancexx Posted October 1, 2010 Posted October 1, 2010 You'll get that return because WMI doesn't know about the newer processors. It's reading the processor info and it must be returning the value of 176, which to the Win32_processor function, that means it's a Xeon P3. Unless Microsoft updates the returns for the newer CPUs or the manufacturers of the CPUs use different architecture codes, it won't change. Processor info is stored inside the processor itself, on the lowest possible level. It's retrieved with CPUID instruction. If WMI fails to get right info then the reason is something else than what you think. I posted this somewhere already and other posted their versions too (maybe better). Again: expandcollapse popup#AutoIt3Wrapper_UseX64=n #include <Memory.au3> ; Allocating memory with $PAGE_EXECUTE_READWRITE Global $pRemoteCode = _MemVirtualAlloc(0, 512, $MEM_COMMIT, $PAGE_EXECUTE_READWRITE) ; Standard allocation in reserved address Global $tCodeBuffer = DllStructCreate("byte[512]", $pRemoteCode) ;XXXXXXXXXXXXXX BASIC CALLING PARAMETER XXXXXXXXXXXXXXXXXXXXXXXXXX ConsoleWrite("! EAX = 0" & @CRLF) ; Buffer to fill with data: Global $tBuffer = DllStructCreate("char[12]") ; Pointer to it: Global $pBuffer = DllStructGetPtr($tBuffer) ; Code: DllStructSetData($tCodeBuffer, 1, _ "0x" & _ "" & _; 10. SET eax AND CALL "B8" & SwapEndian(0) & _ ; mov eax, 0 "0FA2" & _ ; cpuid "" & _ ; 20. ARRANGE DATA "891D" & SwapEndian($pBuffer) & _ ; mov dword[$pBuffer], ebx "8915" & SwapEndian($pBuffer + 4) & _ ; mov dword[$pBuffer + 4], edx "890D" & SwapEndian($pBuffer + 8) & _ ; mov dword[$pBuffer + 8], ecx "" & _ ; 30. RETURN "C3" _ ) ; Execute it: Global $iRet = _RunAtAddress($pRemoteCode) ; Return: ConsoleWrite("Return: " & $iRet & @CRLF) ; Collected data: ConsoleWrite("The highest basic calling parameter: " & $iRet & @CRLF) ConsoleWrite("Vendor ID: " & DllStructGetData($tBuffer, 1) & @CRLF) ConsoleWrite(@CRLF & @CRLF) ConsoleWrite("! EAX = 1" & @CRLF) ; New buffer: $tBuffer = DllStructCreate("dword[4]") ; Pointer to it: $pBuffer = DllStructGetPtr($tBuffer) DllStructSetData($tCodeBuffer, 1, _ "0x" & _ "" & _ ; 10. SET eax AND CALL "B8" & SwapEndian(1) & _ ; mov eax, 1 "0FA2" & _ ; cpuid "" & _ ; 20. ARRANGE DATA "A3" & SwapEndian($pBuffer) & _ ; mov dword[$pBuffer], eax "8915" & SwapEndian($pBuffer + 4) & _ ; mov dword[$pBuffer + 4], edx "890D" & SwapEndian($pBuffer + 8) & _ ; mov dword[$pBuffer + 8], ecx "891D" & SwapEndian($pBuffer + 12) & _ ; mov dword[$pBuffer + 12], ebx "" & _ ; 30. RETURN "C3" _ ) ; Execute it: $iRet = _RunAtAddress($pRemoteCode) ; Return eax: ConsoleWrite("Return: " & $iRet & @CRLF) ; Collected data: ConsoleWrite("EAX: " & DllStructGetData($tBuffer, 1, 1) & @CRLF) ConsoleWrite("Hyper-Threading Technology: " & BitShift(DllStructGetData($tBuffer, 1, 2), 28) & @CRLF) ; bit 28 ConsoleWrite("ECX (feature flag): " & DllStructGetData($tBuffer, 1, 3) & @CRLF) ConsoleWrite("EBX (LogicalProcessorCount): " & DllStructGetData($tBuffer, 1, 4) & @CRLF) ConsoleWrite("+ Derived out of EAX: " & @CRLF) $iEAX = DllStructGetData($tBuffer, 1, 1) $iStepping = BitAND($iEAX, 0xF) ; 0-3 ConsoleWrite(" Stepping: " & $iStepping & @CRLF) $iBaseModel = BitAND(BitShift($iEAX, 4), 0xF) ; 4-7 ConsoleWrite(" BaseModel: " & $iBaseModel & @CRLF) $iBaseFamily = BitAND(BitShift($iEAX, 8), 0xF) ; 8-11 ConsoleWrite(" BaseFamily: " & $iBaseFamily & @CRLF) ConsoleWrite(" Reserved: " & BitAND(BitShift($iEAX, 12), 0xF) & @CRLF) ; 12-15 $iExtendedModel = BitAND(BitShift($iEAX, 16), 0xF) ; 16-19 ConsoleWrite(" Extended Model: " & $iExtendedModel & @CRLF) $iExtendedFamily = BitAND(BitShift($iEAX, 20), 0xFF) ; 20-27 ConsoleWrite(" Extended Family: " & $iExtendedFamily & @CRLF) ConsoleWrite(" Reserved: " & BitAND(BitShift($iEAX, 28), 0xF) & @CRLF) ; 28-31 ConsoleWrite("+ Derived out of that: " & @CRLF) ConsoleWrite(" Model: " & "~~" & @CRLF) ;<- needs calculating ConsoleWrite(" Family: " & "~~" & @CRLF) ;<- needs calculating ConsoleWrite("+ Derived out of EBX: " & @CRLF) $iEBX = DllStructGetData($tBuffer, 1, 4) $iBrandID = BitAND($iEBX, 0xFF) ; 0-7 ConsoleWrite(" Brand ID: " & $iBrandID & @CRLF) $iCLFLUSH = BitAND(BitShift($iEBX, 8), 0xFF) ; 8-15 ConsoleWrite(" CLFLUSH size: " & $iCLFLUSH & @CRLF) $iLogicalProcessorCount = BitAND(BitShift($iEBX, 16), 0xFF) ; 16-23 ConsoleWrite(" LogicalProcessorCount: " & $iLogicalProcessorCount & @CRLF) $LocalApicId = BitAND(BitShift($iEBX, 24), 0xFF) ; 24-32 ConsoleWrite(" LocalApicId: " & $LocalApicId & @CRLF) ConsoleWrite(@CRLF & @CRLF) ConsoleWrite("! EAX = 2" & @CRLF); This one is couldn't be tested with me (the highest basic calling parameter returned 1) ; New buffer: $tBuffer = DllStructCreate("dword[4]") ; Pointer to it: $pBuffer = DllStructGetPtr($tBuffer) DllStructSetData($tCodeBuffer, 1, _ "0x" & _ "" & _ ; 10. SET eax AND CALL "B8" & SwapEndian(2) & _ ; mov eax, 2 "0FA2" & _ ; cpuid "" & _ ; 20. ARRANGE DATA "A3" & SwapEndian($pBuffer) & _ ; mov dword[$pBuffer], eax "891D" & SwapEndian($pBuffer + 4) & _ ; mov dword[$pBuffer + 4], ebx "890D" & SwapEndian($pBuffer + 8) & _ ; mov dword[$pBuffer + 8], ecx "8915" & SwapEndian($pBuffer + 12) & _ ; mov dword[$pBuffer + 12], edx "" & _ ; 30. RETURN "C3" _ ) ; Execute it: $iRet = _RunAtAddress($pRemoteCode) ; Return eax: ConsoleWrite("Return: " & $iRet & @CRLF) ; Collected data: ConsoleWrite("EAX: " & DllStructGetData($tBuffer, 1, 1) & @CRLF) ConsoleWrite("EBX: " & DllStructGetData($tBuffer, 1, 2) & @CRLF) ConsoleWrite("ECX: " & DllStructGetData($tBuffer, 1, 3) & @CRLF) ConsoleWrite("EDX: " & DllStructGetData($tBuffer, 1, 4) & @CRLF) ; ...etc, depending on he highest basic calling parameter ;XXXXXXXXXXXXXX EXTENDED CALLING PARAMETER XXXXXXXXXXXXXXXXXXXXXXXXXX ConsoleWrite(@CRLF & @CRLF) ConsoleWrite("! EAX = 0x80000000" & @CRLF) ; New buffer: $tBuffer = DllStructCreate("dword[4]") ; Pointer to it: $pBuffer = DllStructGetPtr($tBuffer) DllStructSetData($tCodeBuffer, 1, _ "0x" & _ "" & _ ; 10. SET eax AND CALL "B8" & SwapEndian(0x80000000) & _ ; mov eax, 0x80000000 "0FA2" & _ ; cpuid "" & _ ; 20. ARRANGE DATA "A3" & SwapEndian($pBuffer) & _ ; mov dword[$pBuffer], eax "" & _ ; 30. RETURN "C3" _ ) ; Execute it: $iRet = _RunAtAddress($pRemoteCode) ; Return eax: ConsoleWrite("Return: " & $iRet & @CRLF) ; Collected data: ConsoleWrite("The highest extended calling parameter: " & Ptr(DllStructGetData($tBuffer, 1, 1)) & @CRLF) ConsoleWrite(@CRLF & @CRLF) ConsoleWrite("! EAX = 0x80000001" & @CRLF) ; New buffer: $tBuffer = DllStructCreate("dword[4]") ; Pointer to it: $pBuffer = DllStructGetPtr($tBuffer) DllStructSetData($tCodeBuffer, 1, _ "0x" & _ "" & _ ; 10. SET eax AND CALL "B8" & SwapEndian(0x80000001) & _ ; mov eax, 0x80000001 "0FA2" & _ ; cpuid "" & _ ; 20. ARRANGE DATA "A3" & SwapEndian($pBuffer) & _ ; mov dword[$pBuffer], eax "891D" & SwapEndian($pBuffer + 4) & _ ; mov dword[$pBuffer + 4], ebx "890D" & SwapEndian($pBuffer + 8) & _ ; mov dword[$pBuffer + 8], ecx "8915" & SwapEndian($pBuffer + 12) & _ ; mov dword[$pBuffer + 12], edx "" & _ ; 30. RETURN "C3" _ ) ; Execute it: $iRet = _RunAtAddress($pRemoteCode) ; Return eax: ConsoleWrite("Return: " & $iRet & @CRLF) ; Collected data: ConsoleWrite("Extended feature flags EAX : " & DllStructGetData($tBuffer, 1, 1) & @CRLF) ConsoleWrite("Extended feature flags EBX : " & DllStructGetData($tBuffer, 1, 2) & @CRLF) ConsoleWrite("Extended feature flags ECX (CmpLegacy) : " & DllStructGetData($tBuffer, 1, 3) & @CRLF) ConsoleWrite("Extended feature flags EDX: " & DllStructGetData($tBuffer, 1, 4) & @CRLF) ConsoleWrite(@CRLF & @CRLF) ConsoleWrite("! EAX = 0x80000002->0x80000003->0x80000004" & @CRLF) ; New buffer: $tBuffer = DllStructCreate("char[48]") ; Pointer to it: $pBuffer = DllStructGetPtr($tBuffer) DllStructSetData($tCodeBuffer, 1, _ "0x" & _ "" & _ ; 10. SET eax AND CALL "B8" & SwapEndian(0x80000002) & _ ; mov eax, 0x80000002 "0FA2" & _ ; cpuid "" & _ ; 20. ARRANGE DATA "A3" & SwapEndian($pBuffer) & _ ; mov dword[$pBuffer], eax "891D" & SwapEndian($pBuffer + 4) & _ ; mov dword[$pBuffer + 4], ebx "890D" & SwapEndian($pBuffer + 8) & _ ; mov dword[$pBuffer + 8], ecx "8915" & SwapEndian($pBuffer + 12) & _ ; mov dword[$pBuffer + 12], edx "" & _ ; 30. SET eax AND CALL "B8" & SwapEndian(0x80000003) & _ ; mov eax, 0x80000003 "0FA2" & _ ; cpuid "" & _ ; 40. ARRANGE DATA "A3" & SwapEndian($pBuffer + 16) & _ ; mov dword[$pBuffer + 16], eax "891D" & SwapEndian($pBuffer + 20) & _ ; mov dword[$pBuffer + 20], ebx "890D" & SwapEndian($pBuffer + 24) & _ ; mov dword[$pBuffer + 24], ecx "8915" & SwapEndian($pBuffer + 28) & _ ; mov dword[$pBuffer + 28], edx "" & _ ; 50. SET eax AND CALL "B8" & SwapEndian(0x80000004) & _ ; mov eax, 0x80000004 "0FA2" & _ ; cpuid "" & _ ; 60. ARRANGE DATA "A3" & SwapEndian($pBuffer + 32) & _ ; mov dword[$pBuffer + 32], eax "891D" & SwapEndian($pBuffer + 36) & _ ; mov dword[$pBuffer + 36], ebx "890D" & SwapEndian($pBuffer + 40) & _ ; mov dword[$pBuffer + 40], ecx "8915" & SwapEndian($pBuffer + 44) & _ ; mov dword[$pBuffer + 44], edx "" & _ ; 70. RETURN "C3" _ ) ; Execute it: $iRet = _RunAtAddress($pRemoteCode) ; Return eax: ConsoleWrite("Return: " & $iRet & @CRLF) ; Collected data: ConsoleWrite("Processor brand string: " & DllStructGetData($tBuffer, 1) & @CRLF) MsgBox(0, '', DllStructGetData($tBuffer, 1)) ; And so on... ; Just one more: ConsoleWrite(@CRLF & @CRLF) ConsoleWrite("! EAX = 0x80000008" & @CRLF) ; New buffer: $tBuffer = DllStructCreate("dword[4]") ; Pointer to it: $pBuffer = DllStructGetPtr($tBuffer) DllStructSetData($tCodeBuffer, 1, _ "0x" & _ "" & _ ; 10. SET eax AND CALL "B8" & SwapEndian(0x80000008) & _ ; mov eax, 0x80000008 "0FA2" & _ ; cpuid "" & _ ; 20. ARRANGE DATA "A3" & SwapEndian($pBuffer) & _ ; mov dword[$pBuffer], eax "891D" & SwapEndian($pBuffer + 4) & _ ; mov dword[$pBuffer + 4], ebx "890D" & SwapEndian($pBuffer + 8) & _ ; mov dword[$pBuffer + 8], ecx "8915" & SwapEndian($pBuffer + 12) & _ ; mov dword[$pBuffer + 12], edx "" & _ ; 30. RETURN "C3" _ ) ; Execute it: $iRet = _RunAtAddress($pRemoteCode) ; Return eax: ConsoleWrite("Return: " & $iRet & @CRLF) ; Collected data: ConsoleWrite("EAX (largest virtual and physical address sizes): " & DllStructGetData($tBuffer, 1, 1) & @CRLF) ConsoleWrite("EBX: " & DllStructGetData($tBuffer, 1, 2) & @CRLF) ConsoleWrite("ECX: " & DllStructGetData($tBuffer, 1, 3) & @CRLF) ConsoleWrite("EDX: " & DllStructGetData($tBuffer, 1, 4) & @CRLF) ; Maximum number of cores $iApicIdCoreIdSize = BitAND(DllStructGetData($tBuffer, 1, 3), 0xF) ; 0-3 ECX ConsoleWrite("ApicIdCoreIdSize = " & $iApicIdCoreIdSize & @CRLF) If $iApicIdCoreIdSize = 0 Then $IMNC = 1 Else $IMNC = 2 ^ $iApicIdCoreIdSize EndIf ConsoleWrite("Maximum number of cores " & $IMNC & @CRLF) Func _RunAtAddress($pCode) Local $aCall = DllCall("user32.dll", "dword_ptr", "CallWindowProcW", "ptr", $pCode, "ptr", 0, "dword", 0, "wparam", 0, "lparam", 0) If @error Then Return SetError(1, 0, 0) Return $aCall[0] EndFunc ;==>_RunAtAddress Func SwapEndian($iValue, $iSize = 0) If $iSize Then Local $sPadd = "00000000" Return Hex(BinaryMid($iValue, 1, $iSize)) & StringLeft($sPadd, 2 * ($iSize - BinaryLen($iValue))) EndIf Return Hex(Binary($iValue)) EndFunc ;==>SwapEndian ♡♡♡ . eMyvnE
BrewManNH Posted October 1, 2010 Posted October 1, 2010 Using the WMI code creator, use the Win32_Processor drop down selection, and then look at Name. If you run the test script, you should see the name of the processor as Windows sees it. I'm not at home right now, so I don't have the actual names of the comboboxes to look at, but this should point you in the right direction. If you still need help, let us know, and once I get to my home computer I can get the exact information. If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag GudeHow to ask questions the smart way! I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from. Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays. - ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script. - Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label. - _FileGetProperty - Retrieve the properties of a file - SciTE Toolbar - A toolbar demo for use with the SciTE editor - GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI. - Latin Square password generator
Rishodi Posted October 1, 2010 Author Posted October 1, 2010 (edited) Processor info is stored inside the processor itself, on the lowest possible level. It's retrieved with CPUID instruction. If WMI fails to get right info then the reason is something else than what you think. I posted this somewhere already and other posted their versions too (maybe better). Again:Thanks, that works perfectly! I didn't expect to have to use CPUID instruction directly, but without knowing an alternative to WMI with which Windows would surface this data, that'll do just fine.Using the WMI code creator, use the Win32_Processor drop down selection, and then look at Name. If you run the test script, you should see the name of the processor as Windows sees it. I'm not at home right now, so I don't have the actual names of the comboboxes to look at, but this should point you in the right direction. If you still need help, let us know, and once I get to my home computer I can get the exact information.As I have posted above, WMI is not showing the correct information in the Name property. It contains the string Intel Pentium III Xeon processor. The correct processor brand string is displayed in Device Manager, System Properties, and is returned using the CPUID instruction in the code posted by trancexx, but does not appear to be accessible through WMI.What OS are you running?XP Pro SP3 Edited October 1, 2010 by Rishodi
ashigro Posted April 24, 2014 Posted April 24, 2014 could you please advise on how to execute that code?
Moderators JLogan3o13 Posted April 24, 2014 Moderators Posted April 24, 2014 (edited) ashigro, did you not notice this thread is 4 years old? Please don't resurrect old threads, as the language has evolved a lot in the last four years. If you're experiencing an issue with your script, please begin a new thread with a detailed explanation; you can even link to this thread if you believe it particularly relevent. Edited April 24, 2014 by JLogan3o13 "Profanity is the last vestige of the feeble mind. For the man who cannot express himself forcibly through intellect must do so through shock and awe" - Spencer W. Kimball How to get your question answered on this forum!
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now