mhuelse
Goto Top

Wie kann ich die ProzessID, eines laufenden Programms, in einer einzeiligen FOR Schleife herausfinden?

Es geht darum ein Watchdog loop script für ein Script/Programm (CMD.exe, programm_xyz.exe) zu realisieren. Das Haupt-Script startet ein weiteres "watchdog" script was die Laufzeit des Hauptscriptes überwachen soll.

: Punkt 1 :
Mir geht es nur darum, eine Loop zu realisieren die in einer FOR - Schleife nach der ProzessID eines Programms sucht (z.B.: einer ping.exe [localhost -t] die irgendwann gestartet wurde), diese ausgibt und ggf. das Hauptprogramm nach Zeit X "killt"

Punkt 2

Wie findet man in der Haupt-Batch die ProzessID eines per "start /B anderes_script.cmd" gestarteten scriptes heraus, um diese uberwachen zu können.

Punkt 3

Gibt es eine Möglichkeit, das schließen des CMD.exe Fensters (via X am rechten oberen Fensterrand) abzufangen und ein "panik" script auszuführen, was ein geordetes beenden ermöglichen würde, ein "watchdog" fürs Haupt-script sozusagen

Meine Idee wäre so eine FOR Schleife, allerdings scheint das nicht so zu klappen, wie ich das gerne hätte. Außerhalb der FOR - Schleife funktioniert mein Anssatz, was kann ich da tun bzw. wo ist mein Fehler.

for /f "tokens=3 delims=," %i in ('wmic process get processid,executablepath /format:csv^|findstr /I "ping.exe"') do ( echo  %i )  


matze

Content-Key: 147997

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

Printed on: April 23, 2024 at 14:04 o'clock

Member: rubberman
rubberman Jul 30, 2010 at 10:57:24 (UTC)
Goto Top
Hallo mhuelse.

Punkt 1 sollte mit tasklist machbar sein
for /f "delims=, tokens=2" %%a in ('tasklist /fi "imagename eq ping.exe" /fo "csv" /nh') do echo %%~a  

Punkt 3 IMO unmöglich

Punkt 2 vielleicht mit WIMIC, such mal im msdn. Mir fällt da auf Anhieb aber nichts ein.
[Edit: Oder du gibst dem Kind einen Namen (Fenstertitel), dann geht's auch per tasklist. /]

Grüße
rubberman
Member: mhuelse
mhuelse Jul 30, 2010 at 11:33:24 (UTC)
Goto Top
Viele Dank!

das ist auch mein erster Gedanke gewesen, das mit tasklist zu machen, nur ist da das Problem, dass ich das nicht an einem Verzeichnis festmachen kann, wie mit "wmic process get processid,executablepath /format:csv"
Ich gebe zu, man hätte das am Anfang mit erwähnen sollen.

Matze
Mitglied: 77559
77559 Jul 30, 2010 at 12:29:45 (UTC)
Goto Top
Hallo rubberman,
Punkt 3 IMO unmöglich
In der Form schwierig (wenn auch nicht unmöglich) aber mit einem Tool wie CMDOW könnte man die zu schützende CMD mit /HID verstecken, dann kann auch niemand irgendwo drauf klicken.

Hier mal eine Demo:
@echo off & SetLocal & CLS
Set "MSG=Achtung"  
If "%1" EQU "DispWarn" Goto :DispWarn  
set Delay=10

Echo Batch gestartet, 
Echo.
Echo Dieses CMD Fenster verschwindet nach drücken einer beliebigen Taste für %Delay% Sekunden
pause >NUL
:: Startet diese Batchdatei nochmal in sep. Fenster zur Anzeige einer Warnung
Start "%MSG%" cmd.exe /k "%~f0" DispWarn  

:: Verstecke mich
cmdow @ /HID
:: warten
ping -n %Delay% localhost >NUL 2>&1
:: komm wieder raus.
cmdow @ /VIS
:: Beende jetzt überflüssigen warnhinweis
cmdow %MSG% /END
Echo bin wieder da

pause

Goto :Eof

:DispWarn
mode con: cols=50 lines=10
color e1
Title %MSG%
cls
:: setze mich on Top
cmdow @ /TOP
Echo.Hier sollte dein Hinweis hin
Echo.
Echo.Laber bla blubb
Echo.Laber bla blubb
:Setze ein paar Punkte zur Simulation es täte sich etwas
For /L %%l in (1,1,49) do ping -n 2 localhost >NUL & set /P _="."<NUL  
Echo.
goto :Setze

Gruß
LotPings
Member: pieh-ejdsch
pieh-ejdsch Jul 30, 2010 at 12:40:19 (UTC)
Goto Top
Hi mhuelse,

zu Punkt 2 wäre die Zeile vllt so abänderbar

C:\Users\Pieh-Ejdsch>for /f "tokens=2* delims=," %i in ('"wmic process get processid,executablepath,commandline /format:csv"  ') do @echo "%i,%j" |findstr /c:"\"cmd /"  

Gruß Phil
Member: mhuelse
mhuelse Jul 30, 2010 at 13:46:07 (UTC)
Goto Top
Hi,

Leider kann ich dein Codeschnippsel nicht ganz nachvollziehen, helft mir mal, dass zu verstehen. Ich hab's einfach mal mit einem Test probiert, werde aber eben nicht ganz schlau daraus...

echo ping localhost -n 30>test.cmd
echo ENDE!>>test.cmd

start /b test.cmd


for /f "tokens=2* delims=," %%i in ('"wmic process get processid,executablepath,commandline /format:csv"  ') do echo "%%i,%%j" |findstr /c:"\"cmd /"  
Member: pieh-ejdsch
pieh-ejdsch Jul 30, 2010 at 22:29:49 (UTC)
Goto Top
Hi mhuelse,

Mein Fehler - da war ich wohl zu voreilig. executablepath kannste auch weglassen ist eh immer "Pfad der cmd.exe"
for /f "tokens=2* delims=," %i in ('"wmic process get processid,commandline /format:csv"') do echo "%i,%j" |findstr /c:"\"cmd /"  
gibt ja nur die Zeile(n) von Batches aus, welche noch aktiv sind aber nur mit der Befehlszeile: "Pfad\Batch.cmd" im CMD-Fenster oder Ausführen-Dialog bzw. Doppelklick darauf gestartet worden sind.
in diesem Beispiel
Startparameter commandline , PID
"cmd /c ""E:\AdminHelp\test123.cmd" ",316"

for /f "tokens=2* delims=," %i in ('"wmic process get processid,commandline /format:csv"') do @echo "%i,%j"|findstr /c:"cmd.exe  /K"  
gibt die Zeile(n) aus, welche mit "start /b "Pfad\Batch.cmd" im CMD-Fenster oder Batches gestartet wurden
solange dieses CMD-Fenster noch aktiv ist wird die Zeile ausgegeben auch wenn in diesem CMD-Fenster mit EXIT quittiert wird und das Fenster offen ist

Beispielausgabe:
"C:\Windows\system32\cmd.exe  /K E:\AdminHelp\test123.cmd,2456"

PS. das erste token von der Wmic ausgabe ist mit Formatangabe entsprechend %Userdomain%, deswegen hatte ich es gleich weggelassen.
Gruß Phil
Member: rubberman
rubberman Jul 31, 2010 at 00:07:27 (UTC)
Goto Top
@77559

Joa, das wird den User nicht abhalten das Ding im Taskmanager zu killen.
BTW Ähnliches (disable / enable Closebutton) hab ich als Toolchen selbst schon in C++ geschrieben. Hilft natürlich ebensowenig.

Letztlich bleibt vermutlich also nur von außen zu überwachen, ob der Task noch läuft. Vermutlich wird es dann aber schon zu spät sein...

Grüße
rubberman
Member: TsukiSan
TsukiSan Jul 31, 2010 at 00:18:22 (UTC)
Goto Top
Letztlich bleibt vermutlich also nur von außen zu überwachen, ob der Task noch läuft. Vermutlich wird es dann aber schon zu spät sein...

und wenn sich ständig etwas selbst penedrant startet und um's Verreck.. nicht schließen lässt, dann haben wir schon fast so etwas wie einen Virus/Wurm etc.

Mein Tipp:
Wenn du, mhuelse, der Admin bist, dann sperre bei den usern einfach den Zugriff auf den Taskmanager und lasse dein Script hidden ausführen und du musst dir um Punkt 3 wenig Gedanken machen.

Gruss
tsuki
Member: mhuelse
mhuelse Aug 02, 2010 at 06:44:35 (UTC)
Goto Top
Ich bin zwar der Support-Admin auf diesem System, aber leider nicht der einzigste, und erschwerend kommt hinzu, das die auch noch überall in Deutschland verteilt sitzen. Ansonsten ist es schon richtig, dass man damit nicht "nette Sachen" veranstalten könnte. Es ging ja auch nicht drum das "versteckt" zu machen, sondern einfach nur darum ein "definiertes" beenden des mittlerweile sehr komplexen multiuser - Hauptscripts zu erreichen. Dafür schien mir so eine Art "Interaktiver - watchdog" ganz geeignet zu sein.
Auf dem TS System den Taskmanager zu deaktivieren ist eine schlechte Idee, da dort ständig irgendwelche Java Prozesse hängenbleiben bzw. von den Benutzern nicht richtig beendet wurden bzw. durch Kommunikations -problemchen rausfliegen.

@ Phil

wie bekomme ich das hin, dass mir in einem Einzeiler nur die PID in einer Variable landet, sozusagen Punkt 1 und Punkt 2 in einem zu lösen. Eine verschachtelte FOR-Schleife hab ich bis jetzt noch nicht so hinbekommen.


Vielen Dank
Mathias
Member: pieh-ejdsch
pieh-ejdsch Aug 02, 2010 at 07:08:05 (UTC)
Goto Top
Moin,

das zweite ausgegebene Token ist doch die PID
das wäre dann so
for /f "tokens=2* delims=," %i in ('"wmic process get processid,commandline /format:csv"') do (@echo "%i"|findstr /c:"cmd.exe  /K">nul&& set "PID=%j")  

als verschachtelte For-Schleife eventuell so

for /f "tokens=2* delims=," %i in ('"wmic process get processid,commandline /format:csv"') do (@echo "%i"|findstr /c:"cmd.exe  /K">nul&&(echo PID j%& taskkill /PID %j))  

Gruß Phil
Member: mhuelse
mhuelse Aug 02, 2010 at 11:26:20 (UTC)
Goto Top
Vielen Dank Phil!

Da ich kein Hauptamtlicher Admin bin und eigentlich anderes auf dem Radar habe, muss ich mir immer mal Zeit nehmen dieses "script" zu pflegen / optimieren, sodass ich zeitlang nur Gedanklich an dem script arbeite. Darum auch die eventuell "simplen" Fragen....

Grüße
Mathias
Member: mhuelse
mhuelse Aug 10, 2010 at 13:43:26 (UTC)
Goto Top
Habe da noch eine Frage dazu, da mein gedankliches Konstrukt, was ich heute mal in "real" testen wollte nicht so recht will.

::
:: Testweise einen PING ausführen und nach ca. 15 Sekunden Task hart beenden
::
start ping.exe -n 300 localhost
:: 
for /L %%X IN (5,-1,2) do (
echo Loop=%%X
C:\WINDOWS\system32\ping.exe -n 3 localhost
for /f "tokens=2* delims=," %%i in ('"wmic process get processid,commandline /format:csv"') do (@echo %%i|findstr "ping.exe">nul&& set PID=%%j)  
::
:: wenn keine PID definiert, dann exit
::
)
echo timeout
taskkill /f /PID %PID%
exit 0

Wenn ich dieses Script ausführe erhalte ich folgende Fehlermeldung;

C:\DOCUME~1\USR~1.DSD\LOCALS~1\Temp\1>echo Loop=%X
Loop=4
) was unexpected at this time.

C:\DOCUME~1\USR~1.DSD\LOCALS~1\Temp\1>)

Wenn ich die "innere" FOR Schleife;
for /f "tokens=2* delims=," %i in ('"wmic process get processid,commandline /format:csv"') do (@echo %i|findstr "ping.exe">nul&& echo PID=%j)  

separate am CMD ausführe erhalte ich nur "()" Klammern und später das gewünschte Ergebnis. Wenn ich die Klammern hinter dem "DO" weglasse sieht es zumindest richtig aus.
Was ist mein Fehler, bzw. was kann ich tun damit es funktioniert.

Vielen Dank
Mathias
Member: pieh-ejdsch
pieh-ejdsch Aug 11, 2010 at 13:55:26 (UTC)
Goto Top
Hi Mathias,

Wenn Du KommentarZeilen innerhalb von Klammern Verwenden möchtest dann Nicht als Letzte Zeile innerhalb dieser Klammer!

Achte bei einer AusKommentierten Klammer darauf dass die Zeile nach dem Kommentar einen Befehl enthält (zumindest ein REM)

führe Diese im CMD-Fenster aus
echo 1. Test mit REM innerhalb einer Klammer 
(echo 1.1
echo 1.2
echo 1.3
Rem
)

echo 2. Test mit Kommentar-Zeilen vor BefehlsZeilen innerhalb einer Klammer 
(::Kommentar vor dem 1.Befehl in der IF-Klammer
echo 2.1
::Kommentar vor dem 2.Befehl in der IF-Klammer
echo 2.2
::Kommentar vor dem 3.Befehl in der IF-Klammer
echo 2.3
::Kommentar vor dem 4.Befehl in der IF-Klammer
Rem
)

echo 3. Test mit Kommentar-Zeilen als Letzte Zeile innerhalb einer Klammer - geht NICHT
(echo 2.1
echo 2.2
echo 2.3
REM
::Kommentar als Letzte Zeile in der IF-Klammer fasst in die Grütze
)

Warum suchst Du erst viermal nach der PID von ping.exe - setzt nur die zuletzt gefunde PID als Variable und Killst den Prozess erst am Ende?

Gruß Phil