evinben
Goto Top

Abbildpfadname eines Prozesses abfragen. Prozess abhängig von seinem Abbildpfadnamen (Ausführungspfad, ExecutablePath) neustarten

Hallo,

back-to-topwie kann der Abbildpfadname eines Prozesses abgefragt werden?


So wie es aussieht bin ich wohl der erste mit so einer Frage hier, sodass es mich sehr wundert, dass es "so selten" vorkommt, wie es zu vermuten wäre.

Gruß
evinben


Kurz zu dem Vorhaben:
Einige Prozesse müssen öfters beendet und neugestartet werden. Da jedoch deren Pfade sich ändern, müssen die Pfade zuerst abgefragt und in Variable gesetzt werden und erst dann die Prozesse beendet und neu gestartet werden.
Daher wird eine Lösung zum Abfragen des Abbildpfadnamens eines Prozesses benötigt.
Wenn es per Batch umständlich realisierbar ist, dann eventuell per VBS.
Wobei Batch wäre jedenfalls zu bevorzugen, da der Hauptcode in Batch ist

Content-Key: 204390

Url: https://administrator.de/contentid/204390

Ausgedruckt am: 29.03.2024 um 08:03 Uhr

Mitglied: AndreasHoster
AndreasHoster 04.04.2013 um 10:04:27 Uhr
Goto Top
Wenns auch ein VBS Skript sein darf:
On Error Resume Next

Const wbemFlagReturnImmediately = &h10
Const wbemFlagForwardOnly = &h20

   Set objWMIService = GetObject("winmgmts:\\.\root\CIMV2")  
   Set colItems = objWMIService.ExecQuery("SELECT * FROM Win32_Process where Name='notepad.exe'", "WQL", _  
                                          wbemFlagReturnImmediately + wbemFlagForwardOnly)

   For Each objItem In colItems
      WScript.Echo "CommandLine: " & objItem.CommandLine  
      WScript.Echo "ExecutablePath: " & objItem.ExecutablePath  
      WScript.Echo "Name: " & objItem.Name  
   Next
Beispielausgabe:
CommandLine: "notepad.exe" C:\boot.ini
ExecutablePath: C:\WINDOWS\system32\notepad.exe
Name: notepad.exe

Wenn man Commandline und Name nicht braucht, kann mans auch weglassen.
Wenn man in Zeile 7 where Name='notepad.exe' weglässt, dann listet das Skript alle auf.
Mitglied: evinben
evinben 04.04.2013 um 12:43:27 Uhr
Goto Top
Hallo @AndreasHoster

deine Lösung hat mich zu einer Idee gebracht - per Batch via WMIC:

for %%d in (
	notepad.exe
	cmd.exe
	) do for /f "tokens=*" %%e in ('wmic process get ExecutablePath^|findstr /i /c:"%%d"') do (  
		rem Abbildpfadname anzeigen:
		echo "%%e"  
		rem taskkill /T /F /IM %%d
		rem start "" "%%e"  
		)

Leider aus mir unbekannten Gründen gibt "%%e" in der 6. und 8. Zeile nicht den Pfad in Anführungszeichen auf einer Zeile aus. Daher funktioniert momentan der Code nicht.
Beim Aktivieren der 8. Zeile, lautet die Fehlermeldung wie folgt 1:1 (Zeilenvorschub beachten):

C:\Program Files\Notepad.exe
" konnte nicht gefunden werden. Stellen Sie sicher, dass Sie den Namen richtig eingegeben
haben und wiederhohlen Sie den Vorgang.


Anscheinend ist da etwas mit WMIC besonders zu beachten, falls es kein Bus sein sollte. Nun muss der Zeilenvorschub entfernt werden, damit das Anführungszeichen auf die gleiche Zeile kommt.

Gruß
evinben
Mitglied: DerWoWusste
DerWoWusste 04.04.2013 um 12:59:28 Uhr
Goto Top
Hi.

Wie wär's mit einem Powershell-Einzeiler?
get-process powershell |fw -property path
liefert beispielsweise
C:\WINDOWS\system32\WindowsPowerShell\v1.0\powershell.exe
als Ausgabe.
Mitglied: AndreasHoster
AndreasHoster 04.04.2013 um 13:29:50 Uhr
Goto Top
Ich kenne mich jetzt mit WMIC nicht sonderlich gut aus, ich habe meine meisten Sachen immer gleich komplett in VBS geskriptet, da Batch doch manche Beschränkung hat.
Aber die Idee von @DerWoWusste mit Powershell ist gut.
Mitglied: evinben
evinben 04.04.2013 aktualisiert um 13:43:44 Uhr
Goto Top
Hallo @DerWoWusste und @AndreasHoster,

wenn ich die Zeit neue Skript-Sprachen zu studieren hätte, z. B. wie in PowerShell FOR-Schleifen verwendet werden (da gibt es nicht mal Pause, sondern Start-Sleep -s 10), hätte ich es gerne umgesetzt.
Gerade habe ich mich gemütlich ein bisschen in Batch eingearbeitet...
Jedoch mit eurer Hilfe immer gerne bin ich bereit zu lernen.

Gruß
evinben
Mitglied: Endoro
Endoro 04.04.2013 um 14:12:24 Uhr
Goto Top
Hallo evinben,

du könntest folgendes mal versuchen (ungetestet):

for %%d in (
	notepad.exe
	cmd.exe
	) do for /f "tokens=*" %%e in ('wmic process get ExecutablePath^|findstr /i /c:"%%d"') do (  
	  for /f "delims=" %%f in ("%%~e") do (  
		rem Abbildpfadname anzeigen:
		echo "%%~f"  
		rem taskkill /T /F /IM %%d
		rem start "" "%%~f"  
		)
	)

Gruss,
Mitglied: evinben
evinben 04.04.2013 aktualisiert um 15:30:17 Uhr
Goto Top
Hallo @Endoro,

mit deiner Lösung wird drei Mal der gleiche Pfad angezeigt (d. h. in der 9. Zeile drei Mal derselbe Prozess von cmd.exe gestartet), anstatt zwei verschiedene.

Gruß
Mitglied: Endoro
Endoro 04.04.2013 um 18:21:08 Uhr
Goto Top
Hi,

was wird denn ausgegeben?
Poste das doch mal.

Gruss!
Mitglied: evinben
evinben 04.04.2013 um 21:01:13 Uhr
Goto Top
Hallo @Endoro,

also die Ausgabe scheitert schon bei der folgenden Zeile:
for %%d in (Apoint.exe ApMsgFwd.exe ApntEx.exe) do for /f "tokens=*" %%e in ('wmic process get ExecutablePath ^|findstr /i /c:"%%d"') do echo "%%e"  

Übernimm einfach den Code 1:1 und führe dieses von einer Batch-Datei aus, dann wirst du sehen, dass alle mögliche Prozesse abgearbeitet werden, jedoch nicht ApMsgFwd.exe

Direkt von cmd geht es mit der folgenden Zeile aber:
for %d in (Apoint.exe ApMsgFwd.exe ApntEx.exe) do for /f "tokens=*" %e in ('wmic process get ExecutablePath ^|findstr /i /c:"%d"') do echo "%e"  

sehr merkwürdig
Gruß
Mitglied: evinben
evinben 11.01.2014 aktualisiert um 14:53:25 Uhr
Goto Top
Hallo,

bei dem Ausführen des ganz unteren Codes, erhalte ich in der Eingabeaufforderung folgende Zeilen 1:1

Folgender Prozess wird beendet: C:\windows\Explorer.EXE
"a  "C:\windows\Explorer.EXE  

"b "C:\windows\Explorer.EXE  

"c "C:\windows\Explorer.EXE  
Drücken Sie eine beliebige Taste . . .

Wenn wir die Ausgabe des Variablenwertes in der 3. Zeile genau betrachten, stellen wir fest, dass am Anfang der Zeile ungewollt ein Anführungszeichen eingefügt wird und das allererste Zeichen aus dem Variablenwert (1) hier nicht ausgegeben wird bzw. ganz verloren geht. Außerdem wird am Ende der Zeile ein Anführungszeichen nicht ausgegeben.

In der Datei tmp.txt sieht jedoch so aus:
C:\windows\Explorer.EXE                                                

"C:\windows\Explorer.EXE                                                  
"  

Nach mehreren Versuchen habe ich leider den Fehler nicht beseitigen können.
Hättet ihr eine Lösung?


Hier ist der besagte Code

@echo off
setlocal enabledelayedexpansion
@prompt -$G
chcp 1252 >nul
PushD %~dp0
echo.

:Options
:~~~~~~~~~~~~~~~~


:~~~~~~~~~~~~~~~~
:/End options



:CODE
:~~~~~~~~~~~~~~~~

:Mit WMIC wird der Abbildpfadname eines Prozesses abgefragt - erfordert Administrator-Rechte!

for %%d in (
	explorer.exe
	iexplorer.exe
	) do for /f "tokens=*" %%e in ('wmic process get ExecutablePath^|findstr /i /c:"%%d"') do (  
			rem Abbildpfadname anzeigen:
			echo Folgender Prozess wird beendet: %%~e
rem NACHFOLGENDER ABSCHNITT IST NUR VORÜBERGEHEND FÜR DEN TEST ZU VERSTEHEN
rem ##########################################################################
echo 1a  "%%e"  
echo.
set "var=%%e"  
echo 2b "!var!"  
echo.
set "var=!var: =!"  
echo 3c "!var!"  

type nul>tmp.txt
echo %%e>tmp.txt
echo "%%e">>tmp.txt  
pause & rem ##################################################################
			taskkill /T /F /IM %%d
			start "" "%%~e" &&echo Prozess "%%~e" wurde gestartet  
			echo.
		)

:Für direkten Test in der Eingabeaufforderung
:for /f "tokens=*" %e in ('wmic process get ExecutablePath^|findstr /i /c:"explorer.exe"') do echo %e  
:for /f "tokens=*" %e in ('wmic process get ExecutablePath^|findstr /i /c:"explorer.exe"') do for /f "tokens=* delims= " %f in ("%~e") do echo %f  

:timeout /t 3 >nul
pause >nul
Mitglied: DerWoWusste
DerWoWusste 11.01.2014 aktualisiert um 20:34:20 Uhr
Goto Top
Neun Monate später wieder reindenken macht mir wenig Spaß, sorry.
Mitglied: Endoro
Endoro 11.01.2014 aktualisiert um 20:21:34 Uhr
Goto Top
Hey, das ist das wmic Schätzchen mit den trailing carriage returns:
for /f "skip=1delims=" %a in ('wmic process where "name='explorer.exe' OR name='iexplore.exe'" get ExecutablePath') do @for /f "delims=" %b in ("%~a") do @echo %~b  
Läuft hier so in der Shell.

Gruss.
Mitglied: evinben
evinben 12.01.2014 aktualisiert um 13:16:51 Uhr
Goto Top
Hallo Endoro,

das Problem ist nicht das Neustarten der Prozesse (dank AndreasHoster@ mit dem Hinweis auf wmic und anschließend dir, habe ich es vor einem Jahr bereits erledigt), sondern:

1. die nachfolgenden Leerzeichen in der Variable (sobald deine aller letzte Variable (%~b) in Anführungszeichen gesetzt wird, werden diese ersichtlich). Das Problem habe ich heute soweit beheben können.
2. Wenn ein Prozess nicht gefunden worden ist, dann meldet wmic "Keine Instanzen verfügbar". Und genau an der Stelle muss ein echo rein, mit der Meldung, dass der abgefragte Prozess gar nicht gestartet ist.

Ich poste den Code erneut:

@echo off
@prompt -$G
chcp 1252 >nul
PushD %~dp0
echo.

:Mit WMIC den Abbildpfadname eines Prozesses abfragen

for %%d in (
	explorer.exe
	explorer1.exe
	explorer2.exe
	usw...exe
	) do (
		setlocal enabledelayedexpansion
		for /f "tokens=*" %%e in ('wmic process where "name='%%d'" get ExecutablePath^|findstr /i /c:"%%d"') do if not defined %%e echo Der Prozess %%e konnte nicht gefunden werden & (  
			for /f "delims=" %%f in ("%%~e") do (  
				rem Abbildpfadname anzegen:
				set ExecPath=%%f
				call :loop
				echo Folgender Prozess wird beendet: "!ExecPath!"  
				taskkill /T /F /IM %%d
				start "" "!ExecPath!" &&echo Folgender Prozess ist neugestartet worden: "!ExecPath!"  
				echo.
				)
		endlocal
			)
		)

goto :next
rem Leerzeichen am Ende einer Variable entfernen
:loop
if "%ExecPath:~-1%"==" " set "ExecPath=%ExecPath:~0,-1%" & goto :loop  
goto :eof
:next

:timeout /t 3 >nul
pause >nul

Gruß
evinben
Mitglied: Endoro
Endoro 12.01.2014 um 14:04:26 Uhr
Goto Top
Hey,

defined kann bei Forschleifenparametern nicht verwendet werden. Richtig ist:
if "%%~a"==""  

Die Leerzeichen können so entfernt werden:
for /f "tokens=1*delims==" %a in ('wmic process where "name='explorer.exe' OR name='iexplore.exe'" get ExecutablePath /value') do @for /f "delims=" %c in ("%~b") do @echo "%~c"  

Gruss.
Mitglied: evinben
evinben 12.01.2014, aktualisiert am 14.01.2014 um 09:47:51 Uhr
Goto Top
perfekte Umsetzung!
Vielen Dank für diesen Lösungsvorschlag - dies habe ich gleich so umgesetzt.
Was bewirkt genau das zweie "=" Zeichen in delims, außer Wunder face-smile?
Es geht ja um "carriage return"-Zeichen. ???

Wie oben geschrieben ist der 2. Punkt noch offen: Wenn ein Prozess nicht gefunden worden ist, dann meldet wmic "Keine Instanzen verfügbar". Wie kann dieser Zustand abgefragt werden (wie geschrieben hier muss eine Bedingung rein - nehmen wir mal ECHO PROZESS NICHT VORHANDEN & goto :MachAnders)?
Mit %ERRORLEVEL% haut es nicht hin.
Aber auch mit der von dir vorgeschlagenen Variante if "%%~a"=="" (anstatt if not defined %%~a) klappt es in der 1. FOR-Schleife nicht (und bis zu der 2. FOR-Schleife kommt es sowieso nicht soweit).

Gruß
Mitglied: Endoro
Endoro 13.01.2014 um 22:45:50 Uhr
Goto Top
Hey,

das Gleichheitszeichen nach dem Gleichheitszeichen führt dazu, dass die for /f Schleife dieses als Tokentrenner betrachtet. Aus dem Token ExecutablePath=C:\windows\Explorer.EXE werden die Token ExecutablePath und C:\windows\Explorer.EXE.

Die überzähligen Wagenrücklaufzeichen ("carriage return", CR, ASCII 13, HEX x0d) werden von wmic aus nur M$ bekannten Gründen produziert und verunstalten die Konsolenausgabe sowie die Variablenzuweisung mit set. Wenn die wmic Ausgabe duch ein Hexdump-Programm gepiped wird, kann zB folgendes beobachtet werden:
0000000: 0d 0d 0a 0d 0d 0a 45 78 65 63 75 74 61 62 6c 65  ......Executable
0000010: 50 61 74 68 3d 43 3a 5c 77 69 6e 64 6f 77 73 5c  Path=C:\windows\
0000020: 45 78 70 6c 6f 72 65 72 2e 45 58 45 0d 0d 0a 0d  Explorer.EXE....
0000030: 0d 0a 0d 0d 0a 0d 0d 0a                          ........
Diese unerwünschten Doppel-0d zu entfernen gelingt am besten, wenn die Ausgabe mit einer weiteren Forschleife "gefiltert" wird.

Zu deinem Code noch ein Vorschlag:
@ECHO OFF &SETLOCAL
for /f "tokens=1*delims==" %%a in ('wmic process where "name='explorer.exe' OR name='iexplore.exe'" get ExecutablePath /value') do (  
	for /f "delims=" %%c in ("%%~b") do (  
		rem Abbildpfadname anzeigen:
		set "ExecPath=%%~c"  
		echo Folgender Prozess wird beendet: "%%~c"  
		taskkill /T /F /IM %%d
		start "" "%%~c" &&echo Folgender Prozess ist neugestartet worden: "%%~c"  
		echo(
	)
)

if not defined ExecPath echo(Prozesse nicht gefunden!
Gruss.
Mitglied: evinben
evinben 14.01.2014 um 13:02:19 Uhr
Goto Top
Hallo Endoro!

hier hat sich etwas Missverständnis eingeschichtet (dass delims beliebige Trennzeichen (Delimeter) repräsentiert ist schon klar, sonst wäre ich nicht so weit gekommen).
Als ich die Frage mit dem Gleichheitszeichen gestellt habe, war ich immer noch bei der alten Ausgabe, also:
C:\Windows\system32>for /f "skip=1delims=" %a in ('wmic process where "name='explorer.exe' OR name='iexplore.exe'" get ExecutablePath') do @for /f "delims=" %b in ("%~a") do @echo %~b  
C:\Windows\Explorer.EXE
C:\Program Files\Internet Explorer\iexplore.exe
und dachte mir du hättest da undokumentierten Judogriff angewandt, etwa was die ganze Zeit Phil macht face-wink, um das CR-Zeichen zu entfernen. Alles klar, jetzt verstehe ich, dass es ganz klassisch abläuft. Der zusätzliche Schalter /value macht es einfacher. Auf die Idee wäre ich jedenfalls nie gekommen und erneut vielen Dank hierfür!

Dein zusätzlicher Code-Vorschlag wird so allerdings nicht gehen, da in meiner 1. FOR-Schleife ja eine Liste von Prozessen abgearbeitet wird und wenn der "nicht ausgeführte Prozess" nicht zufälligerweise der letzte in dieser Liste wäre, dann würde deine 13. Zeile (echo(Prozesse nicht gefunden!) nicht abgearbeitet.

Eine weile habe ich rumüberlegt und so klappt es endlich:
@echo off
@prompt -$G
chcp 1252 >nul
PushD %~dp0
echo.

:Mit WMIC den Abbildpfadname eines Prozesses abfragen

setlocal enabledelayedexpansion
for %%d in (
	prozess1.exe
	prozess2.exe
	prozess3.exe
	prozess4.exe
	usw......exe
	) do (
		set ExecPath=
		for /f "tokens=1*delims==" %%e in ('wmic process where "name='%%d'" get ExecutablePath /value') do (  
			for /f "delims=" %%g in ("%%~f") do (  
				set "ExecPath=%%~g"  
				)
			)
		if defined ExecPath (
			rem Abbildpfadname anzegen:
			echo Folgender Prozess wird beendet: "!ExecPath!"  
			taskkill /T /F /IM %%d
			start "" "!ExecPath!" && echo Folgender Prozess ist neugestartet worden: "!ExecPath!"  
			) else echo Der Prozess "%%d" wird entweder nicht oder mit eröhten Rechten ausgeführt & call :MachAnders  
		echo.
		)
goto :END

:MachAnders
echo Andere Aufgabe wird gestartet
goto :eof

:END
:timeout /t 3 >nul
pause >nul

Was meinst du zu dem Aufbau? Könnte man so gelten lassen?

Gruß
evinben