I want write batch script:
Open cmd.exe and then run command which run minimalized Matlab (MATLAB.exe) and then matlab app (MATLABWindow.exe)
After that it must check if Matlab app is working
if yes, do nothing (still checking)
if not, it will kill minimalized MATLAB.exe
What I wrote but didnt work except running matlab and matlab app:
#ECHO OFF
START cmd.exe /min /k "matlab -nosplash -nodesktop -minimize -r "matlab.apputil.run('ThorlabsLC100APP')""
taskkill /F /IM cmd.exe
SLEEP 30
:search
TASKLIST|FIND "MATLABWindow.exe"
IF %ERRORLEVEL% equ 0 (
GOTO search)
ELSE (GOTO found)
TIMEOUT /T 5
GOTO search
:found
taskkill /im MATLAB.exe
EXIT
Thanks
Solved:
if not DEFINED IS_MINIMIZED set IS_MINIMIZED=1 && start "" /min "%~dpnx0" %* && exit
#ECHO OFF
START /min cmd.exe /k "matlab -nosplash -nodesktop -minimize -r "matlab.apputil.run('ThorlabsLC100APP')""
timeout /t 30 /nobreak
:loop
tasklist /FI "IMAGENAME eq MATLABWindow.exe" | findstr "MATLABWindow.exe" >nul
if %ERRORLEVEL% == 1 goto mycode
goto loop
:mycode
taskkill /F /IM MATLAB.exe
taskkill /F /IM cmd.exe
end
Related
I wanted to call waiting spinner on my batch script like this is my code:
#echo off
::-----------------------------Waiting-Spinner-------------------------------
:spinner
set mSpinner=%mSpinner%.
if %mSpinner%'==....' (set mSpinner=.)
cls
::----------------------------Subdomain-Script-------------------------------
echo Enumerating Subdomains From Script1 %mSpinner%
python2 enumsubdomain.py google.com > google.txt
SLEEP 1
goto spinner
echo Enumerating Subdomains From Script2 %mSpinner%
python2 enumsubdomain2.py yahoo.com > yahoo.txt
SLEEP 1
goto spinner
#pause
And this spinner text output should be something like this:
Enumerating Subdomains From Script1 ...<Here this dot will be animated]
Enumerating Subdomains From Script2 ...<Here this dot will be animated]
But it only outputs first line(Script1) and the 2nd script stops and doesn't outputs the 2nd line as well, i guess it's because of goto line in batch script and i have no idea what can be done here to make it work!
After clarification in your comment, you'd probably want something like this.
We start the commands in separate windows with new window titles per window, then we use tasklist to determine of either are still running. So both results will be echo if both run, or only one will be echod if only one runs.
#echo off
set done1=1
set done2=1
start "enum1" /min cmd.exe /C ^(python2 enumsubdomain.py google.com ^> google.txt^)
start "enum2" /min cmd.exe /C ^(python2 enumsubdomain2.py yahoo.com ^> yahoo.txt^)
:spinner
set mSpinner=%mSpinner%.
if "%mSpinner%"=="...." (set mSpinner=.)
cls
(tasklist /FI "WINDOWTITLE eq enum1" | findstr /i "cmd")>nul && echo Enumerating Subdomains From Script1 %mSpinner% || set done1=0
(tasklist /FI "WINDOWTITLE eq enum2" | findstr /i "cmd")>nul && echo Enumerating Subdomains From Script2 %mSpinner% || set done2=0
if %done1% equ 0 if %done2% equ 0 goto :eof
(sleep 1)>nul
goto :spinner
You want to use the spinner several times, so using a subroutine for the spinner is a good idea.
The main problem is: batch waits for a command to end before continuing with the next one, so you can't include the python command into the loop. Solution: start the command as an independent process and then start the "spinning loop". Break it, when the independent process does not exist anymore.
Here the subprocess :spinner takes a string as parameter (the message), making it flexible.
Instead of clearing the screen (cls) for each iteration of the loop, I took a different approach: overwriting the line over and over (less flickering and keeping the previous screen intact)
#echo off
setlocal EnableDelayedExpansion
REM create a CariageReturn:
for /f %%a in ('copy /Z "%~dpf0" nul') do set "CR=%%a"
cls
start /min "MySpinnerProcess" cmd /c "timeout 8 >google.txt"
call :spinner "Enumerating Subdomains From Script1"
start /min "MySpinnerProcess" cmd /c "timeout 5 >yahoo.txt"
call :spinner "Enumerating Subdomains From Script2"
echo finished.
goto :eof
:spinner
tasklist /fi "WindowTitle eq MySpinnerProcess" 2>nul | findstr /bilc:"cmd.exe" >nul || (
echo %~1 done.
goto :eof
)
set "mspinner=%mspinner%."
if %mspinner% == .... set "mspinner=."
<nul set /p ".=%~1 %mspinner% !CR!"
timeout 1 >nul
goto :spinner
For completeness my script for running the two scripts simultaneously. (very similar to Gerhard's solution, but keeping two spinners) (in my defense: I already had it ready when I asked you if you want them one after the other or simultaneously, but I just had to spend the sunny Sunday Afternoon outside)
#echo off
setlocal
::---------Waiting-Spinner---------
start /min "MyPhytonProcess1" cmd /c "timeout 8 >google.txt"
start /min "MyPhytonProcess2" cmd /c "timeout 5 >yahoo.txt"
:spinner
set mSpinner1=%mSpinner1%.
set mSpinner2=%mSpinner2%.
if %mSpinner1%==.... (set mSpinner1=.)
if %mSpinner2%==.... (set mSpinner2=.)
cls
::----------------------------Subdomain-Script-------------------------------
echo Enumerating Subdomains From Script1 %mSpinner1%
echo Enumerating Subdomains From Script2 %mSpinner2%
if "%mSpinner1%%mSpinner2%" == "Done.Done." goto :done
tasklist /FI "WindowTitle eq MyPhytonProcess1" 2>nul |find "cmd.exe" >nul || set "mSpinner1=Done"
tasklist /FI "WindowTitle eq MyPhytonProcess2" 2>nul |find "cmd.exe" >nul || set "mSpinner2=Done"
timeout 1 >nul
goto :spinner
:done
echo finished.
#pause
I have a X.exe program that takes about 2-6 hours to finish. Exact time is unknown, but I'd like to implement a threshold of 6.5 or 7 hours. If this program does not return any value by this amount of time, it will be killed. How do I implement this using batch *.bat files?
Here is what I had so far: a timer bat1.bat and an actual bat2.bat.
bat1.bat:
start cmd /C bat2.bat & timeout /t 25200 & taskkill /im X.exe /f
bat2.bat:
cd blah
bat1.bat
The problem with this approach is that only after 25200 seconds (or 7 hours) the timer will be stopped, and it won't be terminated before that limit. How do I tell the computer that if the program X.exe is finished then don't wait anymore?
Any help is appreciated!
I think this is a much simpler solution:
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
In this method there is not any additional code running at same time; just the waiting state of timeout command.
EDIT: Some explanations added
Note that both the "WaitingToKill" cmd.exe process with the timeout command and the X.exe program are running in parallel. If the timeout command ends after 7 hours, the taskkill /im X.exe /f command is executed, the X.exe program is killed and both cmd.exe processes ends.
If the X.exe program ends before the 7 hours, the Batch file execute the next line as usual. This line is taskkill /fi "WINDOWTITLE eq WaitingToKill" /f, so the window with the timeout command is killed and both cmd.exe processes ends.
thanks to #Squashman i was able to build a script on my own. seem to work fine
#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.
)
lessons learned:
1. hard to compare numeric variables in batch (compare diff with 0 instead)
2. terminated first time elaspedtime > killtime (might be a bit longer than killtime depending how often it checks)
I've tried various solutions but in the end this is really cumbersome in batch.
If you are willing to use an external tool the simplest way is
"C:\Program Files\Git\usr\bin\timeout.exe" 5 .\test.exe
It properly returns the exit code of the test process, also works if you spawn multiple test processes simultaneously and does not pop up windows all the time.
Here's my script in my bat file:
cd "C:\Program Files (x86)\Steam\Steamapps\common\F13game\"
Start F13theGameRemap.exe
cd "C:\Program Files (x86)\Steam\steamapps\common\F13Game\SummerCamp\Binaries\Win64\"
Start /WAIT SummerCamp.exe
Start /WAIT Taskkill /f /im F13theGameRemap.exe
exit
All I want is to run the first program, then the 2nd. When the 2nd program "summercamp.exe" exits, i want the first program "F13thegameremap.exe" to exit.
The way this script works now is that Taskkill immediately ignores the start /wait command of summercamp.exe and closes F13theGameRemap.exe immediately.
How do I fix this?
Something like this:
#Echo off
Cd /D "C:\Program Files (x86)\Steam\Steamapps\common\F13game\"
Start F13theGameRemap.exe
Cd /D "C:\Program Files (x86)\Steam\steamapps\common\F13Game\SummerCamp\Binaries\Win64\"
Set "App2=SummerCamp.exe"
Start /WAIT %App2%
:loop
Timeout /t 1 >NUL
tasklist.exe /FI "ImageName eq %App2%" /NH |find /i "%App2%" >NUL && Goto :loop
Start /WAIT Taskkill /f /im F13theGameRemap.exe
The :loop will check with 1 second delay if %App2% aka SummerCamp.exe is still running.
I have a batch file that starts two programs :
#echo off
start "" "C:\Program Files (x86)\Kodi\Kodi.exe"
start "" "C:\Program Files\OpenVPN\bin\openvpn-gui.lnk"
Now when i close program "Kodi", i want that it close automatically first the task "openvpn-gui.exe" and then "openvpn.exe"
Thank you !
What about this:
start "" "C:\Program Files\OpenVPN\bin\openvpn-gui.exe"
start "" "C:\Program Files\OpenVPN\bin\openvpn.exe"
start "" /WAIT "C:\Program Files (x86)\Kodi\Kodi.exe"
taskkill /IM "openvpn.exe"
taskkill /IM "openvpn-gui.exe"
Not tested, but give a try :
#echo off
Title Killing two process automatically after closing one program manually
set "RunningProcess=Kodi.exe"
set "Process2Kill=openvpn-gui.exe openvpn.exe"
tasklist /fi "imagename eq %RunningProcess%" /nh |find /i /c "%RunningProcess%"|findstr "^1$" >nul
If "%Errorlevel%" EQU "1" (
For %%a in (%Process2Kill%) do Call :KillProcess "%%a"
) else (
echo %RunningProcess% is still running
)
pause & exit
:KillProcess
Taskkill /f /im "%~1">nul 2>&1
goto :eof
I am trying to get a song to play in the background of Windows, after a little looking I found this:
#echo off
set file=RRLJ.mp3
( echo Set Sound = CreateObject("WMPlayer.OCX.7"^)
echo Sound.URL = "%file%"
echo Sound.Controls.play
echo do while Sound.currentmedia.duration = 0
echo wscript.sleep 100
echo loop
echo wscript.sleep (int(Sound.currentmedia.duration^)+1^)*1000) >sound.vbs
start /min sound.vbs
This works well for starting the song but I have no way of stopping it from a .bat file. The only way I found to cut it short is to open task manager and close it from the processes.
I have tried:
taskkill /im wscript.exe
But I keep getting something in the window saying:
Success: Sent termination sidnal to the process "wscript.exe" with PID 185448
but the music continues to play until I manually end it with task manager
I'd use /T switch (Tree kill): terminates the specified process and any child processes which were started by it.
Here is a script to find ProcessID to terminate exactly needed process only using PID:
#ECHO OFF >NUL
for /F "usebackq tokens=*" %%G in (
`wmic process where "CommandLine like '%%sound.vbs%%' AND Caption like '%%script.exe%%'" get ProcessID/value ^|find /I "="`
) do (
rem echo %%G
for /F "tokens=2 delims==" %%H in ("%%~G") do echo taskkill /T /F /PID %%H
)
Note taskkill command is echoed merely... Remove echo when debugged.
This work for me, and is only one line.
Taskkill /IM "wscript.exe" /F>nul 2>&1