How Can I Make A Command Prompt Hang? - batch-file

Yes, I know you are probably going to complain saying it's a bad thing to do, but I want to do it anyway!
I am creating a batch program and at the end, I need it to hang and not accept user input. I know one method is just creating an infinite loop of:
:pause
pause > nul
goto pause
but I don't think that's a great choice. Although I need it to hang, I need to to be able to be closed via the red 'X' close button at the top of the window.
Any ideas?

This works for me. It redirects < NUL into self to prevent Ctrl+C from breaking, and uses start /b /wait to suppress the "Terminate batch job (Y/N)?" prompts.
#echo off
setlocal
>NUL (echo(%* | findstr "\<hang\>" && waitfor redX)
rem // *** PUT YOUR MAIN SCRIPT HERE ***
echo End of line.
rem // ******* END MAIN SCRIPT *********
call :hang
goto :EOF
:hang
start /b /wait "" "%~f0" hang ^<NUL
On the initial launch of the script, the echo(%* | findstr "\<hang\>" >NUL line looks for a script argument of "hang". If found, the script executes the waitfor command.
Normally, waitfor can be broken with Ctrl+C. But since the usual behavior of Ctrl+C is defeated by start /b and <NUL, the hanging effect is achieved unless a user does Ctrl+Break or sends the answering waitfor signal.
The red X still works, though.

Related

Make a batch file give itself admin privilages and self destruct

I am coding a virus using some BSOD code (I didn't make that part of it) and I want the file to, one started, give itself admin privilages, set the date and time to a certain point, and once the system date and time hit a certain point, self destruct. The problem I'm coming accross is that, the file is stuck on the process of keeping the BSOD on the screen, so it never gets to the self destruct code. Any help would be greatly appreciated. Thanks.
I've tried looping it and putting the code to when the loop reaches a certain point, move on. Didn't work.
#echo off
set loopcount=1
:loop
(
echo ^<html^>^<head^>^<title^>Microsoft Windows^</title^>
echo.
echo ^<hta:application id="oBVC"
echo applicationname="BSOD"
echo version="1.0"
echo maximizebutton="no"
echo minimizebutton="no"
echo sysmenu="no"
echo Caption="no"
echo windowstate="maximize"/^>
(This is the beggining of the code. It should loop once, then self destruct itself)
start "" /wait "bsod.hta"
del /f /q "bsod.hta" > nul
set /a loopcount=loopcount-1
if %loopcount%==0 goto exitloop
goto loop
:exitloop
del "%~f0" & exit
(This is the part where it should have made itself self destruct after the loop happened)
I expected it to loop once, the self destruct, ending all processes. It just stayed on the process of holding up the BSOD
I expected it to loop once, the self destruct, ending all processes.
It just stayed on the process of holding up the BSOD
Your start /wait command will most certainly wait until the hta file has been closed prior to continuing execution of the rest of the batch file. If you wish to have the hta display and continue execution, just remove the /wait
start "bsod.hta"

How to answer automatically (Y/N) when prompt?

My click.bat file:
:main
#start /wait cmd.exe -/c ""C:\Users\MY_USER_NAME\Desktop\2.bat" "
goto :main
My 2.bat file:
#echo off
echo Hello World!
#pause
I am clicking Click.bat and they are both opening (no problem in here).
After that I am closing the Hello World! prompt (2.bat).
and prompt of the Click.bat, ask me ^CTerminate batch job (Y/N)?
I want to auto answer at here (as N).
(When the answer is N, 2.bat opening again like as I want).
I agree with Mofi that addressing the real issue is always better than to work around it, but sometimes this isn't possible or you need a quicker solution.
Instead of passively waiting, until the second process finishes, just actively watch it. If it isn't alive anymore, restart it. That way, it doesn't matter, how the second process finishes/exits/crashes:
test1.bat
#echo off
:main
if exist MyCommand.flag goto :eof
start test2.bat
:wait
timeout 1 >nul
tasklist /fi "Windowtitle eq MyCommand"|find "cmd.exe" >nul || #goto :main
goto :wait
test2.bat
#echo off
title MyCommand
echo Hello World!
#pause
break>MyCommand.flag
You don't have to start cmd /c, because start alone already starts a new cmd process. Give the process a unique title, so you can check, if it is still running.
|| works as "if previous command (find) fails then"
find is neccessary, because tasklist does not provide a helpful errorlevel.
Note: you also need a method to stop, when the second process finishes its task.
Test2.bat writes an empty file when finished. Obviously the file wouldn't be created, when the process crashes before (or is forcefully terminated).
test1.bat simply checks for the existence of the file before restarting the second process.

Goto was unexpected at this time [BATCH]

So basically I was working on my Terminal I am creating in batch and this strange error pops up for a second and then the window closes:
"Goto was unexpected at this time"
I have no idea what's going on. Here's my code:
#ECHO off
set codename=Nature
echo Windows Bat Terminal
echo Codename "%codename%"
:terminal
set /p terminalcommand=Command:
if %terminalcommand%==help goto help
if %terminalcommand%==clr goto clear
if %terminalcommand%==exit goto exit
if %terminalcommand%==color goto color
if %terminalcommand%==time goto timedate
echo.
echo Bad command!
:terminal1
goto terminal`
To recreate simply run this in CMD.
You haven't told us what entry you made to generate this behaviour. The standard cure is to quote each side if the if comparison (if /i "%terminalcommand%"=="time" goto ... (the /i make the comparison case-insensitive)) because if you simply press enter then the command is resolved to "if ==time goto ..." and cmd will see goto where it expects a comparison operator like ==, hence the response. If you run this batch from the command prompt, the window won't close and you'll be able to see these messages better

batch choice command will not work

I have this question about why this choice command won't work. I've looked on this site and compared all my scripting and I just can't figure out why it won't work
http://www.computerhope.com/issues/ch001674.htm
#ECHO OFF
:START
echo 1 to quit or 2 to print hello and go back to this screen
CHOICE /C:12 /N
IF ERRORLEVEL ==1 GOTO QUIT
IF ERRORLEVEL ==2 GOTO HELLO
GOTO :START
:QUIT
EXIT
:HELLO
ECHO hello
GOTO :END
:END
I've made a couple of changes and removed unnecessary code.
#ECHO OFF
:START
CLS
ECHO=1 to quit or 2 to print hello and go back to this screen
CHOICE /C 12 /N
IF ERRORLEVEL 2 (CALL :HELLO & GOTO START)
EXIT /B
:HELLO
ECHO=hello
TIMEOUT 2 1>NUL
Simpler:
#ECHO OFF
:START
echo 1 to quit or 2 to print hello and go back to this screen
CHOICE /C 12 /N
GOTO OPTION-%ERRORLEVEL%
:OPTION-1 Quit
EXIT
:OPTION-2 Hello
ECHO hello
GOTO START
Testing on the errorlevel is done wrong.
There are two possibilities:
#ECHO OFF
:BEGIN
ECHO 1 to quit or 2 to print hello and go back to this screen
CHOICE /C:12 /N
IF ERRORLEVEL 2 GOTO HELLO
IF ERRORLEVEL 1 EXIT /B
GOTO BEGIN
:HELLO
ECHO hello
GOTO BEGIN
For full details see the chapter about CHOICE in my answer on: How to stop Windows command interpreter from quitting batch file execution on an incorrect user input?
The batch user must press either 1 or 2 as otherwise the batch execution is not continued. So testing for the exit code can be done from highest to lowest with:
if errorlevel X ...
That means IF the exit code assigned to the dynamic variable errorlevel is greater OR equal X THEN execute the command (or command block).
The advantage of using this syntax is that it even works in a command block without the need to use delayed variable expansion.
The second possibility is:
#ECHO OFF
:BEGIN
ECHO 1 to quit or 2 to print hello and go back to this screen
CHOICE /C:12 /N
IF %ERRORLEVEL% == 1 EXIT /B
IF %ERRORLEVEL% == 2 GOTO HELLO
GOTO BEGIN
:HELLO
ECHO hello
GOTO BEGIN
By explicitly referencing the dynamic variable ERRORLEVEL, here with expansion before IF evaluates the condition, the order of the errorlevel checks does not matter anymore.
The disadvantage of this method is the need of using delayed expansion if CHOICE and the errorlevel evaluating conditions are within a command block defined with ( ... ).
Run in a command prompt window if /? and set /? for help about right usage of the commands IF and SET respectively get information about delayed variable expansion.
It is possible to use START as label, but it is not advisable to do so because of START is an internal command of Windows command processor. You get troubles on finding START meaning the label and START meaning the command when your batch file will use ever also the command START. BEGIN is used as label for that reason.
It is also advisable to use command EXIT always with parameter /B at least during developing a batch file to exit only the batch processing, but do not completely exit the running command process independent on calling hierarchy and option used on starting cmd.exe.
It is much easier to debug a batch file by running it from within a command prompt window (cmd.exe started with option /K to keep console window open) instead of double clicking on the batch file (cmd.exe started with option /C to close on batch execution finished) on using exit /B instead of just exit as the command prompt window keeps open. Run in a command prompt window cmd /? for details about the options of the Windows Command Processor.
GOTO BEGIN after the two errorlevel evaluations is only executed on user pressing Ctrl+C or Ctrl+Break on this prompt and presses on prompt output by cmd to terminate the batch job the key N. That results in an exit of CHOICE with exit code 0.
It would be better to use %SystemRoot%\System32\choice.exe instead of just CHOICE if the batch file is for Windows Vista or Windows Server 2003 or newer Windows versions with support of Windows command CHOICE.

Check if CTRL-C pressed Or batch wait for agreement

I need to know how can I check in batch file if the second batch file which is opened in other command window has stopped (waiting for argument or process not successful).
#echo off
:loop
start /wait rapidminer-batch.bat -f C:\Users\AHM-PC\Documents\ccc.rmp
echo cmd stopped
pause
goto loop
When called batch ends, it returns a value to errorlevel. It works for call, don't know if for start too.
if %errorlevel% gtr 0 (
echo failed
) else (
echo success)
or call exit /b <number of error> in your called batch, to return specific value. Check exit for more details.
The normal method to provide interbatch communication is a flag file
Either you create a flag file in the main routine and wait for the started routine to delete it or wait until the started batch creates a file, and delete it.
eg
echo.>myflag.txt
start anotherbatch.bat
:loop
timeout /t 1 >nul
if exist myflag.txt goto loop
Here, the batch will wait until myflag.txt is deleted, which you do in the second batch. All you need is for the two routines to agree on a filename to use.

Resources