Top-Themen

AppleEntwicklungHardwareInternetLinuxMicrosoftMultimediaNetzwerkeOff TopicSicherheitSonstige SystemeVirtualisierungWeiterbildungZusammenarbeit

Aktuelle Themen

Administrator.de FeedbackApache ServerAppleAssemblerAudioAusbildungAuslandBackupBasicBatch & ShellBenchmarksBibliotheken & ToolkitsBlogsCloud-DiensteClusterCMSCPU, RAM, MainboardsCSSC und C++DatenbankenDatenschutzDebianDigitiales FernsehenDNSDrucker und ScannerDSL, VDSLE-BooksE-BusinessE-MailEntwicklungErkennung und -AbwehrExchange ServerFestplatten, SSD, RaidFirewallFlatratesGoogle AndroidGrafikGrafikkarten & MonitoreGroupwareHardwareHosting & HousingHTMLHumor (lol)Hyper-VIconsIDE & EditorenInformationsdiensteInstallationInstant MessagingInternetInternet DomäneniOSISDN & AnaloganschlüsseiTunesJavaJavaScriptKiXtartKVMLAN, WAN, WirelessLinuxLinux DesktopLinux NetzwerkLinux ToolsLinux UserverwaltungLizenzierungMac OS XMicrosoftMicrosoft OfficeMikroTik RouterOSMonitoringMultimediaMultimedia & ZubehörNetzwerkeNetzwerkgrundlagenNetzwerkmanagementNetzwerkprotokolleNotebook & ZubehörNovell NetwareOff TopicOpenOffice, LibreOfficeOutlook & MailPapierkorbPascal und DelphiPeripheriegerätePerlPHPPythonRechtliche FragenRedHat, CentOS, FedoraRouter & RoutingSambaSAN, NAS, DASSchriftartenSchulung & TrainingSEOServerServer-HardwareSicherheitSicherheits-ToolsSicherheitsgrundlagenSolarisSonstige SystemeSoziale NetzwerkeSpeicherkartenStudentenjobs & PraktikumSuche ProjektpartnerSuseSwitche und HubsTipps & TricksTK-Netze & GeräteUbuntuUMTS, EDGE & GPRSUtilitiesVB for ApplicationsVerschlüsselung & ZertifikateVideo & StreamingViren und TrojanerVirtualisierungVisual StudioVmwareVoice over IPWebbrowserWebentwicklungWeiterbildungWindows 7Windows 8Windows 10Windows InstallationWindows MobileWindows NetzwerkWindows ServerWindows SystemdateienWindows ToolsWindows UpdateWindows UserverwaltungWindows VistaWindows XPXenserverXMLZusammenarbeit
GELÖST

Speicherort per PID herausfinden

Frage Entwicklung Batch & Shell

Mitglied: Alme123

Alme123 (Level 1) - Jetzt verbinden

11.05.2013, aktualisiert 15.11.2013, 3150 Aufrufe, 26 Kommentare, 3 Danke

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]
Mitglied: rubberman
11.05.2013 um 22:14 Uhr
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
Bitte warten ..
Mitglied: Alme123
12.05.2013 um 07:14 Uhr
Hallo rubberman,

vielen Dank für deine Rückmeldung.

Dieser Prozess soll(te) mit Batch programmiert werden.
Wie WMI funktioniert, weiß ich leider nicht.

Grüße,

Alme123
Bitte warten ..
Mitglied: bastla
12.05.2013 um 09:23 Uhr
Hallo Alme123!

Dann etwa so:
for /f "delims=" %%i in ('"wmic process where ProcessId='%PID%' get ExecutablePath"') do set "ExePath=%%i"
Grüße
bastla
Bitte warten ..
Mitglied: Alme123
12.05.2013, aktualisiert um 09:55 Uhr
@bastla und @rubberman

Entschuldigung, das ich mich falsch ausgedrückt habe:

Es sind cmd Prozesse, von denen der BatchPfad ausgelesen werden soll.

@bastla, dein Script funktioniert; jedoch nicht für das obenstehende.

Alme123
Bitte warten ..
Mitglied: 76109
12.05.2013 um 10:59 Uhr
Hallo Alme123!

@bastla, dein Script funktioniert; jedoch nicht für das obenstehende
Dann verwende 'CommandLine' anstatt 'ExecutablePath'

Gruß Dieter
Bitte warten ..
Mitglied: bastla
12.05.2013 um 11:04 Uhr
Hallo Alme123!

Versuch es damit:
for /f "tokens=2*" %%i in ('"wmic process where ProcessId='%PID%' get CommandLine"') do set "ExePath=%%~j"
Grüße
bastla
Bitte warten ..
Mitglied: Alme123
12.05.2013 um 12:04 Uhr
@bastla

Dein Script funktioniert, aber es zeigt noch die Anführungszeichen und ein Leerzeichen an.
Ausgabe: "C:/batch.bat" "

Mit
01.
set "ExePath=%ExePath:~1%" 
02.
set "ExePath=%ExePath:~0,-5%"
könnte man es beheben.

Kann man es schon mit deinem Befehl ändern?

Alme123
Bitte warten ..
Mitglied: Alme123
12.05.2013 um 12:05 Uhr
@76109

nein, dies funktioniert nicht, siehe @bastla

Alme123
Bitte warten ..
Mitglied: rubberman
12.05.2013 um 12:53 Uhr
Hallo Alme123,

wenn die Batchdatei per Doppelklick ausgeführt wurden, dann vermutlich so:
01.
@echo off &setlocal 
02.
 
03.
set /a PID=2260 
04.
 
05.
call :getBatPath %PID% strBatPath 
06.
echo(%strBatPath% 
07.
pause 
08.
goto :eof 
09.
 
10.
:getBatPath iPID RefVar 
11.
  setlocal 
12.
  set /a iPID=%~1 
13.
  set "RefVar=" 
14.
  set "CmdLn=" 
15.
  for /f "tokens=1* delims==" %%i in ( 
16.
    'WMIC Process WHERE "ProcessId=%iPID%" GET CommandLine /value 2^>nul' 
17.
  ) do for /f "delims=" %%k in ("%%j") do ( 
18.
    set "CmdLn=%%k" 
19.
    setlocal EnableDelayedExpansion 
20.
      set "CmdLn=!CmdLn:cmd /c "=!" 
21.
      for %%l in (!CmdLn!) do ( 
22.
        if "!!"=="" endlocal 
23.
        if not defined RefVar if /i "%%~xl"==".bat" set "RefVar=%%~l" 
24.
25.
26.
  endlocal &set "%~2=%RefVar%" 
27.
goto :eof
Grüße
rubberman
Bitte warten ..
Mitglied: bastla
12.05.2013 um 14:38 Uhr
... obwohl auch
01.
for /f "tokens=2*" %%i in ('"wmic process where ProcessId='%PID%' get CommandLine"') do set "ExePath=%%~j" 
02.
for %%i in (%ExePath:"=%) do set "ExePath=%%i"
schon genügen sollte ...

Grüße
bastla
Bitte warten ..
Mitglied: rubberman
12.05.2013, aktualisiert um 15:44 Uhr
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
Bitte warten ..
Mitglied: bastla
12.05.2013 um 18:23 Uhr
Hallo rubberman!

Hast recht - die Zeile 2 wäre so besser:
for /f "delims=" %%i in ("%ExePath:"=%") do set "ExePath=%%i"
Grüße
bastla
Bitte warten ..
Mitglied: Alme123
12.05.2013 um 18:39 Uhr
Hallo,

Danke an @rubberman und @bastla .

Diese Frage ist gelöst.

Wen es interessiert: Hier ging es weiter mit der gleichen Frage (etwas anders, aber vollständig)

Alme123

[Theard closed]
Bitte warten ..
Mitglied: rubberman
12.05.2013 um 18:44 Uhr
Hallo bastla,

nee, das sieht nur gut aus, wenn man sich die Leerzeichen am Ende auch noch wegzaubert FOR /F ist dafür nicht so toll geeignet.

Grüße
rubberman
Bitte warten ..
Mitglied: bastla
12.05.2013, aktualisiert um 18:58 Uhr
Hallo rubberman!

Yep, ist richtig (das kommt vom Posten zwischen Tür und Angel)

Ich hätte gleich VBS nehmen sollen ...

Grüße
bastla
Bitte warten ..
Mitglied: rubberman
12.05.2013 um 20:56 Uhr
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:
  1. Parent PID des VBScripts ermitteln.
  2. PID und Kommandozeile für jeden cmd.exe Prozess (außer dem mit der Parent PID) ermitteln.
  3. 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
Bitte warten ..
Mitglied: bastla
12.05.2013 um 21:13 Uhr
Hallo rubberman!
Hättest du es anders gelöst?
Ich hätte vermutlich, spät, aber doch, eher mal die Frage nach dem Sinn der ganzen Aktion gestellt ...

Grüße
bastla
Bitte warten ..
Mitglied: 76109
13.05.2013, aktualisiert um 22:00 Uhr
Hallo bastla, rubberman!

Per VBS könnte man es doch vom Prinzip her, in etwa so machen:
01.
Const sSqlExec = "Select * from Win32_Process Where Name='cmd.exe'" 
02.
 
03.
Dim oWMIService, oProcess, sCaller, sPath, sResult 
04.
 
05.
With WScript.Arguments 
06.
    If .Count <> 1 Then 
07.
        WScript.Echo "Aufruf ohne Argument!":  WScript.Quit 1 
08.
    Else 
09.
        sCaller = .Item(0) 
10.
    End If 
11.
End With 
12.
 
13.
Set oWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2") 
14.
     
15.
For Each oProcess In oWMIService.ExecQuery(sSqlExec) 
16.
    If LCase(Left(oProcess.CommandLine, 3)) = "cmd" Then 
17.
        sPath = Split(oProcess.CommandLine, Chr(34))(2) 
18.
        If sPath <> sCaller Then sResult = sResult & sPath & vbCrLf 
19.
    End If 
20.
Next 
21.
WScript.Echo sResult
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.
01.
cscript //nologo xy.vbs "%~f0" 
02.
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]
Bitte warten ..
Mitglied: rubberman
13.05.2013 um 19:37 Uhr
Hallo Dieter,

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
Bitte warten ..
Mitglied: 76109
13.05.2013 um 20:34 Uhr
Hallo rubberman!

Danke für den Tipp mit "%~f0". Hab's oben geändert.

... ich habe da wieder mal viel zu kompliziert gedacht.
Das dachte ich auch

Gruß Dieter
Bitte warten ..
Mitglied: Alme123
15.11.2013, aktualisiert um 17:30 Uhr
An alle,

ich muss den Theard wieder etwas aufreißen, weil bei mir eure Scripte nicht mehr funktionieren.
Ich habe Windows neuinstalliert und danach gab es nur noch Chaos.
Ich habe alle Batchscripte probiert, aber keins bringt das gewünschte Ergebnis.

Ich möchte einfach meine Lösung schreiben, euch fragen ob dieses Script funktioniert, ob bei euch die alten Scripte (Wie bastla's erstes) noch funktionieren und
fragen, ob es auch ggf. eleganter geht:

01.
@echo off 
02.
set "ExePath=" 
03.
set "PID=" 
04.
for /f "tokens=*" %%i in ('%windir%\system32\tasklist.exe ^| %windir%\system32\findstr.exe /I "datei.exe"') do set "PID=%%i" 
05.
echo %PID% | %windir%\system32\findstr.exe /I "Console" >nul 
06.
if errorlevel 1 start /min "" "%ProgramFiles%\VirusDumper\datei.exe" && goto :Eof 
07.
set "PID=%PID:~0,34%" 
08.
set "PID=%PID:~-4%" 
09.
for /f "delims=" %%i in ('"wmic process where ProcessId='%PID%' get ExecutablePath"') do for /f "delims=" %%a in ('"echo %%i | findstr /I "%homedrive%""') do set "ExePath=%%a" 
10.
set "ExePath=%ExePath:~0,-3%" 
11.
echo Speicherort: %ExePath%
Der Code prüft, ob die "datei.exe" geöffnet ist. Wenn nicht, wird sie gestartet und das Script beendet. Wenn doch wird die PID geformt.
Darauf wird der Speicherort gesucht und extrahiert.
Nachteil: Wenn der Speicherort der Datei völlig unklar ist, kann man nur %homedrive% benutzen, was bei anderen Laufwerken zu Fehlern führt.
Das Problem bei euren Scripts (hier bastla's erstes) trat bei der Erhaltung des Speicherorts ein: Es kam statt dem Speicherort folgendes raus:
01.
ExecutablePath 
02.
C:\Users\Benutzer\Desktop\datei.exe 
03.
 
Diese Ausgabe bestand aus 3 Zeilen, die letzte war eine Leerzeile oder eine Zeile nur mit Leerstellen.


Alme123
Bitte warten ..
Mitglied: rubberman
LÖSUNG 15.11.2013, aktualisiert 14.12.2013
Hallo Alme123.

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
01.
for /f "delims=" %%i in ('"wmic process where ProcessId='%PID%' get ExecutablePath /value"') do ( 
02.
  for /f "tokens=1* delims==" %%a in ("%%i") do set "ExePath=%%b" 
03.
)
Grüße
rubberman

EDIT Zeile 2 korrigiert
Bitte warten ..
Mitglied: Alme123
15.11.2013 um 19:59 Uhr
@rubberman

dies funktioniert prächtig! Funktionieren die alten Scripts noch bei dir und weißt du vielleicht, wieso sie bei mir nicht funktionieren?

Alme123
Bitte warten ..
Mitglied: rubberman
15.11.2013 um 20:53 Uhr
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
Bitte warten ..
Mitglied: Alme123
15.11.2013, aktualisiert 16.11.2013
@rubberman

Ich nutze die Windows 7 64 Bit Version nicht die 32iger (ich denke doch x86 ist 32 Bit, ggf. aufklären)
Kodierung der Dateien sind bei mir immer ANSI und cmd hat keine speziellen Voreinstellungen.
Was mir aufgefallen ist: Wenn die PID 3 stellig ist, steht am Anfang der PID ein Leerzeichen.
Der Vorgang schlägt dann fehl.

Alme123
Bitte warten ..
Mitglied: rubberman
15.11.2013, aktualisiert um 22:39 Uhr
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.
01.
>test.txt WMIC OS Get LocalDateTime
Hexdump von test.txt
FFFE4C006F00630061006C004400610074006500540069006D006500200020002000200020002000200020002000200020002000200020000D000A00320030003100330031003100310035003200310034003300340035002E003400340035003000300030002B00300036003000200020000D000A00
Wenn du so etwas in einer FOR /F Schleife verwurstest, wird's komisch.
01.
>test.txt (for /f "delims=" %%i in ('WMIC OS Get LocalDateTime') do echo(%%i)
Hexdump von test.txt
4C6F63616C4461746554696D6520202020202020202020202020200D0D0A32303133313131353231353330392E3939353030302B30363020200D0D0A0D0D0A
Ein normaler Zeilenumbruch unter Windows wäre 0D0A. So etwas wie 0D0D0A macht eine normale Verarbeitung unmöglich. Darum die verschachtelte Schleife.
01.
>test.txt (for /f "delims=" %%i in ('WMIC OS Get LocalDateTime') do for /f "delims=" %%j in ("%%i") do echo(%%j)
Hexdump von test.txt
4C6F63616C4461746554696D6520202020202020202020202020200D0A32303133313131353232303030362E3935323030302B30363020200D0A
Ich hoffe nun ist es klar geworden.

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"
oder noch einfacher
set /a PID=%PID:~29,4%

Grüße
rubberman
Bitte warten ..
Neuester Wissensbeitrag
Windows 10

Powershell 5 BSOD

(3)

Tipp von agowa338 zum Thema Windows 10 ...

Ähnliche Inhalte
Server-Hardware
gelöst Netzteil Watt Power herausfinden (6)

Frage von M.Marz zum Thema Server-Hardware ...

Netzwerke
Clientname anhand MAC Adresse herausfinden (13)

Frage von VerruecktesPferd zum Thema Netzwerke ...

Windows 10
gelöst Win10 Originalen Lizenzkey herausfinden nach diversen Upgrades (7)

Frage von cirrus7 zum Thema Windows 10 ...

Heiß diskutierte Inhalte
LAN, WAN, Wireless
gelöst Server erkennt Client nicht wenn er ausserhalb des DHCP Pools liegt (28)

Frage von Mar-west zum Thema LAN, WAN, Wireless ...

Outlook & Mail
Outlook 2010 findet ost datei nicht (18)

Frage von Floh21 zum Thema Outlook & Mail ...

Windows Server
Server 2008R2 startet nicht mehr (Bad Patch 0xa) (18)

Frage von Haures zum Thema Windows Server ...