[Module] [Windows] Hardware-Monitoring (Aida64)

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Benutzeravatar
Bisonte
Beiträge: 2430
Registriert: 01.04.2007 20:18

[Module] [Windows] Hardware-Monitoring (Aida64)

Beitrag von Bisonte »

aida, aida64, sensor

Hallo.

Hier ein Modul, um die Sensordaten von Aida64 Extreme auszulesen. Es ist nur für Windows, da
1. Aida64Extrem und 2. API benutzt wird.

Benötigt natürlich Aida64 Extreme (weiss nicht ob es auch mit der 'nicht Extreme' Version klappt),
dort muss in den Einstellungen 'Externe Applikationen' bei Hardware Überwachung "Aktiviere Shared Memory"
ausgewählt sein ... und natürlich auch ein paar Sensoren.

Im Fall des Beispiels muss Temperatur-CPU Package (TCPUPKG) und System-CPUAuslastung (SCPUUTI) ausgewählt sein,
damit auch etwas angezeigt wird.

Die Werte der Sensoren wird in einer Liste gespeichert. Diese sollte nur zum LESEN benutzt werden.
Man kann aber auch die Werte einzelnd abfragen...

Verbesserungsvorschläge ? Immer her damit !

Hier habe ich das ganze mit Stringoperationen auseinandergezerrt, da die Ausgabe von Aida ein String in einem XML ähnlichen Format ist.

Bei meinen Tests hat die Abfrage der Werte 5ms mit Debugger gedauert. Evt. gehts ja anders noch schneller ?
XML ? ASM ? Einfach nur anders als hier gelöst ?

P.S. : Threadsafe muss in den Optionen eingetellt sein... na dann... gehts los ;)

Code: Alles auswählen

;: ############################################################################
;: # 
;: # Module     : Aida64
;: # 
;: # Author     : Bisonte
;: # Date       : 02. November 2015
;: # COpt.      : THREAD
;: # PB Version : 5.40 LTS Final
;: # 
;: ############################################################################
;: 
;: To get the SharedMemory SensorData of Aida64
;: Req. CompilerOption Threadsafe
;: and, of course, Aida64 with Shared Memory enabled
;: (and some sensors marked)
;: 
;: Tested with Aida64 Extrem on Win10 Pro x64
;: The Demo shows CPU Package Temperature and CPU Utilization if marked
;: in Aida64

DeclareModule Aida64
  
  EnableExplicit
  
  #AIDA64_SensorValues = "AIDA64_SensorValues"
  
  Structure aida_sensordata
    category.s
    id.s
    label.s
    value.s
  EndStructure
  
  Global NewList Aida64Sensor.aida_sensordata()
  
  Declare.i StartAida64(Delay = 1000, CustomEvent = #PB_Event_FirstCustomValue)
  Declare.i StopAida64()
  Declare.s GetSensorValueOverID(ID.s)
  Declare.s GetSensorValueOverLabel(Label.s)
  
EndDeclareModule
Module        Aida64

  CompilerIf Not #PB_Compiler_Thread
    CompilerError "Module : 'Aida64' requires ThreadSafe Compileroption!"
  CompilerEndIf  
  
  Global Mutex = CreateMutex()
  Global Thread = #False
  Global Halt   = #False
  Global CEvent = #PB_Event_FirstCustomValue
  
  Procedure.s _GetString(String.s, Before.s, After.s)
    
    Protected Result.s
    Protected Start, Stop
    
    Start = FindString(String, Before)
    Stop  = FindString(String, After)
    
    If Start > 0 And Stop > Start
      Result = Mid(String, Start + Len(Before), (Stop-Len(After)) - Start + 1)  
    EndIf
    
    ProcedureReturn Result
    
  EndProcedure  
  Procedure GetAidaSensorList(Delay)
    
    Protected handle, *Mem, Size, Result.s, String.s
    
    While Halt <> #True
      
      LockMutex(mutex)
      
      ClearList(Aida64Sensor())
      
      handle = OpenFileMapping_(#FILE_MAP_ALL_ACCESS, 0, "AIDA64_SensorValues")
      If handle
        *Mem = MapViewOfFile_(handle, #FILE_MAP_ALL_ACCESS, 0, 0, 0)
        If *Mem
          Size = MemoryStringLength(*Mem, #PB_Ascii)
          Result = PeekS(*Mem, Size, #PB_Ascii)
          While Result <> ""
            String = Left(Result, FindString(Result, ">"))
            String + _GetString(Result, Left(Result, FindString(Result, ">")), "</" + Mid(Left(Result, FindString(Result, ">")), 2))
            String + "</" + Mid(Left(Result, FindString(Result, ">")), 2)
            AddElement(Aida64Sensor())
            Aida64Sensor()\category = Left(String, FindString(String, ">"))
            Aida64Sensor()\id  = _GetString(String, "<id>", "</id>")
            Aida64Sensor()\label = _GetString(String, "<label>", "</label>")
            Aida64Sensor()\value = _GetString(String, "<value>", "</value>")
            Result = Mid(Result, Len(String) + 1)
          Wend
          UnmapViewOfFile_(*Mem)
        EndIf
        CloseHandle_(handle)
      EndIf
      
      UnlockMutex(mutex)
      
      PostEvent(CEvent)
      
      Delay(Delay)

    Wend
    
  EndProcedure
  Procedure StartAida64(Delay = 1000, CustomEvent = #PB_Event_FirstCustomValue)
    
    Protected Result
    
    If IsThread(Thread) : Halt = #True : EndIf
    
    CEvent = CustomEvent
    Thread = CreateThread(@GetAidaSensorList(), Delay)
    If Thread
      ProcedureReturn #True
    EndIf
    
    ProcedureReturn #False
    
  EndProcedure
  Procedure StopAida64()
    If IsThread(Thread) : Halt = #True : EndIf
  EndProcedure
  
  Procedure.s GetSensorValueOverID(ID.s)
    Protected Result.s
    ForEach Aida64Sensor()
      If Aida64Sensor()\id = ID
        Result = Aida64Sensor()\value
        Break
      EndIf
    Next
    ProcedureReturn Result
  EndProcedure
  Procedure.s GetSensorValueOverLabel(Label.s)
    Protected Result.s
    ForEach Aida64Sensor()
      If Aida64Sensor()\label = Label
        Result = Aida64Sensor()\value
        Break
      EndIf
    Next
    ProcedureReturn Result
  EndProcedure  
  
EndModule

CompilerIf #PB_Compiler_IsMainFile
  
  EnableExplicit
  
  #AIDA64_DataReady = #PB_Event_FirstCustomValue
  
  Define Event, CPUTEMP, CPUUTIL
  
  OpenWindow(0, 0, 0, 100, 150, "Aida64", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)

  CanvasGadget(1, 10, 10, 50, 100)
  TextGadget(2, 10, 110, 20, 25, "", #PB_Text_Center)
  TextGadget(3, 40, 110, 20, 25, "", #PB_Text_Center)

  Aida64::StartAida64(500, #AIDA64_DataReady)
  
  Repeat
    Event = WaitWindowEvent()
    
    Select Event
      Case #PB_Event_CloseWindow
        Aida64::StopAida64()
        Break
      Case #AIDA64_DataReady
        If StartDrawing(CanvasOutput(1))
          CPUTEMP = Val(Aida64::GetSensorValueOverID("TCPUPKG"))
          CPUUTIL = Val(Aida64::GetSensorValueOverID("SCPUUTI"))
          Box(0, 0, OutputWidth(), OutputHeight(), GetSysColor_(#COLOR_BTNFACE))
          DrawingMode(#PB_2DDrawing_Gradient)
          BackColor(#Red) : FrontColor(#Green)
          LinearGradient(0, 0, 20, 100)
          Box(0, 100, 20, -CPUTEMP, 0)
          Box(30, 100, 20, -CPUUTIL, 0)
          StopDrawing()
        EndIf
        SetGadgetText(2, Str(CPUTEMP))
        SetGadgetText(3, Str(CPUUTIL) + "%")
        
    EndSelect
    
  ForEver

CompilerEndIf
Zuletzt geändert von Bisonte am 03.11.2015 05:16, insgesamt 1-mal geändert.
PureBasic 6.10 LTS (Windows x86/x64) | Windows10 Pro x64 | Asus TUF X570 Gaming Plus | R9 5900X | 64GB RAM | GeForce RTX 3080 TI iChill X4 | HAF XF Evo | build by vannicom​​
Benutzeravatar
Kiffi
Beiträge: 10621
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Re: [Module] [Windows] Aida64

Beitrag von Kiffi »

Hallo Bisonte,

(ich möchte Deinen Thread nicht kapern, deswegen habe ich meinen Code hierhin ausgelagert)

Ich würde es mit WMI machen. Ist wahrscheinlich nicht so performant, kostet dafür aber nichts. ;-)

Grüße ... Peter
Hygge
Benutzeravatar
Bisonte
Beiträge: 2430
Registriert: 01.04.2007 20:18

Re: [Module] [Windows] Aida64

Beitrag von Bisonte »

Nunja... mir ging es da hauptsächlich um die Hardware-Überwachung.
Also Temperaturfühler, Lüftergeschwindigkeiten, CPU Taktung usw. und die
bekomme ich, soweit ich weiss, nicht per WMI.

Das mit der CPU Auslastung war in meinem Beispiel natürlich nur exemplarisch, um zu zeigen, wie es geht.

Was den Kostenfaktor betrifft... Ich glaube HWInfo kann das auch und macht es womöglich auf gleiche Weise. Mal sehen ob ich damit
was anstellen kann ;)
PureBasic 6.10 LTS (Windows x86/x64) | Windows10 Pro x64 | Asus TUF X570 Gaming Plus | R9 5900X | 64GB RAM | GeForce RTX 3080 TI iChill X4 | HAF XF Evo | build by vannicom​​
Benutzeravatar
Kiffi
Beiträge: 10621
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Re: [Module] [Windows] Aida64

Beitrag von Kiffi »

Sorry, ich wollte Deinen Code nicht herabwürdigen. Wollte mit WMI nur eine kostenfreie Alternative aufzeigen. WMI ist die eierlegende Wollmilchsau, wenn es darum geht, Informationen rund um den Rechner zu ermitteln (inklusive Temperaturfühler, Lüftergeschwindigkeiten, CPU Taktung, ...).

Grüße ... Peter
Hygge
Benutzeravatar
Bisonte
Beiträge: 2430
Registriert: 01.04.2007 20:18

Re: [Module] [Windows] Aida64

Beitrag von Bisonte »

Auch Temperatur ? Alle Achtung. Wenn Du mir jetzt nur noch verraten kannst, wo ich nachlesen kann, wie man das ganze anwendet ....

Das mit HWInfo hat sich erledigt. Der Author möchte von jedem der seine .dll nutzen möchte eine Email mit Projektbeschreibung usw. haben.
Da ist das für ein Open Source Modul wohl denkbar ungünstig ;)
PureBasic 6.10 LTS (Windows x86/x64) | Windows10 Pro x64 | Asus TUF X570 Gaming Plus | R9 5900X | 64GB RAM | GeForce RTX 3080 TI iChill X4 | HAF XF Evo | build by vannicom​​
Benutzeravatar
Kiffi
Beiträge: 10621
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Re: [Module] [Windows] Aida64

Beitrag von Kiffi »

Bisonte hat geschrieben:Auch Temperatur ? Alle Achtung. Wenn Du mir jetzt nur noch verraten kannst, wo ich nachlesen kann, wie man das ganze anwendet ....
ursprünglich wollte ich MSAcpi_ThermalZoneTemperature oder Win32_TemperatureProbe vorschlagen, bis ich bemerkte, dass diese Abfragen wohl nicht auf jedem Rechner funktionieren (auf meinem Büro-Rechner: ja; auf meinem Heim-Rechner: nein), was natürlich Käse ist.

Dann fand ich aber dieses kleine Schmuckstück hier: OpenHardwareMonitor.

Bild

OpenHardwareMonitor speist seine ermittelten Daten in das WMI ein, welche man dann wieder recht einfach auslesen kann:

Code: Alles auswählen

EnableExplicit

Define VbScript.s
Define VBS
Define Xml.s

VbScript.s = "strComputer = ''.''" + #CRLF$ + 
             "Set objWMIService = GetObject(''winmgmts:{impersonationLevel=impersonate}!\\'' & strComputer & ''\root\OpenHardwareMonitor'')" + #CRLF$ + 
             "Set colItems = objWMIService.ExecQuery(''Select * From Hardware'')" + #CRLF$ + 
             "Output = ''<OpenHardwareMonitor>''" + #CRLF$ + 
             "Output = Output & ''<Hardware>''" + #CRLF$ + 
             "For Each objItem in colItems" + #CRLF$ + 
             "  Output = Output & ''<element>''" + #CRLF$ + 
             "  Output = Output & ''<HardwareType>'' & objItem.HardwareType & ''</HardwareType>''" + #CRLF$ + 
             "  Output = Output & ''<Identifier>'' & objItem.Identifier & ''</Identifier>''" + #CRLF$ + 
             "  Output = Output & ''<InstanceId>'' & objItem.InstanceId & ''</InstanceId>''" + #CRLF$ + 
             "  Output = Output & ''<Name>'' & objItem.Name & ''</Name>''" + #CRLF$ + 
             "  Output = Output & ''<Parent>'' & objItem.Parent & ''</Parent>''" + #CRLF$ + 
             "  Output = Output & ''<ProcessId>'' & objItem.ProcessId & ''</ProcessId>''" + #CRLF$ + 
             "  Output = Output & ''</element>''" + #CRLF$ + 
             "Next" + #CRLF$ + 
             "Output = Output & ''</Hardware>''" + #CRLF$ + 
             "Set colItems = objWMIService.ExecQuery(''SELECT * FROM Sensor'')" + #CRLF$ + 
             "Output = Output & ''<Sensor>''" + #CRLF$ + 
             "For Each objItem in colItems" + #CRLF$ + 
             "  Output = Output & ''<element>''" + #CRLF$ + 
             "  Output = Output & ''<Identifier>'' & objItem.Identifier & ''</Identifier>''" + #CRLF$ + 
             "  Output = Output & ''<Index>'' & objItem.Index & ''</Index>''" + #CRLF$ + 
             "  Output = Output & ''<InstanceId>'' & objItem.InstanceId & ''</InstanceId>''" + #CRLF$ + 
             "  Output = Output & ''<Max>'' & objItem.Max & ''</Max>''" + #CRLF$ + 
             "  Output = Output & ''<Min>'' & objItem.Min & ''</Min>''" + #CRLF$ + 
             "  Output = Output & ''<Name>'' & objItem.Name & ''</Name>''" + #CRLF$ + 
             "  Output = Output & ''<Parent>'' & objItem.Parent & ''</Parent>''" + #CRLF$ + 
             "  Output = Output & ''<ProcessId>'' & objItem.ProcessId & ''</ProcessId>''" + #CRLF$ + 
             "  Output = Output & ''<SensorType>'' & objItem.SensorType & ''</SensorType>''" + #CRLF$ + 
             "  Output = Output & ''<Value>'' & objItem.Value & ''</Value>''" + #CRLF$ + 
             "  Output = Output & ''</element>''" + #CRLF$ + 
             "Next" + #CRLF$ + 
             "Output = Output & ''</Sensor>''" + #CRLF$ + 
             "Output = Output & ''</OpenHardwareMonitor>''" + #CRLF$ + 
             "WScript.StdOut.Writeline Output" 

VbScript = ReplaceString(VbScript, "''", Chr(34))

CreateFile(0, GetTemporaryDirectory() + "cpuinfo.vbs")
WriteString(0, VbScript)
CloseFile(0)

VBS = RunProgram("wscript", GetTemporaryDirectory() + "cpuinfo.vbs", "", #PB_Program_Open | #PB_Program_Read)

If VBS
  Xml = ReadProgramString(VBS)
  CloseProgram(VBS)
Else
  Debug "!RunProgram"
EndIf

Structure sSensorElement
  Parent.s
  Name.s
  InstanceId.s
  Value.s
  Min.s
  Index.s
  Max.s
  Identifier.s
  ProcessId.s
  SensorType.s
EndStructure

Structure sHardwareElement
  HardwareType.s
  Name.s
  InstanceId.s
  Identifier.s
  ProcessId.s
EndStructure

Structure OpenHardwareMonitor
  List Hardware.sHardwareElement()
  List Sensor.sSensorElement()
EndStructure

If ParseXML(0, Xml) And XMLStatus(0) = #PB_XML_Success
  
  Define OpenHardwareMonitor.OpenHardwareMonitor

  ExtractXMLStructure(MainXMLNode(0), @OpenHardwareMonitor, OpenHardwareMonitor)
  
  FreeXML(0)
  
  Debug "Hardware:"
  Debug "========="
  
  ForEach OpenHardwareMonitor\Hardware()
    Debug "HardwareType: " + OpenHardwareMonitor\Hardware()\HardwareType
    Debug "Identifier: " + OpenHardwareMonitor\Hardware()\Identifier
    Debug "InstanceId: " + OpenHardwareMonitor\Hardware()\InstanceId
    Debug "Name: " + OpenHardwareMonitor\Hardware()\Name
    Debug "ProcessId: "+ OpenHardwareMonitor\Hardware()\ProcessId
    Debug "-----"
  Next
  
  Debug "Sensor:"
  Debug "======="
  
  ForEach OpenHardwareMonitor\Sensor()
    Debug "Identifier: " + OpenHardwareMonitor\Sensor()\Identifier
    Debug "Index: " + OpenHardwareMonitor\Sensor()\Index
    Debug "InstanceId: " + OpenHardwareMonitor\Sensor()\InstanceId
    Debug "Max: " + OpenHardwareMonitor\Sensor()\Max
    Debug "Min: " + OpenHardwareMonitor\Sensor()\Min
    Debug "Name: " + OpenHardwareMonitor\Sensor()\Name
    Debug "Parent: " + OpenHardwareMonitor\Sensor()\Parent
    Debug "ProcessId: " + OpenHardwareMonitor\Sensor()\ProcessId
    Debug "SensorType: " + OpenHardwareMonitor\Sensor()\SensorType
    Debug "Value: " + OpenHardwareMonitor\Sensor()\Value
    Debug "-----"
  Next
  
Else
  Debug XMLError(0)
EndIf
Grüße ... Peter
Hygge
Antworten