evinben
Goto Top

In FOR-Schleife nur 1x Echo ausgeben, den Rest in der Reihenfolge normal abarbeiten

Hallo Administratoren,

ich schaffe leider nicht in einer FOR-Schleife nur 1x Echo auszugeben. Das ist eine Überschrift und lautet hier „Folgende Prozesse werden beendet“. Diese Echo-Zeile soll nur dann erscheinen, wenn während der Prüfung anhand der Prozess-Liste mind. ein aktives Prozess gefunden wurde. Wenn ich diese Zeile in der FOR-Schleife einfach miteinbaue, dann wird sie keine Überschrift mehr, da sie mit jedem gefundenen Prozess mehrmals ausgegeben wird (was zum Nachteil der Lesbarkeit ist).
Ich habe lang ausprobiert und gerätselt, wie ich das Problem mit der Übersichtlichkeit/Lesbarkeit auf einer eleganten Art lösen kann, bin ich aber nur zur einen Lösung gekommen, die funktioniert:
Die FOR-Schleife mit der Prozess-Liste im Batch zu verdoppeln (wenn bei der ersten Schleidf ein Prozess aus der Liste gefunden wurde, dann Echo und zu der nächsten FOR-Zeile springen, ansonsten anderes Echo Kein Prozess gefunden). Das hat aber den Nachteil, dass die Prozessliste an zwei Stellen im Batch verwaltet werden müssen – nicht schön.
Momentan ist es so, dass die Überschrift mit Echo „Folgende Prozesse werden beendet“ selbst dann ausgegeben wird, wenn kein Prozess gefunden wurde – ebenso nicht schön, da sie dann zur Verwirrung stiftet.
Obwohl es so elementar klingt schaffe ich leider nicht eine akzeptable Lösung mit meinen noch frisch gesammelten Batch-Erfahrungen zu finden.
Folgenden Code habe ich mir aufgebaut:
@echo off
setlocal
@prompt -$G

:Meldung
echo.
echo Folgende Prozesse werden beendet
	for %%d in (
Datenbank.exe
ServiceDat.exe
	) do  if /i %%d==%%f call :TaskKill
Echo Kein Prozess gefunden
pause
goto :eof

:TaskKill
for /f  %%f in ('tasklist /NH /FI "imagename eq %%d"') do echo. & echo %%f & taskkill /F /IM  %%f  
:Prozesse überprüfen, die manuell beendet werden sollen
	for %%d in (
Outlook.exe
WINWORD.EXE
	) do for /f  %%f in ('tasklist /NH /FI "imagename eq %%d"') do if /i %%d==%%f echo. & echo %%f  

:M1
echo ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
echo Beenden Sie die Programme mit den hier aufgelisteten Prozessen manuell, um Datenverlust zu vermeiden.
echo ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
echo.

Mit CALL-Funktion habe ich auch eine Weile experimentiert, das ändert allerdings nichts an der Tatsache. Hier muss eine Lösung in so einer Art "Zähler" rein, die 1x ein bestimmtes Echo bzw. eine Variable u. s. ausgibt und es nicht mehr wiederhohlt.
Aber ich verlasse mich gerne auf eurer Kompetenz und bedanke mich für eure Unterstützung.

Den tollen Workshop zu der FOR-Schleife von @Friemler habe ich gelesen und werde ihn noch mehrmals durchlesen müssen.

Nochmal Danke für eure Tipps und Korrekturen.

Euer
evinben

Content-Key: 182139

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

Printed on: May 8, 2024 at 22:05 o'clock

Member: bastla
bastla Mar 17, 2012 at 17:06:58 (UTC)
Goto Top
Hallo evinben!

Schematisch etwa so:
Vor der Schleife
set "Ausgabe=Folgende Prozesse werden beendet"  
und in der Schleife
if defined Ausgabe (
    echo %Ausgabe%
    set "Ausgabe="  
)
Deine Zeile 12 wird übrigens immer ausgegeben werden ...

Grüße
bastla
Member: evinben
evinben Mar 17, 2012 at 20:35:48 (UTC)
Goto Top
Hallo bastla!

Danke dir - stimmt, das ist eine recht einfache Lösung. Was mir auch neu ist, dass nach echo %Ausgabe% kein & folgen muss.


Evinben
Member: evinben
evinben Mar 17, 2012 at 21:18:34 (UTC)
Goto Top
Hallo bastla,

jetzt habe ich bemerkt, dass mit dem folgenden Code-Aufbau jeweils nur ein Prozess gekillt wird. Ich kann leider nicht schaffen die FOR-Schleife so umzustruktruieren, dass wenn die Variable %Meldung% (und auch %MeldungB%) nicht gesetzt ist der Rest trotzdem abgearbeitet werden soll - also dass !alle! Prozesse trotzdem gekillt werden sollen.

echo off
setlocal
@prompt -$G

:In der FOR-Schleife sind Prozesse in jeder Zeile einzutragen, die auf Aktivität überprüft und automatisch beendet werden sollen

:Meldung
echo.
set "Meldung=Folgende Prozesse werden beendet"  

	for %%d in (


Datenbank.exe 
ServiceDat.exe 

	) do for /f  %%f in ('tasklist /NH /FI "imagename eq %%d"') do if /i %%d==%%f if defined Meldung echo %Meldung% & set "Meldung=" & set Gefunden=true & echo. & taskkill /F /IM  %%f  

:Prozesse überprüfen, die manuell beendet werden sollen
set "MeldungB=Beenden Sie die Programme mit den hier gelisteten Prozessen manuell, um Datenverlust zu vermeiden."  

	for %%d in (

EXCEL.EXE
WINWORD.EXE

	) do for /f  %%f in ('tasklist /NH /FI "imagename eq %%d"') do if /i %%d==%%f if defined MeldungB call :MeldungB & set "MeldungB=" & set Gefunden=true & echo. & echo %%f  

goto :M2


:MeldungB
echo.
echo ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
echo %MeldungB%
echo ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
echo.
goto :eof

:M2

if not defined Gefunden Echo Kein Prozess gefunden


:END
pause >nul

Evinben
Member: bastla
bastla Mar 17, 2012 at 21:37:01 (UTC)
Goto Top
Hallo evinben!

Es gibt ja keinen Zwang, alles in eine Zeile zu verwursten:
for %%d in (

    Datenbank.exe 
    ServiceDat.exe 

) do for /f %%f in ('tasklist /NH /FI "imagename eq %%d"') do (  
    if /i %%d==%%f (
        if defined Meldung (
            echo %Meldung%
            echo.
            set "Meldung="  
        )
        taskkill /F /IM  %%f
        set Gefunden=true
    )
)
Übrigens: Brauchst Du
if /i %%d==%%f
hinsichtlich
"imagename eq %%d"
wirklich?

Grüße
bastla
Member: evinben
evinben Mar 18, 2012 at 10:15:20 (UTC)
Goto Top
Hallo Bastla,

vielen Dank für die Korrektur. Jetzt habe ich verstanden, dass ein IF-Befehl in Klammern, unabhängig davon ob sein Ergebnis WAHR oder FALSCH ist, die Verarbeitung der nächsten Befehle nicht ausschließt. Richtig?
Allerdings was ich noch nicht verstehe ist, warum bei so einer Variant wie von dir vorgeschlagen (eine logische Zeile aber auf mehreren physikalischen Zeilen verteilt) kein &-Verkettungszeichen erforderlich ist?
Bei der nachfolgenden Varianten ist das &-Verkettungszeichen dagegen unverzichtbar – ohne es kriege ich den Code nicht zum Laufen:
for %%d in (
EXCEL.EXE
WINWORD.EXE
) do for /f  %%f in ('tasklist /NH /FI "imagename eq %%d"') do if /i %%d==%%f (if defined Meldung (echo %Meldung% & set "Meldung=")) & echo. & taskkill /F /IM  %%f & set Gefunden=true  

Zurück zu deiner letzten Frage:
da TaskList auch dann eine Antwort ausgibt, wenn kein Prozess gefunden wurde („INFORMATION: Es werden keine Aufgaben mit den angegebenen Kriterien ausgeführt.“) hilft
 
if /i %%d==%%f
hier weiter, damit die folgenden Fehler-Zeilen, die im nächsten Schritt durch TaskKill generiert werden würden, auf dem Bildschirm nicht mehr erscheinen:
FEHLER: Der Prozess "INFORMATION:" wurde nicht gefunden.  
FEHLER: Der Prozess "INFORMATION:" wurde nicht gefunden.  
FEHLER: Der Prozess "INFORMATION:" wurde nicht gefunden.  
FEHLER: Der Prozess "INFORMATION:" wurde nicht gefunden.  

Ein schönes Wochenende
Gruß
Evinben
Member: bastla
bastla Mar 18, 2012 at 10:45:08 (UTC)
Goto Top
Hallo evinben!
Jetzt habe ich verstanden, dass ein IF-Befehl in Klammern, unabhängig davon ob sein Ergebnis WAHR oder FALSCH ist, die Verarbeitung der nächsten Befehle nicht ausschließt.
Abgesehen davon, dass es ja auch noch ein "else" gäbe, ist das "if" ja nur einer von mehreren Befehlen (in der Klammer), sodass der Rest tatsächlich nicht davon abhängt ...
eine logische Zeile aber auf mehreren physikalischen Zeilen verteilt
lässt sich mit umschließenden Klammern realisieren - dann wird tatsächlich alles zwischen den Klammern als eine einzige Anweisung (auch mit Konsequenzen hinsichtlich der Variablenauflösung) betrachtet ...
da TaskList auch dann eine Antwort ausgibt, wenn kein Prozess gefunden wurde („INFORMATION: Es werden keine Aufgaben mit den angegebenen Kriterien ausgeführt.“)
Diese Ausgabe kannst Du ja verhindern:
for %%d in (
EXCEL.EXE
WINWORD.EXE
) do for /f  %%f in ('tasklist /NH /FI "imagename eq %%d" 2^>nul') do (if defined Meldung echo %Meldung% & set "Meldung=") & echo. & taskkill /F /IM  %%f & set Gefunden=true  
Grüße
bastla

[Edit] Überflüssige Klammern entfernt [/Edit]
Member: evinben
evinben Mar 18, 2012 at 12:02:18 (UTC)
Goto Top
Hallo bastla,

danke.

Diese Ausgabe kannst Du ja verhindern:
Es geht bei mir so nicht. So sieht es am CMD aus:
C:\Windows\system32>tasklist /NH /FI "imagename eq blabla" 2>nul  
INFORMATION: Es werden keine Aufgaben mit den angegebenen Kriterien ausgeführt.
Wenn der Prozess nicht gefunden wurde, wird die Meldung mit 2>nul weiterhin ausgegeben, die eine Fehlermeldung im nächsten Schritt (bei TaskKill) verursacht.

evinben
Member: bastla
bastla Mar 18, 2012 at 14:26:49 (UTC)
Goto Top
Hallo evinben!

Ich habe das nur unter XP SP3 getestet und mit der Umleitung Erfolg ...

... aber zur Not sollte bei Dir dann
tasklist /NH /FI "imagename eq blabla"|findstr /v /c:"INFORMATION: Es"
funktionieren (um das gleich "an der Quelle" abzufangen) ...

Grüße
bastla
Member: evinben
evinben Mar 18, 2012 at 15:10:33 (UTC)
Goto Top
Hallo bastla,

daher kommt es also - alles klar. Findstr mit dem Schalter /V wäre hier auch eine saubere Lösung (aber nur solange keine Umlauten u. a. Sonderzeichen im Umlaufen sind).

Nun habe ich wieder etwas tolles gelernt und bin im Batch-Bereich ein Schritt weiter gekommen.

Bis demnächst wieder

Gruß
Evinben