CPU Belastung eines Prozzesses in Prozent berechnen.
Mit
WMIC /OUTPUT:C:\temp\ProcessList.txt PROCESS get Caption,ProcessId, ExecutablePath,ParentProcessID,KernelModeTime,UserModeTime
Möchte ich bestimmte Prozzesse beobachten.
( Starte eine Batch Datei alle 5 min per geplanten Task).
Wieviel, welcher Art, von welchen ElternProzzzes, und die CPU Belastung in %.
Die ersten habe ich. Aber bei der Prozzessorbelastung in % tue ich micht schwer, weil die Angaben in Nanosekunden sind und nicht in Prozent. (Deswegen kann es noch sein das Batch gar nicht das richtige ist wegen den hohen Zahlen).
Langsam wird es er eine theoritsche Frage. Wie ich von dem Nanosekunde auf die Prozentualle Rechnerauslastung komme.
Alls möglichen Rechnenformelansätze die ich bis jetzt gefunden habe, und erst versucht habe per Excel auszuprobieren, wahren nicht wirklich erfolgversprechend.
Also ich habe folgende Textdatei mit den Zeiten der Prozzesse und möchte dann jetzt die prozentuale Verteilung.
Im Moment verfolge ich folgende Theorie.
- System Idel Process + System + KernelModeTime + UserModeTime von jeden Process zusammenaddiert ergeben 100 %. => Systemzeit
- Die Zeit eines Prozesses ist KernelModeTime + UserModeTime dieses Prozzesses => Prozzeszeit
- Die Prozentuale Belastung des Systems durch den Prozesse ist dann Prozzeszeit / Systemzeit *100 => Prozentualle Belastung .
Kann mir jemand bestätigen oder wiederlegen ob meine Überlegung richtig ist .
Und dann wie ich dann die Berechnung in Batch oder eventuell in VBS vornehme.
Viele Dank im Vorraus
WMIC /OUTPUT:C:\temp\ProcessList.txt PROCESS get Caption,ProcessId, ExecutablePath,ParentProcessID,KernelModeTime,UserModeTime
Möchte ich bestimmte Prozzesse beobachten.
( Starte eine Batch Datei alle 5 min per geplanten Task).
Wieviel, welcher Art, von welchen ElternProzzzes, und die CPU Belastung in %.
Die ersten habe ich. Aber bei der Prozzessorbelastung in % tue ich micht schwer, weil die Angaben in Nanosekunden sind und nicht in Prozent. (Deswegen kann es noch sein das Batch gar nicht das richtige ist wegen den hohen Zahlen).
Langsam wird es er eine theoritsche Frage. Wie ich von dem Nanosekunde auf die Prozentualle Rechnerauslastung komme.
Alls möglichen Rechnenformelansätze die ich bis jetzt gefunden habe, und erst versucht habe per Excel auszuprobieren, wahren nicht wirklich erfolgversprechend.
Also ich habe folgende Textdatei mit den Zeiten der Prozzesse und möchte dann jetzt die prozentuale Verteilung.
Caption ExecutablePath KernelModeTime ParentProcessId ProcessId UserModeTime
System Idle Process 2780593281250 0 0 0
System 14652812500 0 4 0
smss.exe 60937500 4 444 0
csrss.exe C:\WINDOWS\system32\csrss.exe 1637343750 444 492 282187500
winlogon.exe C:\WINDOWS\system32\winlogon.exe 514218750 444 516 46093750
services.exe C:\WINDOWS\system32\services.exe 815937500 516 564 81406250
lsass.exe C:\WINDOWS\system32\lsass.exe 380781250 516 576 57343750
svchost.exe C:\WINDOWS\system32\svchost.exe 5937500 564 752 1250000
svchost.exe C:\WINDOWS\system32\svchost.exe 291250000 564 832 61406250
svchost.exe C:\WINDOWS\system32\svchost.exe 21718750 564 896 6406250
svchost.exe C:\WINDOWS\system32\svchost.exe 12656250 564 912 2656250
svchost.exe C:\WINDOWS\System32\svchost.exe 2138906250 564 928 394062500
Im Moment verfolge ich folgende Theorie.
- System Idel Process + System + KernelModeTime + UserModeTime von jeden Process zusammenaddiert ergeben 100 %. => Systemzeit
- Die Zeit eines Prozesses ist KernelModeTime + UserModeTime dieses Prozzesses => Prozzeszeit
- Die Prozentuale Belastung des Systems durch den Prozesse ist dann Prozzeszeit / Systemzeit *100 => Prozentualle Belastung .
Kann mir jemand bestätigen oder wiederlegen ob meine Überlegung richtig ist .
Und dann wie ich dann die Berechnung in Batch oder eventuell in VBS vornehme.
Viele Dank im Vorraus
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 187255
Url: https://administrator.de/contentid/187255
Ausgedruckt am: 23.11.2024 um 01:11 Uhr
13 Kommentare
Neuester Kommentar
Hallo mycroftone,
so wie du das angehst, wirst du doch nie die Werte voneinander separieren können. Versuche doch wenigstens was Auswertbares daraus zu machen. Per Batch vielleicht erst mal so:
So spuckt dir der Code wenigstens ein "deutsch" umformatiertes (mit Semikola als Trennzeichen) CSV Format aus. Damit könntest du dann in Excel weiter arbeiten.
Da du damit aber noch nicht on the fly zum Ergebnis kommst und das per Batch auch nicht möglich ist, frage ich mich
- Warum Batch und nicht gleich VBS oder eine andere Sprache?
- Wie soll das Ergebnis der Aktion eigentlich aussehen? Ein zusätzlicher Prozentwert in jeder Zeile? In welchem Format?
Grüße
rubberman
so wie du das angehst, wirst du doch nie die Werte voneinander separieren können. Versuche doch wenigstens was Auswertbares daraus zu machen. Per Batch vielleicht erst mal so:
@echo off &setlocal
>"ProcessList.csv" (
for /f "delims=" %%i in (
'WMIC PROCESS get Caption^,ProcessId^,ExecutablePath^,ParentProcessID^,KernelModeTime^,UserModeTime /format:csv'
) do (
for /f "delims=" %%j in ("%%i") do (
set "line=%%j"
setlocal EnableDelayedExpansion
echo !line:,=;!
endlocal
)
)
)
Da du damit aber noch nicht on the fly zum Ergebnis kommst und das per Batch auch nicht möglich ist, frage ich mich
- Warum Batch und nicht gleich VBS oder eine andere Sprache?
- Wie soll das Ergebnis der Aktion eigentlich aussehen? Ein zusätzlicher Prozentwert in jeder Zeile? In welchem Format?
Grüße
rubberman
Hallo mycroftone!
Hier mal ein VBS-Skript (*.vbs), dass eine CSV-Datei mit Prozentangabe (letzte Spalte) erstellt:
Gruß Dieter
Hier mal ein VBS-Skript (*.vbs), dass eine CSV-Datei mit Prozentangabe (letzte Spalte) erstellt:
Const CsvPath = "E:\Test\Ausgabe.csv"
Const strComputer = "."
Dim objWMIService, colProcesses, colProcess, Fso, File, Text, Target, TimeSumme, i
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colProcesses = objWMIService.ExecQuery("Select * from Win32_Process")
ReDim Target(colProcesses.Count - 1): i = 0 'Array(Anzahl Prozesse)
For Each colProcess In colProcesses
With colProcess.Properties_
'Array(Zeilen, Spalten)
Target(i) = Array(.Item("Caption").Value, _
.Item("ProcessId").Value, _
.Item("ExecutablePath").Value, _
.Item("ParentProcessID").Value, _
.Item("KernelModeTime").Value, _
.Item("UserModeTime").Value, _
0) 'Item für Prozentangabe reservieren
If IsNull(Target(i)(2)) Then Target(i)(2) = "" 'Null-Rückgabe für Path eliminieren
'Zeiten der einzelnen Prozesse addieren
TimeSumme = TimeSumme + CDbl(Target(i)(4)) + CDbl(Target(i)(5))
i = i + 1 'Array(Zeile + 1)
End With
Next
'Text = Csv-Zeile mit Spalten-Überschrift
Text = "Caption;ProcessId;ExecutablePath;ParentProcessID;KernelModeTime;UserModeTime;Prozent" & vbCrLf
For i = 0 To UBound(Target) 'Prozentwerte/Prozess berechnen und in Array eintragen
'Prozentanteil im Format "0,000000%" in Array eintragen
Target(i)(6) = FormatNumber((CDbl(Target(i)(4)) + CDbl(Target(i)(5))) / TimeSumme * 100, 6) & "%"
'Text + Csv-Zeile der einzelnen Prozesse
Text = Text & Join(Array(Target(i)(0), _
Target(i)(1), _
Target(i)(2), _
Target(i)(3), _
Target(i)(4), _
Target(i)(5), _
Target(i)(6)), ";") & vbCrLf
Next
Set Fso = CreateObject("Scripting.FileSystemObject")
'Csv-Datei erzeugen
With Fso.CreateTextFile(CsvPath)
.Write Text
.Close
End With
Gruß Dieter
Hallo Zusammen.
@Dieter
Ähnlich hätte ich es vermutlich auch gelöst - vielleicht mit einem Recordset zur Sortierung der Daten, á la
[EDIT]Dieters Anregung folgend, Arrayelemente durch Namen ersetzt.[/EDIT]
@mycroftone
Ich weiß nicht recht, ob es das ist was du suchst. Natürlich bekommst du so keine Momentaufnahme (für eine eingeschränkte Zeitspanne), sondern eine Zusammenfassung über die gesamte Dauer der Windowssitzung. Heißt, ein Prozess der gerade erst gestartet wurde und momentan fast 100% CPU Auslastung verursacht, schlägt in deiner Auswertung vermutlich mit <1% zu Buche.
Grüße
rubberman
@Dieter
Ähnlich hätte ich es vermutlich auch gelöst - vielleicht mit einem Recordset zur Sortierung der Daten, á la
Dim oADORec, oWMI, colItems, oItem, oFSO, oFile
Dim arrFields, arrValues
Dim dblSum
Dim sExePath
' Usersettings
Const sCSVPath = "ProcessList.csv"
Const sDelim = ";"
Const sComputerName = "."
Const sReplaceNull = ""
Const iDecimales = 5
' Datentypen http://msdn.microsoft.com/en-us/library/windows/desktop/ms675318.aspx
Const adChar = 129
Const adUnsignedInt = 19
Const adUnsignedBigInt = 21
Const adDouble = 5
' Datei öffnen http://msdn.microsoft.com/en-us/library/314cz14s.aspx
Const ForWriting = 2
arrFields = Array("Caption", "ProcessId", "ExecutablePath", _
"ParentProcessID", "KernelModeTime", "UserModeTime", "ProcessorUsage")
dblSum = 0
' ADO Recordset http://msdn.microsoft.com/en-us/library/windows/desktop/ms681510.aspx
Set oADORec = CreateObject("ADODB.Recordset")
' Append http://msdn.microsoft.com/en-us/library/windows/desktop/ms681564.aspx
oADORec.Fields.Append "Caption", adChar , 1024
oADORec.Fields.Append "ProcessId", adUnsignedInt
oADORec.Fields.Append "ExecutablePath", adChar , 256
oADORec.Fields.Append "ParentProcessID", adUnsignedInt
oADORec.Fields.Append "KernelModeTime", adUnsignedBigInt
oADORec.Fields.Append "UserModeTime", adUnsignedBigInt
oADORec.Fields.Append "ProcessorUsage", adDouble
oADORec.Open
' Win32_Process Class http://msdn.microsoft.com/en-us/library/windows/desktop/aa394372.aspx
Set oWMI = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" _
& sComputerName & "\root\cimv2")
Set colItems = oWMI.ExecQuery("Select * from Win32_Process")
For Each oItem In colItems
If IsNull(oItem.ExecutablePath) Then
sExePath = sReplaceNull
Else
sExePath = oItem.ExecutablePath
End If
arrValues = Array(oItem.Caption, oItem.ProcessId, sExePath, _
oItem.ParentProcessID, oItem.KernelModeTime, oItem.UserModeTime, 0)
dblSum = dblSum + arrValues(4) + arrValues(5)
oADORec.AddNew arrFields, arrValues
Next
Set oItem = Nothing
Set colItems = Nothing
Set oWMI = Nothing
' CPU-Nutzung als Double-Wert hinzufügen
oADORec.MoveFirst
While Not oADORec.EOF
oADORec("ProcessorUsage").Value = _
(CDbl(oADORec("KernelModeTime")) + CDbl(oADORec("UserModeTime"))) / dblSum
oADORec.Update
oADORec.MoveNext
Wend
' Sort Property http://msdn.microsoft.com/en-us/library/windows/desktop/ms675783.aspx
' Prozesse mit der höchsten CPU-Nutzung nach oben sortieren
oADORec.Sort = "ProcessorUsage DESC"
' FileSystemObject http://msdn.microsoft.com/en-us/library/d6dw7aeh.aspx
' Schreiben der Daten in die CSV Datei
Set oFSO = CreateObject("Scripting.FileSystemObject")
Set oFile = oFSO.OpenTextFile(sCSVPath, ForWriting, True)
oFile.WriteLine "Caption" & sDelim & "ProcessId" & sDelim & "ExecutablePath" & _
sDelim & "ParentProcessID" & sDelim & "ProcessorUsage"
oADORec.MoveFirst
While Not oADORec.EOF
oFile.WriteLine _
oADORec("Caption") & sDelim & _
CStr(oADORec("ProcessId")) & sDelim & _
oADORec("ExecutablePath") & sDelim & _
CStr(oADORec("ParentProcessID")) & sDelim & _
CStr(Round(oADORec("ProcessorUsage") * 100, iDecimales)) & "%"
oADORec.MoveNext
Wend
oFile.Close
oADORec.Close
Set oADORec = Nothing
Set oFile = Nothing
Set oFSO = Nothing
@mycroftone
Ich weiß nicht recht, ob es das ist was du suchst. Natürlich bekommst du so keine Momentaufnahme (für eine eingeschränkte Zeitspanne), sondern eine Zusammenfassung über die gesamte Dauer der Windowssitzung. Heißt, ein Prozess der gerade erst gestartet wurde und momentan fast 100% CPU Auslastung verursacht, schlägt in deiner Auswertung vermutlich mit <1% zu Buche.
Grüße
rubberman
Hallo rubberman!
Die Idee, einen ADO-Recordset zu verwenden, finde ich auch ganz gut
Allerdings würde ich, wenn die Felder eh schon Namen haben, diese auch im restlichen Code - zwecks besserer Übersicht - mit Namen ansprechen.
Gruß Dieter
Die Idee, einen ADO-Recordset zu verwenden, finde ich auch ganz gut
Allerdings würde ich, wenn die Felder eh schon Namen haben, diese auch im restlichen Code - zwecks besserer Übersicht - mit Namen ansprechen.
Gruß Dieter
Hallo Dieter,
einverstanden, ich werde es apassen. Der Grund dafür war, dass Änderungen (englische durch deutsche Feldnamen ersetzen o.ä.) nur an einer Stelle vergenommen werden müssten. Redundanzen sind dabei fehleranfälliger. Da Editoren aber heute eine "Ersetzen" Funktion mitbringen, ist das nicht weiter tragisch
Grüße
rubberman
einverstanden, ich werde es apassen. Der Grund dafür war, dass Änderungen (englische durch deutsche Feldnamen ersetzen o.ä.) nur an einer Stelle vergenommen werden müssten. Redundanzen sind dabei fehleranfälliger. Da Editoren aber heute eine "Ersetzen" Funktion mitbringen, ist das nicht weiter tragisch
Grüße
rubberman
Hallo rubberman!
Gruß Dieter
einverstanden, ich werde es apassen.
Ein Weiser EntschlußDer Grund dafür war, dass Änderungen (englische durch deutsche Feldnamen
ersetzen o.ä.) nur an einer Stelle vergenommen werden müssten.
Das hatte ich auch so verstandenersetzen o.ä.) nur an einer Stelle vergenommen werden müssten.
Da Editoren aber heute eine "Ersetzen" Funktion mitbringen,
ist das nicht weiter tragisch
Das sehe ich genausoist das nicht weiter tragisch
Gruß Dieter
Hallo mycroftone!
Die Formel stimmt schon, aber die gelieferten Werte taugen nicht für eine Berechnung der aktuellen Prozessleistung.
Die Zeit wird ja nur aufaddiert und dadurch auch nicht mehr weniger. D.h. wenn ich z.B. den Virenscanner starte, dann steigt die KernelModeTime und UserModeTime masiv an und bleibt nach Fertigstellung weiterhin in seiner Größe erhalten, was zur Folge hat, dass der Virenscanner danach zwar 0% Last zieht aber immernoch eine hohe Prozesslast berechnet wird während die anderen Prozesse so vor sich hin döddeln.
Du kannst auf diese Weise also nur ermitteln, wieviel Last ein Prozess insgesamt seit dem Windows-Start gezogen hat.
Gruß Dieter
Die Formel stimmt schon, aber die gelieferten Werte taugen nicht für eine Berechnung der aktuellen Prozessleistung.
Die Zeit wird ja nur aufaddiert und dadurch auch nicht mehr weniger. D.h. wenn ich z.B. den Virenscanner starte, dann steigt die KernelModeTime und UserModeTime masiv an und bleibt nach Fertigstellung weiterhin in seiner Größe erhalten, was zur Folge hat, dass der Virenscanner danach zwar 0% Last zieht aber immernoch eine hohe Prozesslast berechnet wird während die anderen Prozesse so vor sich hin döddeln.
Du kannst auf diese Weise also nur ermitteln, wieviel Last ein Prozess insgesamt seit dem Windows-Start gezogen hat.
Gruß Dieter
Hallo mycroftone.
Klingt doch nicht schlecht. Eine gewisse Zeitspanne (iWait) muss aber dazwischen liegen. Versuch macht klug ...
Prozesse, die während der Laufzeit des Scripts hinzukommen oder beendet werden, werden nicht betrachtet.
Grüße
rubberman
Klingt doch nicht schlecht. Eine gewisse Zeitspanne (iWait) muss aber dazwischen liegen. Versuch macht klug ...
Dim oADORec, oWMI, colItems, oItem, oFSO, oFile
Dim arrFields, arrValues
Dim sExePath
Dim dblSum
' Usersettings
Const sCSVPath = "ProcessList.csv"
Const sDelim = ";"
Const sComputerName = "."
Const sReplaceNull = ""
Const iDecimales = 5
Const iWait = 10
' Datentypen http://msdn.microsoft.com/en-us/library/windows/desktop/ms675318.aspx
Const adChar = 129
Const adUnsignedInt = 19
Const adUnsignedBigInt = 21
Const adBoolean = 11
Const adDouble = 5
' Datei öffnen http://msdn.microsoft.com/en-us/library/314cz14s.aspx
Const ForWriting = 2
arrFields = Array("Caption", "ProcessId", "ExecutablePath", _
"ParentProcessID", "KernelModeTime1", "UserModeTime1", "KernelModeTime2", _
"UserModeTime2", "Running", "ProcessorUsage")
dblSum = 0
' ADO Recordset http://msdn.microsoft.com/en-us/library/windows/desktop/ms681510.aspx
Set oADORec = CreateObject("ADODB.Recordset")
' Append http://msdn.microsoft.com/en-us/library/windows/desktop/ms681564.aspx
oADORec.Fields.Append "Caption", adChar , 1024
oADORec.Fields.Append "ProcessId", adUnsignedInt
oADORec.Fields.Append "ExecutablePath", adChar , 256
oADORec.Fields.Append "ParentProcessID", adUnsignedInt
oADORec.Fields.Append "KernelModeTime1", adUnsignedBigInt
oADORec.Fields.Append "UserModeTime1", adUnsignedBigInt
oADORec.Fields.Append "KernelModeTime2", adUnsignedBigInt
oADORec.Fields.Append "UserModeTime2", adUnsignedBigInt
oADORec.Fields.Append "Running", adBoolean
oADORec.Fields.Append "ProcessorUsage", adDouble
oADORec.Open
' Win32_Process Class http://msdn.microsoft.com/en-us/library/windows/desktop/aa394372.aspx
' 1. Run
Set oWMI = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" _
& sComputerName & "\root\cimv2")
Set colItems = oWMI.ExecQuery("Select * from Win32_Process")
For Each oItem In colItems
If IsNull(oItem.ExecutablePath) Then
sExePath = sReplaceNull
Else
sExePath = oItem.ExecutablePath
End If
arrValues = Array(oItem.Caption, oItem.ProcessId, sExePath, _
oItem.ParentProcessID, oItem.KernelModeTime, _
oItem.UserModeTime, 0, 0, False, 0)
oADORec.AddNew arrFields, arrValues
Next
Set oItem = Nothing
Set colItems = Nothing
WScript.Sleep iWait * 1000
' 2. Run
Set colItems = oWMI.ExecQuery("Select * from Win32_Process")
For Each oItem In colItems
oADORec.MoveFirst
oADORec.Find "ProcessID = #" & oItem.ProcessID & "#"
If Not oADORec.EOF Then
oADORec("KernelModeTime2") = oItem.KernelModeTime
oADORec("UserModeTime2") = oItem.UserModeTime
oADORec("Running") = True
oADORec.Update
End If
Next
Set oItem = Nothing
Set colItems = Nothing
Set oWMI = Nothing
oADORec.MoveFirst
While Not oADORec.EOF
If oADORec("Running") Then
dblSum = dblSum + CDbl(oADORec("KernelModeTime2")) + CDbl(oADORec("UserModeTime2")) _
- CDbl(oADORec("KernelModeTime1")) - CDbl(oADORec("UserModeTime1"))
Else
oADORec.Delete
End If
oADORec.Update
oADORec.MoveNext
Wend
' CPU-Nutzung als Double-Wert hinzufügen
oADORec.MoveFirst
While Not oADORec.EOF
oADORec("ProcessorUsage") = _
(CDbl(oADORec("KernelModeTime2")) + CDbl(oADORec("UserModeTime2")) _
- CDbl(oADORec("KernelModeTime1")) - CDbl(oADORec("UserModeTime1"))) / dblSum
oADORec.Update
oADORec.MoveNext
Wend
' Sort Property http://msdn.microsoft.com/en-us/library/windows/desktop/ms675783.aspx
' Prozesse mit der höchsten CPU-Nutzung nach oben sortieren
oADORec.Sort = "ProcessorUsage DESC"
' FileSystemObject http://msdn.microsoft.com/en-us/library/d6dw7aeh.aspx
' Schreiben der Daten in die CSV Datei
Set oFSO = CreateObject("Scripting.FileSystemObject")
Set oFile = oFSO.OpenTextFile(sCSVPath, ForWriting, True)
oFile.WriteLine "Caption" & sDelim & "ProcessId" & sDelim & "ExecutablePath" & _
sDelim & "ParentProcessID" & sDelim & "ProcessorUsage"
oADORec.MoveFirst
While Not oADORec.EOF
oFile.WriteLine _
oADORec("Caption") & sDelim & _
CStr(oADORec("ProcessId")) & sDelim & _
oADORec("ExecutablePath") & sDelim & _
CStr(oADORec("ParentProcessID")) & sDelim & _
CStr(Round(oADORec("ProcessorUsage") * 100, iDecimales)) & "%"
oADORec.MoveNext
Wend
oFile.Close
oADORec.Close
Set oADORec = Nothing
Set oFile = Nothing
Set oFSO = Nothing
Grüße
rubberman
Hallo @mycroftone, Hallo rubberman!
Das war eine sehr gute Idee und rubberman hat's ja inzwischen gerichtet
Der Vollständigkeit halber, habe ich mein Skript dann eben auch mal etwas angepasst:
wobei Du die Pausen bzw. Start-/Stopzeiten nach Belieben anpassen kannst.
Gruß Dieter
Das war eine sehr gute Idee und rubberman hat's ja inzwischen gerichtet
Der Vollständigkeit halber, habe ich mein Skript dann eben auch mal etwas angepasst:
Option Explicit
Const CsvPath = "E:\Ausgabe.csv"
Const strComputer = "."
Dim Fso, ListeB, ListeE, Key, Token, ValueK, ValueU, ValueT, Text
Dim objWMIService, colProcessesB, colProcessesE, colProcess
Set ListeB = CreateObject("Scripting.Dictionary") 'Assoziatives Array (Key, Wert) für Startwerte
Set ListeE = CreateObject("Scripting.Dictionary") 'Assoziatives Array (Key, Wert) für Stopwerte
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colProcessesB = objWMIService.ExecQuery("Select * from Win32_Process") 'Startwerte abfragen
WScript.Sleep 1000 'Pause in Millisekunden
Set colProcessesE = objWMIService.ExecQuery("Select * from Win32_Process") 'Stopwerte abfragen
For Each colProcess In colProcessesB 'Start-Prozesse in ListeB sammeln (Key=ProzessID)
With colProcess.Properties_
Token = Array(.Item("Caption").Value, _
.Item("ProcessId").Value, _
.Item("ExecutablePath").Value, _
.Item("ParentProcessID").Value, _
.Item("KernelModeTime").Value, _
.Item("UserModeTime").Value, _
0)
If IsNull(Token(2)) Then Token(2) = "" 'Null-Rückgabe für Path eliminieren
ListeB.Add "$" & .Item("ProcessId").Value, Join(Token, ";")
End With
Next
For Each colProcess In colProcessesE 'Stop-Prozesse (nur Zeiten) in ListeE sammeln
With colProcess.Properties_
Token = Array(.Item("KernelModeTime").Value, .Item("UserModeTime").Value)
ListeE.Add "$" & .Item("ProcessId").Value, Join(Token, ";")
End With
Next
ValueT = 0 'Summe Gesamtzeiten auf 0 setzen
For Each Key In ListeB.Keys 'Alle Prozesse auslesen
If ListeE.Exists(Key) Then 'Test ob Prozess bei Stop noch gelaufen ist
Token = Split(ListeB(Key), ";") 'Prozesswerte aus ListeB laden und Differenz Start/Ende übernehmen
ValueK = CDbl(Split(ListeE(Key), ";")(0)) - CDbl(Token(4)) 'KernelModeTime
ValueU = CDbl(Split(ListeE(Key), ";")(1)) - CDbl(Token(5)) 'UserModeTime
Token(4) = ValueK
Token(5) = ValueU
ValueT = CDbl(ValueT + ValueK + ValueU) 'Summe Gesamtzeiten
ListeB.Item(Key) = Join(Token, ";") 'Neue Prozesswerte wieder in Liste zurückschreiben
Else
ListeB.Remove Key 'Wenn Prozess inzwischen terminiert, dann aus Liste entfernen
End If
Next
'Spaltenüberschrift
Text = "Caption;ProcessId;ExecutablePath;ParentProcessID;KernelModeTime;UserModeTime;Prozent" & vbCrLf
For Each Key In ListeB.Keys 'Alle Prozesse auslesen
Token = Split(ListeB(Key), ";") 'Prozesswerte aus ListeB laden
'Prozentwert berechnen und zu den Prozesswerten hinzufügen
Token(6) = FormatNumber((CDbl(Token(4)) + CDbl(Token(5))) / ValueT * 100, 6) & "%"
Text = Text & Join(Token, ";") & vbCrLf 'Prozesswerte in einem Text-String sammeln
Next
Set Fso = CreateObject("Scripting.FileSystemObject")
'Csv-Datei schreiben
With Fso.CreateTextFile(CsvPath)
.Write Text
.Close
End With
Gruß Dieter