2017-10-21 37 views
1

J'ai un programme X.exe qui prend environ 2-6 heures pour terminer. Le temps exact est inconnu, mais je voudrais mettre en place un seuil de 6,5 ou 7 heures. Si ce programme ne renvoie aucune valeur de ce laps de temps, il sera tué. Comment puis-je l'implémenter en utilisant les fichiers batch *.bat?délai d'expiration ou de fermeture lorsque le processus est terminé

Voici ce que j'ai eu jusqu'à présent: une minuterie bat1.bat et une réelle bat2.bat.

bat1.bat:

start cmd /C bat2.bat & timeout /t 25200 & taskkill /im X.exe /f 

bat2.bat:

cd blah 
bat1.bat 

Le problème avec cette approche est que seulement après 25200 secondes (ou 7 heures) de la minuterie est arrêté, et ne sera pas résilié avant cette limite. Comment puis-je dire à l'ordinateur que si le programme X.exe est maintenant terminé, n'attendez plus?

Toute aide est appréciée!

+1

Si vous le définissez x.exe pour l'exécuter en tant que tâche planifiée, vous pouvez lui indiquer d'arrêter la tâche après 8 heures.Malheureusement, vos seules options dans le planificateur de tâches sont 1, 2, 4, 8 ou 12 heures. Ce que vous pouvez faire est d'utiliser la commande 'TASKLIST' pour vérifier si le programme fonctionne toutes les 300 secondes. Si ce n'est pas le cas, le fichier bat peut quitter. Si elle est toujours en cours d'exécution, vérifiez combien de secondes elle a fonctionné jusqu'à présent et tuez-la si elle est de 25 200 secondes. – Squashman

+0

@Squashman merci pour l'idée et la commande. J'ai un simple script 'tasklist/fi" nom de l'image eq X.exe "', mais comment retournez-vous la durée d'exécution de 'X.exe'? Pouvez-vous fournir une réponse formelle afin que je puisse l'accepter aussi? Merci!!! – kensaii

+1

Définissez trois variables. % checktime%% elapsedtime% et% killtime%. Utilisez la variable% checktime% avec la commande 'TIMEOUT'. Utilisez ensuite la commande 'TASKLIST' pour voir si le processus est en cours d'exécution. S'il est en cours d'exécution, ajoutez% checktime% à% elapsedtime%. Vérifiez ensuite si% elapsedtime% est supérieur ou égal à% killtime%. Si la condition kill time n'a pas été remplie, utilisez la commande 'GOTO' pour revenir à une étiquette avant la commande' TIMEOUT'. Si la condition kill time a été remplie, utilisez la commande 'TASKKILL' pour arrêter le processus. – Squashman

Répondre

0

grâce à @Squashman j'ai pu créer un script par moi-même. semblent fonctionner correctement

@echo off 
setlocal enableextensions enabledelayedexpansion 
set /a "checktime=60" 
set /a "elapsedtime=0" 
set /a "killtime=150" 
set XProg=X.exe 
start cmd /C runTest.bat 
timeout /t 10 
:while1 
    echo Go to WHILE loop. 
    echo elapsedtime = %elapsedtime% 
    echo killtime = %killtime% 
    set /a "timeleft = %killtime% - %elapsedtime%" 
    echo timeleft = %timeleft% 
    if /i %timeleft% geq 0 (
     tasklist /fi "imagename eq %XProg%" 2>NUL | find /i /n "%XProg%">NUL 
     if "%ERRORLEVEL%"=="0" (
      echo %XProg% is still running... 
     ) else (
      echo %XProg% is finished before timer. 
     ) 
     set /a "elapsedtime = elapsedtime + checktime" 
     timeout /t %checktime% 
     goto :while1 
    ) else (
     taskkill /im %XProg% /f 
     echo %XProg% is terminated. 
    ) 

leçons apprises: 1. difficile de comparer des variables numériques en batch (diff comparer avec 0 à la place) 2. terminé première fois elaspedtime > killtime (peut-être un peu plus long que killtime selon quelle fréquence chèques)

0

Je pense que c'est une solution beaucoup plus simple:

rem Start the process that will kill the X.exe program after 7 hours 
start "WaitingToKill" cmd /C timeout /t 25200 ^& taskkill /im X.exe /f 

rem Run the X.exe program and wait for it to terminate 
X.exe 

rem Kill the killer process and terminate 
taskkill /fi "WINDOWTITLE eq WaitingToKill" /f 

Dans cette méthode, il n'y a pas de code supplémentaire en cours d'exécution en même temps; juste l'état d'attente de la commande timeout.

EDIT: Quelques explications ajoutées

Notez que les deux processus de cmd.exe "WaitingToKill" avec la commande timeout et le programme X.exe sont en cours d'exécution en parallèle. Si la commande timeout se termine après 7 heures, la commande taskkill /im X.exe /f est exécutée, le programme X.exe est arrêté et les deux processus cmd.exe se termine.

Si le programme X.exe se termine avant les 7 heures, le fichier batch exécute la ligne suivante comme d'habitude. Cette ligne est taskkill /fi "WINDOWTITLE eq WaitingToKill" /f, donc la fenêtre avec la commande timeout est supprimée et les deux processus cmd.exe se termine.

+0

merci pour la réponse, mais c'est pourquoi exactement la question est posée: 'X.exe' termine parfois avant le minuteur, d'où je voudrais vérifier périodiquement si le programme est toujours en cours d'exécution. la réponse que vous proposez est presque identique à mon ancienne solution. Je me trompe quelque part? – kensaii

+0

Vous n'avez pas besoin de vérifier périodiquement quoi que ce soit: les deux processus doivent se terminer lorsque l'autre processus se termine. Il suffit donc d'attendre qu'un processus se termine et de tuer l'autre processus à ce moment-là. Voir mon edit ... – Aacini

+0

Pour être plus clair: Quand tuer le programme «X.exe»? lorsque la commande 'timeout' se termine. Quand tuer la commande 'timeout'? quand le programme 'X.exe' se termine (sauf si j'ai mal compris votre exigence **':/'**) ... – Aacini

0

J'ai essayé différentes solutions, mais à la fin c'est vraiment encombrant en batch. Si vous êtes prêt à utiliser un outil externe de la manière la plus simple est

"C:\Program Files\Git\usr\bin\timeout.exe" 5 .\test.exe

Il retourne correctement le code de sortie du processus de test, fonctionne également si vous engendrez processus de test multiples simultanément et ne fenêtres pop pas tous le temps.