I have been trying to start Steam from inside my Java program.
I have tried this:
StringBuffer output = new StringBuffer();
Process p;
try {
p = Runtime.getRuntime().exec("cmd.exe start \"\" \"C:/Program Files (x86)/Steam/Steam.exe\" -login myid mypassword"); //the string amounts to start "" "C:\Program Files (x86)\Steam\Steam.exe" -login myid mypassword
p.waitFor();
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = "";
while ((line = reader.readLine())!= null) {
output.append(line + "\n");
}
System.out.println(output);
This would do nothing. I don't even get any error. My mouse becomes a loading mouse as if something is loading in the background. But actually nothing happens.
Although, when I try to run commands such as taskkill /F /IM Steam.exe, they work perfectly fine and actually I see Steam closing.
I was able to run it by removing start.
Runtime.getRuntime().exec("cmd.exe \"C:/Program Files (x86)/Steam/Steam.exe\" -login myid mypassword");
Even removing cmd.exe worked as well
Runtime.getRuntime().exec("\"C:/Program Files (x86)/Steam/Steam.exe\" -login myid mypassword");
But I ran into a very little problem, which I will ask some other time. That little problem is that the process won't execute the next instruction unless I close the Steam. I tried to run it with cmd.exe /c flag, but that didn't work either.
Related
I have a bit of a weird situation. I'm writing a Java program to communicate automatically with Transmission on my Raspberry Pi (Linux).
I have the following code (simplified and edited for convenience/security):
String s;
String fullCommand = "transmission-remote -n username:password -a /location/to/file.torrent";
String[] cmd = fullCommand.split(" ");
Process p = Runtime.getRuntime().exec(cmd);
BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
while ((s = br.readLine()) != null) {
System.out.println("line: " + s);
}
p.waitFor();
System.out.println("exit: " + p.exitValue());
p.destroy();
The output I get is "non-existing or invalid torrent file".
If I run the exact same script on the command line, I get success (so the file exists and is valid).
I've read that Runtime.exec() has problems with spaces. Hence the split(" ").
It does not work without it either.
I know Runtime.exec() isn't the same as command line, but is there any way I could get this working?
I have a workaround, but I'd like to do it in one step.
If anyone is interested: the workaround is writing the command to a .sh file, make it executable and run that using Runtime.exec(). This does work.
So for work I would like to automate something for minitab. We get results from our microscope and these need to be put into Minitab. Now I wanted to make a program that does some changes to the text file and then automatically opens minitab with a macro. I have everything working except for the auto opening of the macro with minitab.
I can launch it from cmd manually no problem, so it should be working.
Code can be found below, after compiling and running I get this error
'C:/Program' is not recognized as an internal or external command,
operable program or batch file.
Process finished with exit code 0
Which makes me believe cmd does something like:
cmd.exe,/c,c:/Program,Files/..
instead of
cmd.exe,/c,c:/program files/...
String PathExe = "\"C:/Program Files/Minitab/Minitab 17/Minitab 17/Mtb.exe\"";
String Macro = "\"c:/minitAPP/Import.mtb\"";
ProcessBuilder builder;
builder = new ProcessBuilder("cmd.exe", "/c", PathExe + " " + Macro);
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);
There is no need to use cmd.exe to execute another .exe file. Just execute it directly, without the quotes:
ProcessBuilder builder = new ProcessBuilder(
"C:\\Program Files\\Minitab\\Minitab 17\\Minitab 17\\Mtb.exe",
"c:\\minitAPP\\Import.mtb");
By specifying an entire path as a single argument to ProcessBuilder, you ensure that the operating system will treat it as a single argument, which is the purpose of using quotations marks on a normal command line.
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.
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.