How to end only a single task using taskkill? - cmd

I have a .bat file that end another .bat file using taskkill but it ends up killing itself and the other .bat file.
So how do I make sure it kills only the oldest .bat file?
Because the 2nd bat file runs after the first
I can't use PID because the PID changes with each run!
taskkill /im cmd.exe
This kills all the cmd procceses including itself! I need it to kill only 1 of the processes. (that's the older 1)

I have ran into this problem before and the way I solved it is:
Have the first script (the file you want to close) looking to see if a temporary file has been made, and if it has, delete the file the close.
:loop
if EXIST %TEMP%\close.tmp (
del %TEMP%\close.tmp
exit
)
other code
goto :loop
And in the second script (the one closing the first script) just make it create the temporary file.
echo do you want to close SCRIPT1?
choice
if %ERRORLEVEL%==1 echo.>%TEMP%\close.tmp
And if you want to, you can make it so the first script runs more commands before it closes.

Related

set batch script for loop to NOT wait for previous iteration to complete

I have the following script which launches multiple sessions of RDP connection files at once (colleted from a folder which only contains rdp files).
If I launch this from cmd prompt, it launches all sessions in parallel (which is what I want)
for /r %i in (*.rdp) do (mstsc %~nxi /f)
**while **if i run this script, it just launches the first session then waits for the relative process to end before running the second connection and so on.
for /r %%i in (*.rdp) do (mstsc %%~nxi /f)
What I'm doing wrong? Shouldn't it be the default behavior of batch to run all commands in parallel?
I've checked this but it doesn't address my exact scenario and it doesn't work anyhow as expected (e.g. START myBatchScript.bat doens't change the "waiting for process" behavior)
EDIT
Added answer based on comments (Thanks to #Compo and #Modi)
The coding solution to replicate the cmd behavior as a batch script is using the "start" command (as below, thanks to #Compo)
#for /r %i in (*.rdp) do #(start "" mstsc "%~nxi" /f)
for the reason why this happens refer to #Mofi comments.

Auto restart batch file upon exit from batch

Currently I have a batch file running:
cd "C:\Users\chriscrutt\Desktop\"
:loop
Start /w yeet.bat
goto loop
This runs "yeet.bat". Sometimes the command prompt will crash but I need it to automatically restart. That is why I used "/w" but it requires me to manually input "N" when it asks: Terminate batch job (Y/N)? Is there a way to make it so it automatically restarts or so it will automatically say "N" to restart it?
This is how it goes. I run the bat file which runs the yeet file which runs the other program. the code for "yeet.bat" is
title ETHBTC
cd "C:\Users\chriscrutt\Google Drive\gekkoETHBTC"
node gekko
When i do "node gekko" it runs the bot.
This code do what you want: each time that yeet.bat ends for any reason it is restarted again "immediately and automatically".
cd "C:\Users\chriscrutt\Desktop\"
:loop
Start yeet.bat | set /P "="
goto loop

Want to execute two commands in windows batch file one by one

I want to send the spool files to printer from spool folder one by one and after processing each file it will be moved to another folder or delete it.
But When I'm trying to run below batch file it directly moves spool files without sending to printer which is due to batch processing.
for %%f in (C:\WINDOWS\system32\spool\PRINTERS\*.SPL) do (
echo %%~nf
start "" E:\spool\xyz\tp.exe "C:\WINDOWS\system32\spool\PRINTERS\%%~nf.SPL" "HP Printer"
move "C:\WINDOWS\system32\spool\PRINTERS\%%~nf.SPL" d:\%%~nf.txt
)
SO need any alternative option without using windows PowerShell.
Thanks in advance.
It is not because of the batch processing. By default batch waits on the termination of a command before moving on. So leaving out the start should do.
The problem is actually the start command. By default start will execute the program as a new process and won't wait for it to finish. Use start /WAIT instead, the /WAIT option will ask it to wait. But as I said earlier, you don't even need start.
Supposing your program exits when it has completed its task, you should do:
for %%f in ("C:\WINDOWS\system32\spool\PRINTERS\*.SPL") do (
echo %%~nf
E:\spool\xyz\tp.exe "%%~ff" "HP Printer"
move "%%~ff" d:\%%~nf.txt
)
In general that should do. But if the program E:\spool\xyz\tp.exe itself starts some kind of background process and exits without waiting for it to terminate, even start /WAIT won't help. As I don't know the program you're using (E:\spool\xyz\tp.exe) I won't be able to help you in that case.
EDIT: Just a little improvement I made in the code: you don't need to specify the whole path to get the file corresponding to the loop variable, %%~ff will do it for you (see this link for others).

Batch file fails on startup, but works when I click it

I have a small problem with my batch script. The idea is simple:
I have an app that checks for updates periodically (checks for one exe file). If it finds one it then downloads it, renames it and puts it in the same directory as the old file. Then the app creates a .bat file and also puts it in the same directory. The contents of .bat file are :
#ECHO OFF
ECHO Waiting while old application closes...
ping 127.0.0.1 -n 5
taskkill /IM myApp.exe /f
ECHO Updating application
move /y myApp_TEMP.exe myApp.exe
START myApp.exe
pause
Before I close my application (myApp.exe) I instruct it to execute the .bat file, ant wait 5 sec. so it will properly close, that’s why the ping 127.0.0.1 -n 5 is here for. So ideally this script should:
Close myApp.exe
Rename myApp_TEMP.exe to myApp.exe
Overwrite old myApp.exe with new myApp.exe
Start myApp.exe
And it works when I double click on the .bat file, the problem occurs when I put myApp.exe in Windows startup list.
So the app start's, downloads update, generates the .bat file (keep in mind that everything is happening in the same directory) and then runs it. After some digging i found out that the line move /y myApp_TEMP.exe myApp.exe is not executing. But when I run this script manually everything works. Maybe someone has already experienced similar issues?
You are using relative paths in your filenames. Check that it's being run with the correct current directory or switch to absolute paths.
I would suggest using a CD /D <directory of the .exe file> before the move, that way you always know for sure you're in the right directory. Also, you can use timeout 5 /NOBREAK to wait for 5 seconds in regular batch-files
Might need to add some redundancy to the script. Such as:
#ECHO OFF
ECHO Waiting while old application closes...
taskkill /IM myApp.exe /f
timeout 5 /nobreak >nul
ECHO Updating application
IF EXIST "%cd%\MyApp_TEMP.exe" move /y myApp_TEMP.exe myApp.exe
IF EXIST "%cd%\MyApp.exe" GOTO STARTAPP
ECHO File not found. Unable to update.
pause
exit
:STARTAPP
START myApp.exe
pause
The problem seems to stem from a problem in directory searching. While this could be solved with a rather long search time, it'd be easier to make sure that the batch is in the same directory as "MyApp_TEMP.exe" or using
cd <path to MyApp_TEMP.exe>
ECHO Updating application
move /y myApp_TEMP.exe myApp.exe
START myApp.exe
pause
You could also use an ELSE if the file is not found, I just Personally prefer to use label jumping with GOTO.

Pausing a batch file when double-clicked but not when run from a console window?

Is there a way for a batch file (in this case, running on Windows XP) to determine whether it was launched from a command line (i.e. inside a console window) or launched via the shell (e.g. by double-clicking)?
I have a script which I'd like to have pause at certain points when run via the shell, but not when run at a command line. I've seen a similar question on SO, but am unable to use the same solution for two reasons: first, whether or not it pauses needs to be dependent on multiple factors, only one of which is whether it was double-clicked. Second, I'll be distributing this script to others on my team and I can't realistically ask all of them to make registry changes which will affect all scripts.
Is this possible?
Found one :-) – After desperately thinking of what cmd might do when run interactively but not when launching a batch file directly ... I finally found one.
The pseudo-variable %cmdcmdline% contains the command line that was used to launch cmd. In case cmd was started normally this contains something akin to the following:
"C:\Windows\System32\cmd.exe"
However, when launching a batch file it looks like this:
cmd /c ""C:\Users\Me\test.cmd" "
Small demo:
#echo off
for %%x in (%cmdcmdline%) do if /i "%%~x"=="/c" set DOUBLECLICKED=1
if defined DOUBLECLICKED pause
This way of checking might not be the most robust, though, but /c should only be present as an argument if a batch file was launched directly.
Tested here on Windows 7 x64. It may or may not work, break, do something weird, eat children (might be a good thing) or bite you in the nose.
A consolidated answer, derived from much of the information found on this page (and some other stack overflow pages with similar questions). This one does not rely on detecting /c, but actually checks for the name of the script in the command line. As a result this solution will not pause if you double-clicked on another batch and then called this one; you had to double-click on this particular batch file.
:pauseIfDoubleClicked
setlocal enabledelayedexpansion
set testl=%cmdcmdline:"=%
set testr=!testl:%~nx0=!
if not "%testl%" == "%testr%" pause
The variable "testl" gets the full line of the cmd processor call, stripping out all of the pesky double quotes.
The variable "testr" takes "testl" and further strips outs the name of the current batch file name if present (which it will be if the batch file was invoked with a double-click).
The if statement sees if "testl" and "testr" are different. If yes, batch was double-clicked, so pause; if no, batch was typed in on command line (or called from another batch file), go on.
Edit: The same can be done in a single line:
echo %cmdcmdline% | findstr /i /c:"%~nx0" && set standalone=1
In plain English, this
pipes the value of %cmdcmdline% to findstr, which then searches for the current script name
%0 contains the current script name, of course only if shift has not been called beforehand
%~nx0 extracts file name and extension from %0
>NUL 2>&1 mutes findstr by redirecting any output to NUL
findstr sets a non-zero errorlevel if it can't find the substring in question
&& only executes if the preceding command returned without error
as a consequence, standalone will not be defined if the script was started from the command line
Later in the script we can do:
if defined standalone pause
One approach might be to create an autoexec.nt file in the root of c:\ that looks something like:
#set nested=%nested%Z
In your batch file, check if %nested% is "Z" - if it is "Z" then you've been double-clicked, so pause. If it's not "Z" - its going to be "ZZ" or "ZZZ" etc as CMD inherits the environment block of the parent process.
-Oisin
A little more information...
I start with a batch-file (test.cmd) that contains:
#echo %cmdcmdline%
If I double-click the "test.cmd" batch-file from within Windows Explorer, the display of echo %cmdcmdline% is:
cmd /c ""D:\Path\test.cmd" "
When executing the "test.cmd" batch-file from within a Command Prompt window, the display of
echo %cmdcmdline% depends on how the command window was started...
If I start "cmd.exe" by clicking the "Start-Orb" and "Command Prompt" or if I click "Start-Orb" and execute "cmd.exe" from the search/run box. Then I execute the "test.cmd" batch-file, the display of echo %cmdcmdline% is:
"C:\Windows\system32\cmd.exe"
Also, for me, if I click "Command Prompt" from the desktop shortcut, then execute the "test.cmd" batch-file, the display of echo %cmdcmdline% is also:
"C:\Windows\system32\cmd.exe"
But, if I "Right-Click" inside a Windows Explorer window and select "Open Command Prompt Here", then execute the "test.cmd" batch-file, the display of echo %cmdcmdline% is:
"C:\Windows\System32\cmd.exe" /k ver
So, just be careful, if you start "cmd.exe" from a shortcut that contains a "/c" in the "Target" field (unlikely), then the test in the previous example will fail to test this case properly.

Resources