How to close Windows console automatically (send CTRL+C to console programatically)? - windows

I have two windows batch scripts, script1.bat and script2.bat. script2.bat is launched from script1.bat.
script1.bat:
...
start call script2.bat
...
script2.bat has to be closed when user closes script1.bat's console (in another words, script2.bat and its console should be closed automatically when script1.bat is closed). But script2.bat should not be killed, It should be terminated because script2.bat has to release database connection. I mean unix signal teminology by using kill and terminate words. So scrip2.bat should not be killed immediately, it should be terminated in way that allows the process to perform nice termination releasing resources and saving state if appropriate.
I made it for unix system and I resolved it as following.
script1.sh:
...
sh script2.sh > /dev/null 2>&1 &
script2_pid="$!"
trap 'kill -15 $script2_pid' EXIT HUP TERM INT KILL
...
How to make it on Windows?
====EDIT====
I think that my question is not entirely clear for everyone so I would like to clarify it.
I have java application which connects to JBoss application server. It is tested now and I need to launch both in very convenient way. I prepared batch script (script1.bat)which starts both, client application and JBoss application. This script also do another things like setting environment variables. So script2.bat is a Jboss standalone.bat file in fact. I wouldn't like to edit this file.
script1.bat is my script, it sets environment variables, start JBoss and start my java application.
My script (script1.bat):
...
set environment variable
...
REM start jboss
start standalone.bat
REM start my java application
java ...
When user closes Java application, JBoss should also be closed. I need it only for tester's convenient and I know that in production environmnet it should work in another way.
I don't know how to terminate JBoss automatically after user closes my java client application. JBoss connects to H2 database and creates lock on it so if JBoss will be killed immediately then database lock is still there. If JBoss process receives CTRL+C it terminates properly (removes database lock). I want to make it automatically, After user closes java client application, JBoss has to be closed as it receives CTRL+C.
I have no idea how to do it on Windows. But I did it on linux and I added my code to this question.

Sorry, but your script makes no sense. start call script2.bat?? The combination of start and call is nonsense. You use either one or the other but not both.
Further I have to disappiont you. There is no way to close a console but keep the code running. You can't even start a hidden console in Windows. Closing the console will instantly stop the execution of the code.
EDIT:
Now I understand what you are asking. Start your first script using
start "somename" script1.bat
This will start script1 in a console with "somename" as window title.
In the second script you can use this:
:WORKING
REM Do some stuff here
REM and here
REM and here
FOR /f "tokens=*" %%A IN ('tasklist^ /v^| findstr /i /c:"somename"') DO GOTO WORKING
REM shutdown part
REM close db connections
REM exit script2
This part will check if the a console with "somename" in the title is running and if yes reenter the loop. At the end of the loop it alway checks whether script1 is still active. As soon as it's not found the code goes on to the shutdown part.
If you only want to wait for script1 to terminate you can use PING -n 5 127.0.0.1 > NUL as a 5 (or longer, just replace the 5 ^^) second timeout to avoid busy-waiting:
:WORKING
PING -n 5 127.0.0.1 > NUL
FOR /f "tokens=*" %%A IN ('tasklist^ /v^| findstr /i /c:"somename"') DO GOTO WORKING
REM shutdown part
REM close db connections etc.
REM exit script2

If CLI is enabled in JBoss then JBoss can be shutdowned by CLI. Following batch shows how to shutdown JBoss
...
set environment variable
...
REM start jboss
start "UNIQUE_NAME" path_to_JBoss\bin\standalone.bat -c standalone.xml
REM start java application
java ...
REM shutdown JBoss by CLI
call path_to_JBoss\bin\jboss-cli.bat --connect ":shutdown"
REM it is just in case. If CLI did not shutdown JBoss, then following line kills JBoss without release of resource.
FOR /f "TOKENS=1,2,*" %%a IN ('tasklist^ /FI "WINDOWTITLE eq UNIQUE_NAME*" /nh') DO taskkill /pid %%b

Related

Stuck in cmd script loop

I'm using a script that, upon logging in, loads Remote Desktop Protocol (RDP) and pushes the user to a Virtual Desktop Environment (VDI), along with their credentials. The script does not allow the next command 'Shutdown /l' to run until it is finished running.
The problem I'm having is that once in the VDI, RDP tries to load up again. How do I prevent this from happening? Thank you in advanced.
start /wait \\ph-vda\C$\VDI_Users_RDP\%username%.rdp /multimon /noConsentPrompt
Shutdown /l
I think what you're describing is that the same script is running when the user logs in, even when they log into the VDI. You don't want the script to run in the VDI. If that's right, here's one idea.
#echo off
if exist "%userprofile%\in_vdi" goto :eof
type nul >"%userprofile%\in_vdi"
start /wait \\ph-vda\C$\VDI_Users_RDP\%username%.rdp /multimon /noConsentPrompt
del "%userprofile%\in_vdi"
Shutdown /l

Batch script pauses on exception, possible to continue automatically?

I have the following snippet in a batch file to run a program with an argument in a loop:
for /F "tokens=*" %%a in (some-list.txt) do (
java -jar some-java-package.jar com.example.package.class %%a
)
Sometimes the Java application crashes on a memory exception (this could be an important point, because according to my current programming experience these seem to be special exceptions and I was not able to catch them like I would catch normal exceptions in program code).
In such a case it seems my batch script pauses until I take action: I can press Ctrl-C and on batch's question if I want to stop the batch job respond N, then it will continue with the next program call.
Is it possible to tell batch to go on in such events automatically?
You should call java using the start command like this:
for /F "tokens=*" %%a in (some-list.txt) do (
start "" /WAIT "java" -jar some-java-package.jar com.example.package.class %%a
)
The /WAIT switch lets start wait until the application (java) has finished execution.
The "" portion defines the window title (this is defined here since start sometimes confuses it with the command line when no title given).

Need auto-restart script in batch for minecraft server

I am currently an administrator on a private Minecraft server, though in this case the technical question lies outside the scope of typical minecraft supoort.
I wish to have the batch file that launches the server restart at 12 am and 12 pm, though I have little experience in batch and a cursory google search brings up nothing helpful.
The issue I run into is both that I have no idea if batch CAN execute commands within a java server console, send the commands to save the server and then exit, and restart itself, due to only knowing basic batch functions.
More specifically, I want the batch file itself to run a command in the server window after either 43200 seconds or on each of the 12s, then restart itself. I do not know how to get a batch file to run a command within the server command line, or if it's even possible.
The current batch code is as follows:
#echo off
:Minecraft
echo (%time%) Minecraft started.
java -Xms2048m -Xmx2048m -XX:PermSize=128m -jar FTBServer-1.6.4-965.jar nogui
pause
echo (%time%) WARNING: Minecraft closed or crashed, restarting.
ping 1.1.1.1 -n 1 -w 3000 >nul
goto Minecraft
Any help would be aprreciated. Thanks.
i use this but if you want it to restart it automatically then just delete the :choise part and make a loop from start to restart
#echo off
title minecraft-server-1.8.3
color 0A
prompt [server]:
cls
:start
echo loading server...
java -Xms3G -Xmx3G -jar minecraft_server.1.8.3.jar nogui
cls
:choice
set /P a=do you want to restart[Y/N]?
if /I "%a%" EQU "Y" goto :restart
if /I "%a%" EQU "N" goto :stop
goto :choice
:restart
cls
echo server will restart
TIMEOUT /T 5
cls
goto :start
:stop
cls
echo closing server
TIMEOUT /T 5
exit
ps. replace minecraft_server.1.8.3.jar with the name of your server file
Solution 1:
I would suggest to use the windows task scheduler instead of a batch file. There you can create a task, schedule it to be triggered at 12am/pm and insert any cmd command you want to be executed. However, it's non-trivial to cummunicate with the server console without knowing the specific interface or how to administrate a minecraft server. What you can do is simply kill the server and restart it using the command line.
Solution 2:
If you don't like this solution and don't know how to communicate with the server console you can try this:
Take a look at AutoIt (https://www.autoitscript.com/site/). It's a VERY simple script language which also can simulate click and input from the keyboard. So you can write a script that sets the focus to your server console and types the desired command to restart the server. This AutoIt script can be compiled to an exe file or you can run it as an au3 script.
You should still use the task scheduler to run your exe/script at 12am/pm.
If you need some help writing the AutoIt script I can help you with that.
I wrote a similar program for a friend in AutoIt here is the script i commented the lines you need to config:
HotKeySet("{ESC}", end)
HotKeySet("{F1}", start) ;optional
HotKeySet("{F2}", pause) ;optional
pause() ; starts the pause loop when started
; restarts the server all 12 hours
Func start()
$Path = "PathToYourBatch.bat" ; self explained
While 1
If #HOUR = 00 Or #HOUR = 12 Then ;starts the server at 00 and 12
Run($Path)
EndIf
WEnd
EndFunc
Func pause()
While 1
Sleep(500) ; waits 500 ms to reduce lag
WEnd
EndFunc
Func end()
Exit
EndFunc
You dont need to use the hotkeys but you could easily control the program with them(remote desktop)
You can use a online compiler like (http://www.script-example.com/themen/AutoIT-Online-Compiler.php) or download it from (https://www.autoitscript.com/site/) hope i could help if any further questions with the code ask me.

taskkill: different behaviour console vs. script

I am writing a small shutdown script for a java application. I get the pid and then try to do the following:
taskkill /t /pid !pid!
If I am running the command from the console (typing it by hand) everything works fine. I see the shutdown routine being executed in the java console and afterwards the java console is gone. I sometimes see the windows "process not responding. kill now or wait" dialog after a few seconds but the dialog is automatically closed when the java program stops.
If i execute a bat file with the same command I immediately see the "Process not responding..." dialog. I see the console output: "process was successfully shut down" but the java console is still open. It didn't even initiate the shutdown sequence.
edit: the complete batch script
#echo off
setlocal enabledelayedexpansion
if exist .\lock (
set /p pid=< lock
taskkill /t /pid !pid!
)
On the command line !pid! will normally not expanded, as delayed expansion is disabled and can only be enabled by the registry ey or with cmd /V:on.
So at the command line !pid! will stay unchanged and in the batch it will be expanded to the content of the pid variable.
Edit
As you show the correct command on the cmd line, the command in the batch must be wrong.
You should add an echo after the set/p line
Echo pid="!pid!"

Stop a Windows Service that is dependant on another service via Batch File

All,
I'm trying to stop a Windows service that we have created that is dependant on another service. I just want to stop both of the service using a batch file, sc command for example, where the services are running on a remote machine.
I have tried stopping the services in the order of dependancy (least dependant first), but it does not stop the service.
For example Service1 depends upon Service2 which is configured within the Service settings in the Services console. I am running the script on my Windows 7 PC and the server runs Windows Server 2003.
The following lines are in the noddy batch file I created:
sc \\SERVER stop "Service1"
sc \\SERVER stop "Service2"
The output in the Command Console is:
D:\Test>sc \\SERVER stop "Service2"
[SC] ControlService FAILED 1051:
A stop control has been sent to a service that other running services are dependent on.
The service Service2 will not stop. Service1 stops fine.
Any ideas?
Thanks,
Andez
The "net stop" command has a parameter which is not commented. This parameter is /yes and will automatically stop all the dependent services too
So to stop a service with or without dependencies you just type
net stop spooler /yes
You can check which dependencies a service has by running sc qc <service>
And in order to script that and retrieve the dependencies you can put it in a for-loop
Example:
#echo off
setlocal enabledelayedexpansion
set service=winmgmt
set server=server
for /f "Tokens=2 Delims=:" %%i in ('sc \\%server% qc %service% ^| find /i "DEPENDENCIES"') do (
set depservice=%%i
rem removes spaces
set depservice=!depservice: =!
sc \\%server% stop "!depservice!"
rem extra: accumulate all dependencies to one variable
set alldeps=!alldeps!, !depservice!
rem remove first ", " in variable
set alldeps=!alldeps=~2!
)
sc \\%server% stop "%service%" && echo Both %service% and !alldeps! were stopped || echo Something went wrong stopping %service%
exit /b
The above will only work if the service that you want to stop only has one dependency.
To anyone experiencing similar problems:
It's important to remember that the SC command is asynchronous. The following may help:
Halt batch file until service stop is complete?
Niklas batch file doesn't work for me.
It appears that on Windows Server 2008 R2, the qc command shows the services that this service depends on. They are not relevant at this point, you can stop the service without causing a ripple in their life.
What you actually want are the services that depend on the service being killed. You get those with the EnumDepend command to sc.exe.
Unfortunately, the output syntax is quite a bit different, so you'll need to preserve the logic shown above but replace the parsing.

Resources