Speicherort per PID herausfinden
ich habe folgendes Problem:
ich habe mehrere cmd Prozesse, von denen ich die PID weiß.
Kann man per PID (oder anderer Prozess Info aus tasklist oder pslist) den Speicherort mit Batch-Dateinamen herausfinden?
Dies soll möglichst auf Batch oder VbScript beziehen.
Vielen Dank im Vorraus,
Alme123
[Edit 12.05.13: Frage verbessert]
[Edit 2; 15.11.13: Fehler nach Neuinstallation, siehe Theard #comment-839423]
ich habe mehrere cmd Prozesse, von denen ich die PID weiß.
Kann man per PID (oder anderer Prozess Info aus tasklist oder pslist) den Speicherort mit Batch-Dateinamen herausfinden?
Dies soll möglichst auf Batch oder VbScript beziehen.
Vielen Dank im Vorraus,
Alme123
[Edit 12.05.13: Frage verbessert]
[Edit 2; 15.11.13: Fehler nach Neuinstallation, siehe Theard #comment-839423]
Please also mark the comments that contributed to the solution of the article
Content-ID: 206325
Url: https://administrator.de/contentid/206325
Printed on: October 9, 2024 at 17:10 o'clock
26 Comments
Latest comment
Hallo Alme123.
Ich gehe davon aus dass du auf den Pfad des entsprechenden Programms hinaus willst.
Funktioniert mittels WMI. Die Win32_Process Klasse hat eine CommandLine Eigenschaft, aus der du das extrahieren kannst. Sowohl per VBScript als auch per Batch. Wenn du dich für eines von beiden entschieden hast, bin ich auch gerne weiter behilflich.
Grüße
rubberman
Ich gehe davon aus dass du auf den Pfad des entsprechenden Programms hinaus willst.
Funktioniert mittels WMI. Die Win32_Process Klasse hat eine CommandLine Eigenschaft, aus der du das extrahieren kannst. Sowohl per VBScript als auch per Batch. Wenn du dich für eines von beiden entschieden hast, bin ich auch gerne weiter behilflich.
Grüße
rubberman
Hallo Alme123!
Gruß Dieter
@bastla, dein Script funktioniert; jedoch nicht für das obenstehende
Dann verwende 'CommandLine' anstatt 'ExecutablePath'Gruß Dieter
Hallo Alme123,
wenn die Batchdatei per Doppelklick ausgeführt wurden, dann vermutlich so:
Grüße
rubberman
wenn die Batchdatei per Doppelklick ausgeführt wurden, dann vermutlich so:
@echo off &setlocal
set /a PID=2260
call :getBatPath %PID% strBatPath
echo(%strBatPath%
pause
goto :eof
:getBatPath iPID RefVar
setlocal
set /a iPID=%~1
set "RefVar="
set "CmdLn="
for /f "tokens=1* delims==" %%i in (
'WMIC Process WHERE "ProcessId=%iPID%" GET CommandLine /value 2^>nul'
) do for /f "delims=" %%k in ("%%j") do (
set "CmdLn=%%k"
setlocal EnableDelayedExpansion
set "CmdLn=!CmdLn:cmd /c "=!"
for %%l in (!CmdLn!) do (
if "!!"=="" endlocal
if not defined RefVar if /i "%%~xl"==".bat" set "RefVar=%%~l"
)
)
endlocal &set "%~2=%RefVar%"
goto :eof
Grüße
rubberman
Hallo bastla,
nur dann, wenn keine Leerzeichen im Pfad sind, oder habe ich einen Denkfehler?
Grüße
rubberman
PS: Ich glaube dort sind wir schon einen Meter weiter gekommen
nur dann, wenn keine Leerzeichen im Pfad sind, oder habe ich einen Denkfehler?
Grüße
rubberman
PS: Ich glaube dort sind wir schon einen Meter weiter gekommen
Hallo bastla,
ist doch kein Beinbruch
Ich bin aber davon überzeugt, dass es mit VBS auch nicht einfacher würde. Die Anforderungen aus dem oben verlinkten Beitrag mal mit einbezogen ergibt das:
Das VBScript würde aus einem Batch aufgerufen werden. Dabei soll für alle cmd.exe Prozesse die PID und der Pfad der dazugehörigen Batchdatei ermittelt werden. Der aufrufende Batchprozess soll dabei ausgeschlossen werden.
Bedeutet:
Punkt 1 ist schon eine kleine Herausforderung, aber machbar.
Bei Punkt 3 fällt mir Split() mit
Grüße
rubberman
ist doch kein Beinbruch
Ich bin aber davon überzeugt, dass es mit VBS auch nicht einfacher würde. Die Anforderungen aus dem oben verlinkten Beitrag mal mit einbezogen ergibt das:
Das VBScript würde aus einem Batch aufgerufen werden. Dabei soll für alle cmd.exe Prozesse die PID und der Pfad der dazugehörigen Batchdatei ermittelt werden. Der aufrufende Batchprozess soll dabei ausgeschlossen werden.
Bedeutet:
- Parent PID des VBScripts ermitteln.
- PID und Kommandozeile für jeden cmd.exe Prozess (außer dem mit der Parent PID) ermitteln.
- Pfade der Batchdateien aus den Kommandozeilen extrahieren.
Punkt 1 ist schon eine kleine Herausforderung, aber machbar.
Bei Punkt 3 fällt mir Split() mit
"
als Trenner ein. Das wäre aber auch eine Alternative für FOR /F in Batch (auch wenn die Syntax dafür etwas gewohnheitsbedürftig ist). Hättest du es anders gelöst?Grüße
rubberman
Hallo bastla, rubberman!
Per VBS könnte man es doch vom Prinzip her, in etwa so machen:
Wobei ich die PID jetzt mal außer acht gelassen habe...
Es sollen ja, wenn ich das richtig verstanden habe nur die CMD-Scripte ermittelt werden, also ist das VB-Script ja eigentlich uninteressant.
Wenn das VB-Script über Batch aufgerufen werden soll, dann wird die Variable %0 als Argument an das VB-Script übergeben, um die aufrufende Batch ausschließen zu können.
In der CmdLine beginnen alle Scriptaufrufe mit "cmd" Left(3). Somit befindet sich der Pfad im Split-Token (2) und mit Right(3) kann man bei Bedarf auch noch auf die Extension "bat" testen ...
Gruß Dieter
[edit] Script-Aufruf auf Anraten von rubberman entsprechend geändert [/edit]
Per VBS könnte man es doch vom Prinzip her, in etwa so machen:
Const sSqlExec = "Select * from Win32_Process Where Name='cmd.exe'"
Dim oWMIService, oProcess, sCaller, sPath, sResult
With WScript.Arguments
If .Count <> 1 Then
WScript.Echo "Aufruf ohne Argument!": WScript.Quit 1
Else
sCaller = .Item(0)
End If
End With
Set oWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
For Each oProcess In oWMIService.ExecQuery(sSqlExec)
If LCase(Left(oProcess.CommandLine, 3)) = "cmd" Then
sPath = Split(oProcess.CommandLine, Chr(34))(2)
If sPath <> sCaller Then sResult = sResult & sPath & vbCrLf
End If
Next
WScript.Echo sResult
Es sollen ja, wenn ich das richtig verstanden habe nur die CMD-Scripte ermittelt werden, also ist das VB-Script ja eigentlich uninteressant.
Wenn das VB-Script über Batch aufgerufen werden soll, dann wird die Variable %0 als Argument an das VB-Script übergeben, um die aufrufende Batch ausschließen zu können.
cscript //nologo xy.vbs "%~f0"
Pause
In der CmdLine beginnen alle Scriptaufrufe mit "cmd" Left(3). Somit befindet sich der Pfad im Split-Token (2) und mit Right(3) kann man bei Bedarf auch noch auf die Extension "bat" testen ...
Gruß Dieter
[edit] Script-Aufruf auf Anraten von rubberman entsprechend geändert [/edit]
Hallo Dieter,
gute Idee. Nur aus Sicherheitsgründen (je nach dem, wie die Batchdatei selbst aufgerufen wurde), würde ich das
Die PID noch mit zu verwursten ist dann Makulatur
Grüße
rubberman
gute Idee. Nur aus Sicherheitsgründen (je nach dem, wie die Batchdatei selbst aufgerufen wurde), würde ich das
%0
zu "%~f0"
machen. Ansonsten ist das ziemlich clever gelöst, ich habe da wieder mal viel zu kompliziert gedacht.Die PID noch mit zu verwursten ist dann Makulatur
Grüße
rubberman
Hallo rubberman!
Danke für den Tipp mit "%~f0". Hab's oben geändert.
Gruß Dieter
Danke für den Tipp mit "%~f0". Hab's oben geändert.
... ich habe da wieder mal viel zu kompliziert gedacht.
Das dachte ich auchGruß Dieter
Hallo Alme123.
Ungetestet
Grüße
rubberman
EDIT Zeile 2 korrigiert
Wenn der Speicherort der Datei völlig unklar ist
Warum sollte er das sein? Wenn der Prozess gestartet wurde, ist auch klar wo das Executable liegt.Ungetestet
for /f "delims=" %%i in ('"wmic process where ProcessId='%PID%' get ExecutablePath /value"') do (
for /f "tokens=1* delims==" %%a in ("%%i") do set "ExePath=%%b"
)
Grüße
rubberman
EDIT Zeile 2 korrigiert
Hallo Alme123,
meine Scripts funktionieren nach wie vor. Habe ich auf der selben Windowsversion geschrieben (Win7 x86).
Ich kann nur mutmaßen: Je nach WMIC Version kommt die Ausgabe in einem verstümmelten Unicode Zeichensatz mit merkwürdigen Zeilenumbrüchen. Diese kann man mit einer verschachtelten FOR /F Schleife "normalisieren".
Grüße
rubberman
meine Scripts funktionieren nach wie vor. Habe ich auf der selben Windowsversion geschrieben (Win7 x86).
Ich kann nur mutmaßen: Je nach WMIC Version kommt die Ausgabe in einem verstümmelten Unicode Zeichensatz mit merkwürdigen Zeilenumbrüchen. Diese kann man mit einer verschachtelten FOR /F Schleife "normalisieren".
Grüße
rubberman
Hallo Alme123,
du hast mich missverstanden. Mir ging es um die Dateiversion von wmic.exe und deren Ausgabeformat. Bei mir ist es UTF-16 LE.
Hexdump von test.txt
Wenn du so etwas in einer FOR /F Schleife verwurstest, wird's komisch.
Hexdump von test.txt
Ein normaler Zeilenumbruch unter Windows wäre 0D0A. So etwas wie 0D0D0A macht eine normale Verarbeitung unmöglich. Darum die verschachtelte Schleife.
Hexdump von test.txt
Ich hoffe nun ist es klar geworden.
Alternativ (statt deinen Zeilen 10 bis 14)
oder noch einfacher
Grüße
rubberman
du hast mich missverstanden. Mir ging es um die Dateiversion von wmic.exe und deren Ausgabeformat. Bei mir ist es UTF-16 LE.
>test.txt WMIC OS Get LocalDateTime
FFFE4C006F00630061006C004400610074006500540069006D006500200020002000200020002000200020002000200020002000200020000D000A00320030003100330031003100310035003200310034003300340035002E003400340035003000300030002B00300036003000200020000D000A00
Wenn du so etwas in einer FOR /F Schleife verwurstest, wird's komisch.
>test.txt (for /f "delims=" %%i in ('WMIC OS Get LocalDateTime') do echo(%%i)
4C6F63616C4461746554696D6520202020202020202020202020200D0D0A32303133313131353231353330392E3939353030302B30363020200D0D0A0D0D0A
>test.txt (for /f "delims=" %%i in ('WMIC OS Get LocalDateTime') do for /f "delims=" %%j in ("%%i") do echo(%%j)
4C6F63616C4461746554696D6520202020202020202020202020200D0A32303133313131353232303030362E3935323030302B30363020200D0A
if "%tmpPID%"==" " set "PID=%PID:~1%"
Hmm, und was machst du wenn die PID mal nur 2-stellig ist? Vielleicht solltest du besser mit dem CSV Format bei TASKLIST arbeiten.Alternativ (statt deinen Zeilen 10 bis 14)
for /f "tokens=*" %%i in ("%PID:~29,4%") do set "PID=%%i"
set /a PID=%PID:~29,4%
Grüße
rubberman