I want to start a process in a CMD window with Java, and the easiest way to do that is by
Runtime.getRuntime().exec("cmd /c start program.exe")
The problem is that now I can't get the input from the process. How can I get the output from the process and be able to run it in a separate CMD window?
Your problem is that start is a separate command whose purpose is to launch a completely new process unrelated to the cmd that invokes start. Whatever start then executes is not connected to the original cmd and cannot be accessed by your Java program.
If you need to access the subprocess' in/out/err streams, do not use start.
Hey bro if you want to println the output process of your process use this
Process process= Runtime.getRuntime().exec("cmd /c start program.exe");
BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line = null;
while ((line = br.readLine()) != null) {
line = br.readLine();
System.out.println(line);
}
with this you will get each output process exactly the same with cmd output.
if you want to process 2 cmd maybe you can make 2 process with different exec
Process process1 = Runtime.getRuntime().exec("cmd /c start program1.exe");
Process process2 = Runtime.getRuntime().exec("cmd /c start program2.exe");
if you want this run with same thread please read java books about thread, you can run it at the same time with thread.
Related
Hi friends I want to open cmd on server.I have a java code on my local machine that run a batch file(Run.bat) on server the code runs successfully but does't open a cmd.exe on server, but whenever I go to server and double click on my batch file on server it's open a cmd.
Thanks in advance.
java code:
ProcessBuilder builder = new ProcessBuilder("cmd.exe", "/c",
"F:\\Softwares\\PsTool\\PsExec.exe \\\\aa.aa.aa.aa -u Administrator -p 1234 \"c:\\batch\\Run.bat\"");
builder.redirectErrorStream(true);
Process p = builder.start();
BufferedReader r = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line;
while (true) {
line = r.readLine();
if (line == null) {
break;
}
System.out.println(line);
}
Run.bat:
start cmd
Pretty simple. As the docs state:
By default, the subprocess writes standard output and standard error to pipes. Java code can access these pipes via the input streams returned by Process.getInputStream() and Process.getErrorStream(). However, standard output and standard error may be redirected to other destinations using redirectOutput and redirectError.
Simplified: the ProcessBuilder doesn't generate any Console-Windows, but instead simply redirects output from any command to a pipe that can be read from the javaapp.
I have run an external tool through exce() function in a separate command line console.
command = "cmd.exe /c start /min doxygen " + strDoxyfilePath;
System.out.println("command : " + command);
//pass the command to execute
Process p=Runtime.getRuntime().exec(command);
I used this for read input stream:
BufferedReader br = new BufferedReader(new InputStreamReader
(p.getInputStream(), "UTF-8")); //read output of doxygen
String line = null;
while ((line = br.readLine()) != null){
System.out.println("I M HERE: "+line);
}
But control doesn't go inside while loop and I want to get proper signal at the process end.
I think it is because of the start in your command. You are probably doing it to avoid a cmd window but I think you cannot not interact with the program then.
Try
command = "cmd.exe /c doxygen " + strDoxyfilePath;
Also, note that
You also need to read the stderr (p.getErrrorStream())
Runtime.exec is not a great way to start a child process. ProcessBuilder is the newer and better way to do it.
I think the classic When Runtime.exec() won't still explains it best.
I have a command line tool that queries a server and prints the status of pending jobs to run. This can take up to 30 seconds. I need to call this tool from java and I want to show its output in a text area on my GUI. For the purposes of example, lets say the command is "dir" in windows.
Process.getRuntime().exec("cmd /c dir"); blocks until the command finishes executing, so I thought it would be best to show the command executing in the terminal, then read the output and show it in my text area for future reference. However, the console is hidden giving the user the impression that the application has stopped working. After much research, I have tried:
cmd /k dir - runs in the background and can read output, but application hangs as it requires the /k switch means to keep the window open, but I can't see it to close it.
cmd /c start dir - opens in a new visible terminal, runs but doesn't close. Closing manually doesn't allow me to read the output
cmd /k start dir - same result as above
My question is, how can I spawn a command to run, see it running, and access its output?
Process proc = null;
String[] cmd = { "cmd", "/c", "dir" };
proc = Runtime.getRuntime().exec(cmd);
InputStream inputStream = proc.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
String line;
while ((line = bufferedReader.readLine()) != null)
{
System.out.println(line);
}
You can grab its input / output / error stream using the process methods. but you need to get the process object - Process p = Process.getRuntime().exec("cmd /c dir"); see this answer also.
Is it possible to open the command prompt (and I guess any other terminal for other systems), and execute commands in the newly opened window?
Currently what I have is this:
Runtime rt = Runtime.getRuntime();
rt.exec(new String[]{"cmd.exe","/c","start"});
I've tried adding the next command after the "start", I've tried running another rt.exec containing my command, but I can't find a way to make it work.
If it matters, I'm trying to run a command similar to this:
java -flag -flag -cp terminal-based-program.jar
EDIT Unfortunately I have had some strange findings. I've been able to successfully launch the command prompt and pass a command using this:
rt.exec("cmd.exe /c start command");
However, it only seems to work with one command. Because, if I try to use the command separator like this, "cmd.exe /c start command&command2", the second command is passed through the background (the way it would if I just used rt.exec("command2");). Now the problem here is, I realized that I need to change the directory the command prompt is running in, because if I just use the full path to the jar file, the jar file incorrectly reads the data from the command prompt's active directory, not the jar's directory which contains its resources.
I know that people recommend staying away from rt.exec(String), but this works, and I don't know how to change it into the array version.
rt.exec("cmd.exe /c cd \""+new_dir+"\" & start cmd.exe /k \"java -flag -flag -cp terminal-based-program.jar\"");
If you are running two commands at once just to change the directory the command prompt runs in, there is an overload for the Runtime.exec method that lets you specify the current working directory. Like,
Runtime rt = Runtime.getRuntime();
rt.exec("cmd.exe /c start command", null, new File(newDir));
This will open command prompt in the directory at newDir. I think your solution works as well, but this keeps your command string or array a little cleaner.
There is an overload for having the command as a string and having the command as a String array.
You may find it even easier, though, to use the ProcessBuilder, which has a directory method to set your current working directory.
Hope this helps.
public static void main(String[] args) {
try {
String ss = null;
Process p = Runtime.getRuntime().exec("cmd.exe /c start dir ");
BufferedWriter writeer = new BufferedWriter(new OutputStreamWriter(p.getOutputStream()));
writeer.write("dir");
writeer.flush();
BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
BufferedReader stdError = new BufferedReader(new InputStreamReader(p.getErrorStream()));
System.out.println("Here is the standard output of the command:\n");
while ((ss = stdInput.readLine()) != null) {
System.out.println(ss);
}
System.out.println("Here is the standard error of the command (if any):\n");
while ((ss = stdError.readLine()) != null) {
System.out.println(ss);
}
} catch (IOException e) {
System.out.println("FROM CATCH" + e.toString());
}
}
The following works for me on Snow Leopard:
Runtime rt = Runtime.getRuntime();
String[] testArgs = {"touch", "TEST"};
rt.exec(testArgs);
Thing is, if you want to read the output of that command, you need to read the input stream of the process. For instance,
Process pr = rt.exec(arguments);
BufferedReader r = new BufferedReader(new InputStreamReader(pr.getInputStream()));
Allows you to read the line-by-line output of the command pretty easily.
The problem might also be that MS-DOS does not interpret your order of arguments to mean "start a new command prompt". Your array should probably be:
{"start", "cmd.exe", "\c"}
To open commands in the new command prompt, you'd have to use the Process reference. But I'm not sure why you'd want to do that when you can just use exec, as the person before me commented.
You just need to append your command after start in the string that you are passing.
String command = "cmd.exe /c start "+"*your command*";
Process child = Runtime.getRuntime().exec(command);
String[] command = {"cmd.exe" , "/c", "start" , "cmd.exe" , "/k" , "\" dir && ipconfig
\"" };
ProcessBuilder probuilder = new ProcessBuilder( command );
probuilder.directory(new File("D:\\Folder1"));
Process process = probuilder.start();
You can use any on process for dynamic path on command prompt
Process p = Runtime.getRuntime().exec("cmd.exe /c start dir ");
Process p = Runtime.getRuntime().exec("cmd.exe /c start cd \"E:\\rakhee\\Obligation Extractions\" && dir");
Process p = Runtime.getRuntime().exec("cmd.exe /c start cd \"E:\\oxyzen-workspace\\BrightleafDesktop\\Obligation Extractions\" && dir");
Please, place your command in a parameter like the mentioned below.
Runtime.getRuntime().exec("cmd.exe /c start cmd /k \" parameter \"");
You have to set all \" (quotes) carefully. The parameter \k is used to leave the command prompt open after the execution.
1) to combine 2 commands use (for example pause and ipconfig)
Runtime.getRuntime()
.exec("cmd /c start cmd.exe /k \"pause && ipconfig\"", null, selectedFile.getParentFile());
2) to show the content of a file use (MORE is a command line viewer on Windows)
File selectedFile = new File(pathToFile):
Runtime.getRuntime()
.exec("cmd /c start cmd.exe /k \"MORE \"" + selectedFile.getName() + "\"\"", null, selectedFile.getParentFile());
One nesting quote \" is for the command and the file name, the second quote \" is for the filename itself, for spaces etc. in the name particularly.
I am trying to execute a program from the Java code. Here is my code:
public static void main(String argv[]) {
try {
String line;
Process p = Runtime.getRuntime().exec(new String[]{
"/bin/bash", "-c", "executable -o filename.txt"});
BufferedReader input = new BufferedReader(
new InputStreamReader(p.getInputStream()));
while ((line = input.readLine()) != null) {
System.out.println(line);
}
input.close();
} catch (Exception err) {
err.printStackTrace();
}
}
My OS is Mac OS X 10.6.
Now, the executable I am trying to run is supposed to spit the output to filename.txt. If I take this command and run it on the terminal, it works fine and the filename.txt gets populated also. But, from my java program the file is not created.
if instead I use executable > filename.txt then the filename.txt is created but is empty. Not sure what's wrong here. The executable I am trying to run is Xtide (if that helps).
I would really appreciate any help I can get.
Thanks,
You cannot redirect output to file and read the output in java. It's one or the other. What you want is this:
Process p = Runtime.getRuntime().exec(new String[]{
"/bin/bash", "-c", "executable -o filename.txt"});
p.waitFor();
BufferedReader input = new BufferedReader(
new InputStreamReader(new FileInputStream("filename.txt")));
while ((line = input.readLine()) != null) {
System.out.println(line);
}
The main changes are:
p.waitFor(), since process execution is asynchronous, so you have to wait for it to complete.
The data is read from the file rather than from the output of the process (since this will be empty.)
The answer from mdma works (and I voted it up), but you might also want to consider the version where you do read the output stream directly from executable:
Process p = Runtime.getRuntime().exec(new String[]{
"/bin/bash", "-c", "executable"});
p.waitFor();
BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream())_;
while ((line = input.readLine()) != null) {
System.out.println(line);
}
Correct me if I am wrong, but the symptoms are as follows:
exec("/usr/bash", "-c", "executable > filename.txt") creates an empty file.
exec("/usr/bash", "-c", "executable -o filename.txt") does not create a file.
One or both of the above gives an exit code of 255 when you look at it.
When you run the command from the command line as executable -o filename.txt or executable > filename.txt it works as expected.
In the light of the above, I think that the most likely cause is that /bin/bash is not finding the executable when you launch it from Java. The fact that the first example does create an empty file means that /bin/bash is doing something. But if you try to run
$ unknown-command > somefile.txt
from a bash shell prompt you will get an error message saying that the command cannot be found and an empty "something.txt" file. (You would not see the error message in your Java app because it is being written to stderr, and you are not capturing it.) The reason that the empty "something.txt" file is created is that it is opened by the shell before it attempts to fork and exec the "executable".
If this is the problem, then the simple solution is to use the absolute pathname for the executable.
Also, if you are not doing any command line redirection or other shell magic, there is no need to run the executable in a new bash instance. Rather, just do this:
Process p = Runtime.getRuntime().exec("executable", "-o", filename.txt");
then wait for the process to complete and check the exit code before trying to read the file contents.