Programm1 starten, 10 Sekunden warten, Programm 2 starten

o0Julia0o

Commander
Registriert
Dez. 2012
Beiträge
2.767
hi, ich möchte folgendes per batch erledigen:

Programm 1 start
10 sekunden warten
Programm 2 start
Wenn Programm 1 beendet, dann
echo Programm 1 beendet

Während Programm 1 läuft, also nach dessen start, soll ca. 10 Sekunden gewartet werden. Dann soll Programm 2 gestartet werden.
Wenn Programm 1 beendet wird, soll "Programm 1 beendet" ausgegeben werden.


So geht es nicht:
Code:
start /wait Programm1.exe
start timeout 10
start Programm2.exe
rem [Programm 1 wird vom Nutzer beendet]
echo Programm 1 beendet

Programm 1 wird wie es soll gestartet. Jedoch beginnt der timer erst nachdem Programm 1 beendet wurde. Danach wird Programm 2 wie gewünscht gestartet. Der Text wird auch wie gewünscht ausgegeben.

Wie starte ich also den timeout parallel zu Programm1?
 
Zuletzt bearbeitet:
versuchs mal mit "wait" oder "sleep"
 
  • Gefällt mir
Reaktionen: o0Julia0o
Einfach nur
Code:
timeout /t 10

ggf noch ein /nobreak dranhängen
 
  • Gefällt mir
Reaktionen: o0Julia0o
Danke. Sleep gibt es nicht mehr. Das /wait gebe ich bei Programm1 mit, damit das echo erst ausgegeben wird, sobald Programm1 beendet wurde. Leider wartet der Rest der Batch auch auf Beendigung von Programm1.

Das /t beim timout-Befehl ist überflüssig. Auch so verhält es sich aber wie beschrieben:
Code:
start /wait Programm1.exe
start timeout 10
start Programm2.exe
rem [Programm 1 wird vom Nutzer beendet]
echo Programm 1 beendet
Es wird mit Allem auf Beendigung von Programm1 gewartet. Doch nur das echo soll darauf warten - die letzte Zeile.
 
  • Gefällt mir
Reaktionen: Asghan
starte programm 1 & wait + starte prorgamm 2

Also programm 2 in neuem thread starten, der zu beginn 10 sekunden wartet
 
o0Julia0o schrieb:
danke, wie sähe das im code aus?
Lol. Ich hab Bash gelesen. Sorry. Aber bei Batch kann man bestimmt auch irgendwie mit Threads programmieren. Kenne mich da aber nicht aus.
 
  • Gefällt mir
Reaktionen: o0Julia0o
Geht nicht auch Powershell?

$Prog1 = "wordpad.exe" $Prog2 = "notepad.exe" $id = Start-Process $Prog1 -Passthru Start-Sleep 10 Start-Process $Prog2 Wait-Process -Id $id.Id Write-Output "Prog1 beendet"
 
  • Gefällt mir
Reaktionen: o0Julia0o
Ist das nicht ein ähnliches Thema wie hier?
https://www.computerbase.de/forum/threads/mp3-player-welcher-unsichtbara-laeuft.2029067/
Aber da hast du dir ja auch nicht helfen lassen - z.B. wurde dir da schon gesagt, dass es mit dem Batch-Skript erst weiter geht, wenn Programm1 beendet wird. Hast du aber auch nicht geglaubt.

Mit "start /wait" kommst du jedenfalls nicht weiter. Was ist überhaupt dein Ziel? Was willst du erreichen? Nicht, dass wir hier ein XY-Problem haben.
 
  • Gefällt mir
Reaktionen: o0Julia0o und abcddcba
o0Julia0o schrieb:
Code:
start /wait Programm1.exe

Jedoch beginnt der timer erst nachdem Programm 1 beendet wurde..
Ja, da du start mit Parameter /wait ausführen lässt.
Lass das weg und Programm1.exe wird parallel zur Batch gestartet.

o0Julia0o schrieb:
Programm 1 start
10 sekunden warten
Programm 2 start
Wenn Programm 1 beendet, dann
echo Programm 1 beendet
Das ist so mit Batch nicht möglich.
Batch kennt keine Threads, maximal Prozesse und dann auch nur in dem Sinne, dass es Child Prozesse über Start und Call starten kann.

Mir fallen ein paar Ansätze ein, wie es eventuell machbar wäre.
1.: Beide Programme starten, Tasklist eine Ewigkeit durchloopen und nach den Programmen auschau halten.
In etwa so (nicht getestet!):
Code:
start Programm1.exe
start timeout 10
start Programm2.exe

FOR /L %%i IN (1,1,100000) DO (
  (TASKLIST | FIND /I "program1.exe") || ECHO Programm 1 beendet
  (TASKLIST | FIND /I "program2.exe") || ECHO Programm 2 beendet
)

2.: Beide Programme über eine separate Batch-Dateie starten und mit WaitFor auf ein Signal warten.
In etwa so (nicht getestet und hat einige Schwächen!):
Code:
::SeparateBatch
START /wait %1
WAITFOR /s %computername% /si MyProgramTermination

::Haupt-Batch
SET ProgramMsg1="Programm 1 beendet"
SET ProgramMsg2="Programm 2 beendet"

start SeparateBatch.bat "program1.exe"
start timeout 10
start SeparateBatch.bat "program2.exe"

WAITFOR MyProgramTermination

TASKLIST | FIND /I "program1.exe"
IF %ERRORLEVEL% NEQ 0 (
  ECHO %Program1Msg%
  SET ProgramMsg=%Program2Msg%
) ELSE (
  ECHO %Program2Msg%
  SET ProgramMsg=%Program1Msg%
)

WAITFOR MyProgramTermination
ECHO %ProgramMsg%

3.: Mach das nicht mit Batch!
 
  • Gefällt mir
Reaktionen: o0Julia0o
Du könntest noch "ping" verwenden, wenn du sonst nix hast. Die anderen Lösungen sind aber eleganter.

Code:
rem 10 pings ausführen = 10 sekunden warten
programm1.exe
ping -n 10 127.0.0.1
programm2.exe
 
  • Gefällt mir
Reaktionen: o0Julia0o und floq0r
Nein, grad geprüft, mit 'start /wait prog' wartet die CMD auf das Ende von Prog. Bei Prog aufruf ohne Start sollte das gleiche Verhalten auftreten. 'start prog' dürfte zum Ziel führen. Danach dann 'timeout /T 10 /nobreak' um zu warten.
 
  • Gefällt mir
Reaktionen: o0Julia0o
Das Problem ist dann aber, dass wenn ich Programm1 beende, es nicht registriert wird. Und somit auch kein "echo" ausgegeben werden kann darüber. Beide Programme parallel ans Laufen zu bekommen ist nicht das Problem.

AW4 schrieb:
3.: Mach das nicht mit Batch!
Ich kann aber nix anderes!

sandreas schrieb:
Du könntest noch "ping" verwenden
Das Warten an sich ist nicht das Problem. Ansonsten könnte man auch pingen dafür.

Giana schrieb:
Geht nicht auch Powershell?
Mit Powershell kenne ich mich gar nicht aus. Mit dem Code scheint es mir aber auch nicht das zu tun, was ich wollte. Sieht zumindest so knapp aus der code.

gaym0r schrieb:
Ist das nicht ein ähnliches Thema wie hier?
https://www.computerbase.de/forum/threads/mp3-player-welcher-unsichtbara-laeuft.2029067/
Aber da hast du dir ja auch nicht helfen lassen - z.B. wurde dir da schon gesagt, dass es mit dem Batch-Skript erst weiter geht, wenn Programm1 beendet wird. Hast du aber auch nicht geglaubt.
Ja, ähnlich. Ich nutze das für das Thema. Ma kann aber, wie im anderem Thema geagt, weitermachen, auch wenn Programm1 noch nicht beenet ist. Der Befehl "start" ermöglicht das. Einfach beim 1. Programm ein start davor setzen, dann springt er direkt nach Ausführung zur nächsten Zeile in der Batch.

Vielleicht hat ja mal ein Mitleser ein ähnliches Problem. So funktioniert es nun:
Code:
@echo off
start Programm1.exe
start timeout 10
start Programm2.exe
:: Set Programm nachdem geguckt wird, ob es noch rennt
   :: Dateierweiterung ist Pflicht
   SET LaufProg=Programm1.exe
:: Set Programm was beendet werden soll
   :: Dateierweiterung ist Pflicht
   SET KillProg=Programm2.exe

    :: Set Wartezeit der Überprüfung in Sekunden
    SET /A "_wait=3"

    :ProzessGefunden
    timeout /t %_wait%
        tasklist /NH /FI "IMAGENAME eq %LaufProg%" | FIND /I "%LaufProg%"
        IF "%ERRORLEVEL%"=="0" (
            GOTO :ProzessGefunden
        ) ELSE (
    GOTO :Programm1echo
        )

:Programm1echo
echo Programm 1 beendet
exit
Das 2. Programm beenden könnte man z.B. so(2. lezte Zeile hiermit ersetzen):
Code:
TASKKILL.EXE /F /T /IM %KillProg%

Ich weiß nicht, wie aufwändig sone Guckschleife ist. Von daher habe ich mal eine Wartezeit von 3 Sekunden eingebaut. Das reicht mir im Grunde, klar wäre dauerhaftet gucken schöner. Aber wenn die CPU dann glüht und keine Zeit mehr für andere Prozesse hat wäre auch blöd. Vielleicht wäre es ressourcenschonender, wenn ich der der PID suchen lassen würde?
 
Zuletzt bearbeitet:
Ich vermute mal, dass die Suche nach PID oder Name ähnlich von der Zeit sind. Aber wenn du die Prüfung nicht verlangsamst, dann kann die Batch dabei einen Thread zu 100% auslasten. Wie Windows die Ressourcen dann mit anderen Programmen verteilt, die auf der gleichen Prio laufen, kann man wohl nur vermuten.
 
  • Gefällt mir
Reaktionen: o0Julia0o
Der Prozessname ist nicht einzigartig. Die Verwendung erschließt sich mir daher nicht und führt zu unvorhersehbarem Verhalten.
Die Performancefrage stellt sich nicht.
Batch ist scheinbar auch nicht eine geeignete Umgebung für diesen Anwendungsfall.
 
  • Gefällt mir
Reaktionen: o0Julia0o
Einzigartig genug ;) PID auslesen von dem Prozess hätte das gleiche Problem, da man dieses ja auch erst über den Namen machen müsste.

Warum stellt sich die Performancefrage nicht?

Ich denke auch, dass Batch schlecht-, aber nicht ungeeignet ist. Für mich jedenfalls die einzig mögliche Umgebung.
 
PowerShell ist ja nun weiß Gott keine Raketenwissenschaft. Wer sich mit Batch-Codes auskennt, wird mit PowerShell-Codes auch sehr schnell zurechtkommen. Das ist nur eine reine Willenssache.

In dem anderen Thread könnte man die Sache sehr schnell und einfach mit PowerShell und mit den Elementen des WindowsMediaPlayers in die Tat umsetzen.
Man braucht dafür keine 3rd-Party-Tools.

Aber gut, wer nicht will, der hat halt schon.
 
  • Gefällt mir
Reaktionen: BAGZZlash
Probier mal mit folgendem Programm:
C++:
#include <unistd.h>
#include <time.h>
#include <vector>
#include <string>
#include <iostream>
#include "mingw.thread.h"

void mytask(std::string s)
{
    int n1 = time(NULL);
    system(("start " + s).c_str());
    int n2 = time(NULL);
    std::cout << s << " ends and has time " << (n2 - n1) << " seconds." << std::endl;
}

int main(int argc, char const* argv[])
{
    std::vector<std::string> vs;
    for (int i = 1; i < argc; i++) {
        vs.push_back(std::string(argv[i]));
    }
    int n = (argc - 1) / 2;
    for (int i = 0; i < n; i++) {
        std::thread t1(mytask, vs[i * 2]);
        t1.join();
        usleep(std::stoi(vs[i * 2 + 1]) * 1000 * 1000);
    }
    return 0;
}

Übersetzt habe ich das unter Ubuntu für das Zielsystem Windows:
x86_64-w64-mingw32-g++ -static-libgcc -static-libstdc++ prog1.cpp -o a.exe

"mingw.thread.h" gibt es hier.

Ein Aufruf wäre dann wie folgt:
a.exe b.exe 10 c.exe 0

(a.exe ruft b.exe auf, wartet 10 Sekunden, ruft c.exe auf und wartet 0 Sekunden; sobald ein Programm fertig ist, wird dessen Ausführungszeitdauer ausgegeben (in Sekunden)).
 
  • Gefällt mir
Reaktionen: o0Julia0o
Sorry, das funktionierte noch nicht richtig, weil system(("start ... anscheinend sofort zurückkehrt. Aber das funktioniert jetzt (und ist ganz "Win-Api-konform"):

siehe neue Version.

c++ DeinCode.cpp -std=c++11

Die Aufrufkonvention bleibt dieselbe.

Also, damit kann man das lösen, was cmd.exe nicht kann. (Oder man nimmt die Powershell)

Edit: Da Windows und nix komplett unterschiedliche Prozessmodelle haben, sehen beide Programme so sehr unterschiedlich aus. (Hier steht mehr darüber)

Edit: Siehe auch den hinzugefügten Dateianhang...
 
Zuletzt bearbeitet: (neue Version)
  • Gefällt mir
Reaktionen: o0Julia0o
Zurück
Oben