Running a batch from Java where the cmd prompt goes away - java

I was able to use an amalgamation of SO questions to get a line of code that would:
Run a batch file from within a Java application
Include an argument located in the same directory as the batch file
The argument & batch file are in a directory unrelated to the JAR/java app
So I used this:
Runtime.getRuntime().exec("cmd /c start batchfile.bat argument.js", null, new File( path ));
This works well except that it leaves the cmd prompt open after it has finished executing the batch file. I've looked around and it seems like having the /c flag should make it close after running, but for me it has been staying open. I tried removing 'start' but this meant that the cmd prompt never opened up at all.
Is it because I'm combining having an argument and using a different path that it's not causing the cmd prompt to open and then close after completion like most examples on SO?

Calling both cmd.exe and start in that order is creating a separate window but it doesn't seem like the command shell is terminating based on what you described. I was able to replicate this behavior in a simple batch script. If you want to leave your Java call as it is, check to make sure your batch script includes an exit statement. Preferably exit based on a success or failure condition within your batch script (i.e.: exit 0 or exit 1, etc...)
:: batchfile.bat
...
exit 0
Assuming you are not firing up any new shells within your batch script or prompting for input, adding an explicit exit to your existing batch script should cause the window to close. You can also try to leave your batch script as is, and as others have suggested in comments, change the order of your command text slightly.
Use this instead
start cmd.exe /c ...
Where you call start first and then call cmd.exe /c after followed by your parameters as needed. I tried both options here and either worked fine to cause the batch window to close as expected.

Pass the below command to Runtime to execute.
taskkill /F /IM (processName)
Runtime.getRuntime().exec("taskkill /F /IM "+pProcessName);

Related

Process.waitFor() returns 0 eventhough batch file being called exits with an errorcode other than 0

I'm starting a process (.bat) in java using java.lang.Process
Runtime.getRuntime().exec("cmd /c start /wait test.bat");
exitCode = process.waitFor();
The .bat process inturn calls .exe file, this .exe returns an exit code !=0 on error cases.
START /W test.exe
EXIT %ERRORLEVEL%
I want to get back the exit code returned from the batch file, but still I get back exitcode=0 always. I referred this but does not help.
Please let me know how can I get back the actual returned exit code from the process.
You are asking Java to launch CMD.EXE with the command start /wait test.bat which starts a second CMD.EXE process. There is EXIT %ERRORLEVEL% in the second CMD.EXE but there is no call in the scriptlet which tells the first CMD.EXE to use the status code as EXIT %ERRORLEVEL%. Thus you don't get the non-zero code of test.bat passed up to first CMD.EXE.
The fix is easy as you don't need to use start /wait, just change the command to avoid second CMD.EXE process and then the EXIT %ERRORLEVEL% of the batch script applies to the only CMD.EXE:
Process process = Runtime.getRuntime().exec("cmd /c test.bat");
Note that Runtime is not a good way to launch sub-processes, use ProcessBuilder instead with cmd passed as String[] not String so that you don't need to escape spaces in parameters.
Heed the warnings of the Process javadoc: failure
to promptly write the input stream or read the output stream of
the process may cause the process to block, or even deadlock. This means you should consume STDERR + STDOUT on different threads, or redirect STDERR to STDOUT, or redirect them to files or inherit IO streams - otherwise you may encounter problems. Many examples shown in StackOverflow won't work correctly.

Command prompt do not close after running batch file which have 'exit' in last line

I am running a batch (ScanProject.bat) file using java by following code
Process p= Runtime.getRuntime().exec("cmd /c start /wait ScanProject.bat "+ BaseProjDir+"\\"+jo.getString("Name")+" "+st.nextToken());
System.out.println("Exit value : "+p.waitFor());
And following is the batch file code :-
%2:
cd %1
ant -f ..\antbuild.xml analyse
exit
Batch file run successfully but problem is command prompt window do not closes automatically and hence Process do not terminated automatically and my program wait for infinite time to complete this process.Please suggest me any technique so that cmd exit after running ant -f ..\antbuild.xml analyse command.
Thanks.
cd /D "Full path of directory" or pushd "Full path of directory" with popd before exit is better to switch the current directory to any directory on any drive (cd and pushd/popd) or even to a network share (just pushd/popd). Run in a command prompt window cd /? and pushd /? for details.
cmd /C starts a new Windows command process with closing the process automatically after last command was executed. Run in a command prompt window cmd /? for details on options of Windows command interpreter.
start is a command to start a new Windows command process or a GUI/hybrid application in a separate process.
So what you do here is starting a new Windows command process which starts a new Windows command process.
Running in a command prompt window start /? outputs the help for this command. start interprets often the first double quoted string as title string for the new command process. This causes often troubles on command lines with at least 1 double quoted string. Therefore usage of start requires often an explicit definition of a title string in double quotes as first argument for start which can be even an empty string, i.e. simply "" as first argument after start.
As it can be read after running exit /? in a command prompt window, this command without /B always exits the current Windows command process immediately. So when ant.exe finished, the command process in which the batch file was processed is definitely terminated.
I'm having no experience on Java development, but in my point of view it should be enough to use the following execution command which does not need a batch file at all.
The Java code line
Process p= Runtime.getRuntime().exec("cmd.exe /C cd /D \"" + jo.getString("Name") + "\" && ant.exe -f ..\\antbuild.xml analyse");
should be enough to
start a new Windows command process,
set the current directory within this command process to the drive and directory specified by jo.getString("Name") which of course must return a directory path with drive letter and using backslashes as directory separators, and on success
execute ant in this directory with the specified parameters
with terminating the Windows command process automatically after console application ant.exe finished if ant.exe is a console application.
I'm not sure if cmd.exe /C is needed at all.
I suggest to test this command first manually from within a command prompt window. Then use it in the Java application if really working and producing the expected result. And finally I would further test if cmd.exe /C is needed at all in Java code.
See Single line with multiple commands using Windows batch file for details about the operator && to run a command after previous command was successful. And see also Why do not all started applications save the wanted information in the text files as expected? for an explanation of console / GUI / hybrid application.
NOTE: There is also Java Runtime method exec(String[] cmdarray, String[] envp, File dir) to execute a command like ant.exe with its parameters -f and ..\antbuild.xml and analyse in the directory defined with third parameter which might be better for this task.
Swap out exit for taskkill, assuming you do not have any other cmd processes running. Not very graceful but it will get the job done.
%2:
cd %1
ant -f ..\antbuild.xml analyse
taskkill /im cmd.exe

How to Make Java Open a Batch File in Same Command Prompt Window

I am trying to make a console-based Java application that starts some batch scripts that do some other irrelevant things. Presently, I just want to find the proof of concept
I have tried to use the following code:
Runtime.getRuntime().exec("cmd /c start pathtomybatch.bat");
This works fine until I turn it into a .jar file and attempt to execute it. Then it opens the batch file in a new command prompt window, which I don't want it to do. I want to open the batch file in the same window that my Java program is running in. I read about the start command on TechNet and SS64 and found out that apparently adding changing start to start /b would open the program in the same command prompt window. However, when I try to run this:
Runtime.getRuntime().exec("cmd /c start /b pathtomybatch.bat");
NetBeans says BUILD SUCCESSFUL for both lines of code, but when I try the second line of code, no command prompt window opens and my batch file doesn't get started.
I want to know how I can make Java open that batch file within the same command prompt window without stopping the Java application or waiting for it to finish.
Also, as a tiny extra request, could someone tell me if I could do the same for an .exe file?
I'm on Windows 7, but I want this app to work for people using Vista or newer.
The extra window is coming from the start command you initiate. See https://www.windows-commandline.com/cmd-start-command/
A better pattern is to use
Process p = Runtime.getRuntime().exec("cmd /c pathtomybatch.bat");
Then make sure you loop until p.exitValue() no longer throws an exception (which means the process has exited), and while looping copy all available bytes from p.getOutputStream() and p.getErrorStream() to System.out and/or System.err.

Get exit code from a java application in batch file

I'm currently making an effort to create test cases for one of our java applications.
In my code, my java application calls a batch file, which in turn starts a separate java process, that returns an error code that I need to consume from the calling java application.
I'm doing the following to invoke my batch file:
Process process = runTime.exec(new String[]{"cmd.exe","/c",scriptPath});
exitValue = process.waitFor();
The batch file is as follows:
#echo off
cd %~dp0
java -cp frames.FrameDriver
SET exitcode=%errorlevel%
exit /B %exitcode%
Now with the above code and batch file, my JUnit framework just hangs on this particular test case, as if it's waiting for it to end. Now when JUnit is hanging on the test case, going to the Task Manager, and ending the java.exe process would allow the JUnit framework to continue with the other cases.
Running the .bat file by double clicking it runs the Java application normally.
Adding the START batch command before the java command in my batch file seems to fix the hanging problem, but I can't seem to get the correct exit code from my Java application as it's always 0. (The Java application exits with an error code using System.exit(INTEGER_VALUE)). I'm assuming that the %errorlevel% value is being overwritten by the "start" command's own exit value.
Can anyone please tell me how to solve this problem?
Thanks.
P.S: If it makes any difference, I'm using JDK 5 and Netbeans 5.5.1.
Don't use the /B on your exit. Here is how I would do a script:
#ECHO off
ECHO Running %~nx0 in %~dp0
CALL :myfunction World
java.exe -cp frames.FrameDriver
IF NOT ERRORLEVEL 0 (
SET exitcode=1
) ELSE (
SET exitcode=0
)
GOTO :END
:myfunction
ECHO Hello %~1
EXIT /B 0
:END
EXIT %exitcode%
NOTE: Also, you can execute java program in 3 different ways:
java.exe -cp frames.FrameDriver
CALL java.exe -cp frames.FrameDriver
cmd.exe /c java.exe -cp frames.FrameDriver
This is very critical since, your Java command may exit with a exit code and in order to pass the exit code correctly to the ERRORLEVEL var, you need to use the correct method above, which I am unsure about.

How to close command windows with Java

Each time I use Runtime.exec("cmd /c start....") I am opening a cmd window. I would like to create a more seamless application by closing each previous cmd window. How can I do this?
If anyone knows of a better way to run a series of commands in the same cmd window rather than opening new ones each time I execute a command, please let me know.
Don't use start, that opens another window
Replace:
Runtime.exec("cmd /c start....")
with:
Runtime.exec("cmd /c ....")
Why do you need cmd windows?
I'd run the command directly in Java and capture the output and display it in a local window (if it's needed at all).
Just make sure you consume all the output from the program or it might stall. Also remember to close the stdout, stderr, and stdin streams or some file handles might leak (well, that's true on some JDKs on some Unix OSes... Windows, who knows).
You cannot control the opened windows from Java. But I suggest two solutions for you:
First:
Runtime.exec("cmd /c start /MIN ...")
The /MIN parameter will prevent windows from appearing.
Second: put all the applications you must call inside the same batch file and call it once. :-)

Categories