I wish to open a file (lets say, a word document) from a Java application using the associated program installed on the computer (in this example, using MS Word or Open Office Writer).
The catch is that I want to wait until this subprocess finishes, which can be done using the waitFor() method in the Process class.
String executable = findAssociatedApplicationPath(); //for example, returns "C:\\Program Files\\Microsoft Office\\Office12\\msword.exe"
Process p = Runtime.getRuntime().exec(executable + " " + filepath);
p.waitFor();
Can someone tell me how to write the findAssociatedApplicationPath() method so it returns the correct executable? Or is there another way to do this?
The proper platform-independant way to open a file using the associated program is Desktop.open(). Unfortunately, it does not offer any way to interact with the resulting process.
If you're willing to lose platform independance, you can use the start command in cmd.exe:
String fileName = "c:\\tmp\\test.doc";
String[] commands = {"cmd", "/c", "start", "\"Title\"",fileName};
Process p = Runtime.getRuntime().exec(commands);
p.waitFor()
There's no pure Java way to do this, because it's necessarily OS-specific. On a Windows platform, the start command is probably what you're looking for (for example, start myfile.txt).
There is no "universal" way to do this across all platforms. On Windows, you can execute "start", which will find the correct associated executable. On the mac, you can execute "open". On Linux, I'm afraid you'll have to map the preferred applications manually as far as I know.
String execName = ("cmd /c \"start " + filename + "\"");
You can try to mess around with the Windows registry and other platform-specific settings, but I think the best solution is to simply have the application have its own preferences setting.
You may want to use the classes in package java.util.prefs for this.
I have figured it out.
Using the cmd.exe + start.exe combo, the method waitFor() will not wait for the subprocess to end.
If doing it without the start option it works like a charm (windows only though):
Process p = Runtime.getRuntime().exec("cmd /c \"" + filename + "\""); //extra quotes for filenames with spaces
p.waitFor()
Related
I need to run executable progam (.exe) in java. This program have two different operating modes: GUI and Command line. The syntax to launch the program from the command line is as follows :
C:\Users\Ermanno\Desktop\ "programFolder"\"program.exe" /stext output.txt
in this way the program store the outoput in the file "output.txt".
I tired it:
Process p = new ProcessBuilder("C:\\Users\\Ermanno\\Desktop\\programFolder\\program.exe" ,"/stext a.txt").start();
does not create the output file.
I also tired to use a file batch that contains the command and run it to java but the result is the same.
You need to pass each argument in a single string:
... program.exe", "/stext", "a.txt")...
Also make sure that you start a background thread which reads the output of the child process. If there is a problem, then the child will print an error message to it's standard output and if you don't actively read it, then this output will be lost.
For this, loop over the streams p.getInputStream() and p.getErrorStream().
The latter is especially important since you say "I also tired to use a file batch". Java doesn't do anything different than a batch script. If you can't run the command from batch, it won't work from Java, either.
My experience was horrible with using the JDK ProcessBuilder and Runtime.getRuntime().exec. I then moved to Apache commons-exec. Here is an example:
String line = "AcroRd32.exe /p /h " + file.getAbsolutePath();
CommandLine cmdLine = CommandLine.parse(line);
DefaultExecutor executor = new DefaultExecutor();
int exitValue = executor.execute(cmdLine);
I solved using file bath. This file contains the command.
String [] _s = {"cmd.exe", "/c", "start", "file.bat"};
Process pr = Runtime.getRuntime().exec(_s);
I am trying to launch a .exe file through a Java program. I used the following code:
System.out.println("Opening " + path);
Process exec;
exec = Runtime.getRuntime().exec("rundll32 SHELL32.DLL,ShellExec_RunDLL " + path);//path is the path of the exe file which is passed as an argument from another java class
the output is as follows:
Opening C:\Program Files (x86)\C-Free 5\CppIDE.exe
But it is not opening.
Instead when I try
String pat="C:\\Program Files (x86)\\C-Free 5\\CppIDE.exe";
Process exec;
exec = Runtime.getRuntime().exec("rundll32 SHELL32.DLL,ShellExec_RunDLL " + pat);
the program is opened.
I don't know what the problem is.
It's very likely that the space in your path is the problem.
I suggest you pass the arguments as an array instead of passing a single string containing the whole command (alternatively you could quote the spaces correctly, but that's not quite as easy).
Either
use the String[] version of Runtime.exec() or
switch to using ProcessBuilder which has an altogether simpler and more intuitive API.
With ProcessBuilder this could look like this:
ProcessBuilder pb = new ProcessBuilder("rundll32", "SHELL32.DLL,ShellExec_RunDLL", path);
Process p = pb.start();
Also, I see no reason to invoke rundll32 at all in this scenario. This should work just as well:
ProcessBuilder pb = new ProcessBuilder(path);
Process p = pb.start();
You need to construct the path using File.separator. The path separator you are using will, in this case, will be system dependant.
I'm having some trouble running gnuplot processes from Java. I'm creating a gnuplot script file, and then running it from within a java program. I've tried using both Process Builder and building a precess using Runtime.getRuntime().exec("blah blah..."), and neither have the full capability to work. The funny thing is is that using Runtime to make the process works almost perfectly, as long as the image file I'm creating via gnuplot isn't being saved to a directory without a space in it's name. ProcessBuilder doesn't work at all, however, and gives me the error: "CreateProcess error=2, The system cannot find the file specified"
It's taken me far too long to figure this stuff out, and so any help would be appreciated.
The code I use is here:
File script = new File("Demo.plt"); //Script file that outputs to a PNG file
//This works as long as the script file doesn't output to a png with a space in it's filepath
Process aProcess = Runtime.getRuntime().exec("gnuplot " + script.toString());
Thread.currentThread().sleep(1000);
aProcess.waitFor();
//This doesn't work at all
ProcessBuilder builder = new ProcessBuilder("gnuplot " + script.toString());
builder.redirectErrorStream(true);
Process process = builder.start();
And I know that the script works if run outside of Java, regardless of the spaces in the output line. I've even tried using '\ ' (the escape character for a space) and that doesn't work either. In fact, here is the code that I use:
String graphName = "DemoGraph";
//Isolate the FilePath
String path = script.getPath();
path = path.replace(script.getName(),"");
path = path.replace(File.separator, "\\\\"); //Gets around any parsing errors in filepaths on Windows
path = path.replace(" ", "\\ "); //Should get around parsing errors with spaces in gnuplot, but it seems to be irrelevant.
scriptFileWriter.write("set output \"" + path + graphName + ".png\"\r\n");
It's got to be an issue with java, because the scripts run from the Windows command line, and from the gnuplot command line, and frun being run by double-clicking the
I forgot to put quotes around the file name. It was a STUPID error.
Am trying to execute the a bat file with some arguments through a JAVA programmes . the arguments are file name with full path, And this path had some folder name with space, which are creating issue and giving me the following error
Error: 'D:\Documents' is not recognized as an internal or external
command
the code is as below
String command = "D:\Documents and Settings\ A.bat" + " " D:\Documents and Settings\B.xml
1. process = Runtime.getRuntime().exec(new String[] {"cmd.exe","/c",command});
2. process.waitFor();
3. exitValue = process.exitValue();
You need to escape the \ in your string (i.e. doubling them: D:\\Documents), but that is not the problem. You can try to escape the spaces Documents\\ and\\ Settings or you use the exec method that does this for you. Just dont build the command line by yourself. Better use ProcessBuilder for starting processes.
String command = "\"D:\Documents and Settings\\" A.bat" + " \"D:\Documents and Settings\B.xml\""
Escape double quotes, so you can include double quotes in the literal, to give:
cmd.exe /x "D:\Documents and Settings\" A.bat "D:\Documents and Settings\B.xml"
I was trying to do the same thing. I googled whole day but didn't make it work. At Last I handled it in this way, I am sharing it if it comes to any use of anybody :
String command = "A.bat D:\\Documents and Settings\\B.xml";
File commandDir = new File ( "D:\\Documents and Settings ");
String[] cmdArray = { "cmd.exe", "/c", command };
1. Process process = Runtime.getRuntime().exec( cmdArray, null, cmdArray );
2. process.waitFor();
3. exitValue = process.exitValue();
I've spent a while searching on SO and the wider Internet and was about to post this as a new question when I came across this, which does seem identical to my issue...
I am trying to call a Windows batch file from Java. The batch file takes several arguments but just the first, which is a path to a data file, is of relevance to this problem. The cut-down command line that I have been experimenting with is essentially:
cmd /c c:\path\to\my\batchfile.bat c:\path\to\my\datafile.mdl
I'm using Apache Commons Exec which ultimately delegates to Runtime.getRuntime().exec(String[] cmdarray, String[] envp, File dir), the 'correct' version as opposed to the overloaded versions taking a single String command. Quoting of the arguments when they contain spaces is therefore taken care of.
Now, both the path to the batch file and/or the path to the data file can have spaces in them. If either the path to the batch file or the path to the data file have spaces in, then the batch file is executed. But if both have spaces in them then the path to the batch file is truncated at the first space.
This has to be a (Java or Windows?) bug, right? I've debugged right down to the native call to create() in java.lang.ProcessImpl and all seems ok. I'm on JDK1.6.
I´m using Mac OS Lion, with java version 1.6.0_26
I'm making a small app for Mac in Java with a main menu for the user, so he can choose several options.
One of them is install an app using a .pkg
Everything was working fine with these commands:
File instFolder = new File(System.getProperty("user.dir") + "/foldername/appInstaller.pkg");
String s = "open "+ instFolder.toString();
Process p = Runtime.getRuntime().exec(s);
Then I realized that there is a problem when foldername has spaces or if I copy this java file with the needed subfolders to a USB pen drive with "NO NAME" as name (or some name with spaces).
Because s will become something like:
open /Volumes/NO NAME/foldername/appInstaller.pkg
or
open /Users/user1/Desktop/folder name/appInstaller.pkg
So when you run the p process, the command will finish where the first space appears on the path
open /Volumes/NO
or
open /Users/user1/Desktop/folder
To try to fix this I changed the s definition for something like this:
String s = "open "+ "\"" + instFolder.toString() + "\"";
It stopped working fine. The strange thing is that if i copy the s value (after creating the s variable) and paste it in the terminal it works:
open "/Users/user1/Desktop/folder name/appInstaller.pkg"
but running it from Java it does't work.
Could you help me, please?
Thanks.
In order to properly escape arguments, you can use the following:
Runtime.getRuntime().exec(new String[] { "open", instFolder.toString() });
Though I would probably to use the more modern ProcessBuilder:
ProcessBuilder pb = new ProcessBuilder("open", instFolder.toString());
Process p = pb.start();
int exitCode = p.waitFor();
Though this may be worth a read depending on what you want to do with the processes output.
Note: edited to reflect question in comment
it seems your path does not have quotes when turned into the shell.
You should probably add "'" on both sides of your path, so the final shell command will look like:
open 'your path'
instead of
open your path
Here's a little trick that came out from the answers mentioned above:
ProcessBuilder pb = new ProcessBuilder(commandString.split(" "));
Say commandString = "killall Mail" then the split will separate the words making it a String[] parameter to the ProcessBuilder.