Running a command-line operation from within Java - java

I built a very simple program to test running a command line operation separate of Java. That is: later I want to be able to modify this code from using "move" to any other command I can enter into the command line (including calling other, non-Java, software).
I did search and read probably two dozen answers, but they all either suggested I was trying this correctly, were irrelevent to my simple test or proposed other solutions which did not work (like using the .exec(String[]) method instead of .exec(String) - same result!).
Here is my code:
import java.io.IOException;
public class RunCommand {
private static final String PATH_OUT = "C:\\Users\\me\\Desktop\\Temp\\out\\";
private static final String FILE = "sample.txt";
private static final String PATH_IN = "C:\\Users\\me\\Desktop\\Temp\\in\\";
public static void main(String[] args) {
try {
String command = "move "+PATH_IN+FILE+" "+PATH_OUT;
System.out.println("Command: "+command);
Runtime.getRuntime().exec(command);
} catch (IOException e) {
e.printStackTrace();
}
}
}
Here is what I see output when I run:
Command: move C:\Users\myingling\Desktop\CDS\Temp\in\sample.txt C:\Users\myingling\Desktop\CDS\Temp\out\
java.io.IOException: Cannot run program "move": CreateProcess error=2, The system cannot find the file specified
at java.lang.ProcessBuilder.start(Unknown Source)
at java.lang.Runtime.exec(Unknown Source)
at java.lang.Runtime.exec(Unknown Source)
at java.lang.Runtime.exec(Unknown Source)
at RunCommand.main(RunCommand.java:13)
Caused by: java.io.IOException: CreateProcess error=2, The system cannot find the file specified
at java.lang.ProcessImpl.create(Native Method)
at java.lang.ProcessImpl.<init>(Unknown Source)
at java.lang.ProcessImpl.start(Unknown Source)
... 5 more
Note that when I copy/paste the command into a command prompt window, the file moves successfully though.
What am I missing? All the other questions I've read seem to indicate this should work.
Thanks!
EDIT Works now, thanks for the help everyone! It's annoying that it's hidden the way "move" is a parameter of cmd.exe. I wish they had made it so if it worked when copy/pasted it worked when you called the .exec() method. Oh well.

The "move" command is part of the cmd.exe interpreter, and not a executable by itself.
This would work:
cmd.exe /c move file1 file2

Try this:
Runtime.getRuntime().exec("cmd.exe /c move "+PATH_IN+FILE+" "+PATH_OUT);

In Windows, unlike UNIX, move isn't a separate program. You need to involke the command processor CMD with move as an argument. Read the command line help on CMD, there's a flag you have to set.

move isn't actually a program, its a shell built-in command. Use something like:
String command = PATH_TO_SYSTEM32 + "\\cmd.exe /c move \""+PATH_IN+FILE+"\" \""+PATH_OUT + "\"";
Good practice is to always use absolute paths for external programs. (Well, good practice in this case would be to use Files.move or an equivalent instead of a platform dependent shell call)

Related

error with starting cmd in windows using java?

The following method starts the cmd in Windows and it takes a parameter of the command which need to be run.
I have tested this method using the following commands: net users and it worked fine and it printed the users accounts. but if I run the dir command I get the following error:
java.io.IOEXception:
Cannot run program "dir": CreateProcess error=2, The system cannot find the file specified (in java.lang.ProcessBuilder)
Code :
private String commandOutPut;
public void startCommandLine(String s) throws IOException{
Runtime runtime = Runtime.getRuntime();
Process process = runtime.exec(s); // you might need the full path
InputStream is = process.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String commandOutPut;
while ((commandOutPut = br.readLine()) != null) {
this.commandOutPut = this.commandOutPut + "\n" + commandOutPut;
}
System.out.println(this.commandOutPut);
}
Well, obviously, your method does not start cmd. How did you get this notion?
The net command is a standalone command so it runs just fine, but the dir command is not standalone, it is an internal command of cmd.exe, so you cannot run it without launching cmd.exe to execute it.
To get it to work you will have to pass not dir but cmd.exe /c dir or something like that.
Don't know if this perception can help you. But, seems that "net users" are recognized as Windows command, since "Execute" dialog can run it.
But, for some reason, the "dir" command aren't. When try to run, Windows responds that command was not found.
Additionaly, I tried run Command with inline arguments too, but the arguments are simply ignored. (sorry for bad english)
My best guess is that this is because "net" is a real executable (there is a file WINDIR\System32\net.exe"), while "dir" is a builtin command of the command interpreter - it has no executable and is directly executed within cmd.exe.
Howevever you may get around this be invoking "dir" command inside the cmd process. The syntax - as per Microsoft docs - is:
cmd /c dir
There are also some related answers on the site:
How to execute cmd commands via Java
Run cmd commands through java
You can use the following code for this
import java.io.*;
public class demo
{
public static void main(String args[])
{
try
{
Process pro=Runtime.getRuntime().exec("cmd /c dir");
pro.waitFor();
BufferedReader redr=new BufferedReader(
new InputStreamReader(pro.getInputStream())
);
String ln;
while((ln = redr.readLine()) != null)
{
System.out.println(ln);
}
}
catch(Exception e) {}
System.out.println("Done");
}
}

Java syntax escapting symbols?

I need to process a command in cmd and the command looks like this:
"c:\Program Files (x86)\HMA! Pro VPN\bin\HMA! Pro VPN.exe" -changeip
But I can't really add the " because I will get errors..
Is there a way to do that? What i've tried causes errors:
cmd.exec(""c:/Program Files (x86)/HMA! Pro VPN/bin/HMA! Pro VPN.exe" -reconnect");
How can I escape that character so it works?
Exception in thread "Thread-1" java.lang.IllegalArgumentException: Executable name has embedded quote, split the arguments
at java.lang.ProcessImpl.isQuoted(Unknown Source)
at java.lang.ProcessImpl.getExecutablePath(Unknown Source)
at java.lang.ProcessImpl.<init>(Unknown Source)
at java.lang.ProcessImpl.start(Unknown Source)
at java.lang.ProcessBuilder.start(Unknown Source)
at java.lang.Runtime.exec(Unknown Source)
at java.lang.Runtime.exec(Unknown Source)
at java.lang.Runtime.exec(Unknown Source)
at HMACommand.reconnect(HMACommand.java:15)
You can escape characters using a backslash (\).
In your case the result will be this:
String test = "\"c:\\Program Files (x86)\\HMA! Pro VPN\\bin\\HMA! Pro VPN.exe\" -changeip";
You'll also have to escape the backslashes themselves.
Referring to your edit:
This answer explains why you get the error you're getting.
From the cited source:
On Windows platform, the decoding of command strings specified to Runtime.exec(String), Runtime.exec(String,String[]) and Runtime.exec(String,String[],File) methods, has been improved to follow the specification more closely. This may cause problems for applications that are using one or more of these methods with commands that contain spaces in the program name, or are invoking these methods with commands that are not quoted correctly.
Instead, use a ProcessBuilder.
You could use a ProcessBuilder like so
String[] cmdLine = {
"c:/Program Files (x86)/HMA! Pro VPN/bin/HMA! Pro VPN.exe",
"-changeip"
};
try {
ProcessBuilder pb = new ProcessBuilder(cmdLine);
Process p = pb.start();
p.waitFor();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}

Not able to execute an exe file from java using ProcessBuilder

I am making a project to run C, C++ and Java, from within Java code itself. It works absolutely fine for Java, and the problem is faced when compiling and executing C and C++ files.
I got my compilation right with this code and I can get the executable file generated in my specified path. But now when I run the executable binary from ProcessBuilder I get an error saying that 'file was not found'. Please see to the code and tell me what is going wrong and where??
public void processCode(String path,String lang)throws IOException
{
String cmd="",s=null,out=null,file="";
totalTime=0;
ProcessBuilder process=new ProcessBuilder();
process.directory(new File(path));
if(lang.equals("c")||lang.equals("cpp"))
{
cmd=threadNum+".exe";
process.command(cmd);
}
else if(lang.equals("java"))
{
cmd="java";
file="Main"+threadNum;
process.command(new String[]{cmd,file});
}
process.redirectInput(new File(PATH+"Input\\" + prob + ".txt"));
process.redirectOutput(new File(PATH+"Output.txt"));
Process p=process.start();
long start=System.currentTimeMillis();
while (true)
{
try{
if(p.exitValue()==0)
{
totalTime=(int)(System.currentTimeMillis()-start);
break;
}
}
catch (Exception e)
{
}
if(System.currentTimeMillis()-start>2000)
{
res=1;
p.destroy();
break;
}
}
if(res!=1)
{
compareFile();
}
}
The method is called from here
And the error generated is :
Exception in thread "main" java.io.IOException: Cannot run program "19.exe" (in directory "C:\wamp\www\usercodes\lokesh"): CreateProcess error=2, The system cannot find the file specified
at java.lang.ProcessBuilder.start(ProcessBuilder.java:1029)
at Contest.processCode(Main.java:202)
at Contest.compileCode(Main.java:180)
at Contest.makeFile(Main.java:157)
at Contest.main(Main.java:53)
at Main.main(Main.java:15)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Caused by: java.io.IOException: CreateProcess error=2, The system cannot find the file specified
at java.lang.ProcessImpl.create(Native Method)
at java.lang.ProcessImpl.<init>(ProcessImpl.java:188)
at java.lang.ProcessImpl.start(ProcessImpl.java:132)
at java.lang.ProcessBuilder.start(ProcessBuilder.java:1021)
... 10 more
Setting the directory of a ProcessBuilder does not have any effect on where the system will look for the executable when it tries to start a process. It merely sets the current working directory of the newly-created process to this directory, should it be able to launch a process successfully. Your program 19.exe may well exist in C:\wamp\www\usercodes\lokesh, but unless this folder is on the PATH, the system will not be able to start your process.
Try running the process using the full path of the executable instead of just 19.exe.
It does have to be said that the error message is somewhat misleading. It says that it couldn't find your executable, and then it says 'in directory ...', which implies that that was where it was looking for it.

Java executing Linux commands

I want to write a java code that executes some Linux command:
String cmd = "cd /home/arps/FBI" ;
Process p=Runtime.getRuntime().exec(cmd);
String [] arr = new String [9] ;
arr[0] = "cd /home/arps/FBI" ;
for(int n = 1 ; n < 9 ; n++){
String command = "mv" + " " + "/home/arps/FBI/hr" + n + ".txt" + " " + "/home/arps/FBI/hrs" + n +".txt" ;
arr[n] = command ;
}
Process pp=Runtime.getRuntime().exec(arr);
In above code: I try to rename 8 files named hr1, hr2 .... to hrs1 , hrs2 ... etc. In cd command I try to enter the required directory. However, I have used absolute path also. But the code is giving error:
java.io.IOException: Cannot run program "cd": java.io.IOException: error=2, No such file or directory
java.io.IOException: Cannot run program "mv /home/arps/FBI/hr1.txt /home/arps/FBI/hrs1.txt": java.io.IOException: error=2, No such file or directory
Can anybody help me why is this happening though I manually execute those command means "mv /home/arps/FBI/hr1.txt /home/arps/FBI/hrs1.txt" and executes properly?
cd is a built-in command to the current shell - you can't execute it - it's a shell built-in, as the cwd is a process-level setting, so a new process has it's own value. There is no way to change the cwd from within the java process.
The array argument version of exec is for executing a single command, where you have split the arguments yourself, not for executing multiple commands.
So you either need to give full paths, or implement the copy yourself in Java.
Change the final line of your program from
Process pp=Runtime.getRuntime().exec(arr);
to:
for (String cmdLine: arr) {
Process pp=Runtime.getRuntime().exec(cmdLine);
and you will execute each line separately, according to RunTime documentation.
You might be better off writing a shell script that does what you need and invoking that from Java.
arr array must store the arguments of command. Not seperated commands. refer to my question.
run shell command from java
If ls -l /home/arps/FBI/hrs1.txt outputs nothing as you said in the comments, then the file you're trying to rename simply does not exist, so the exception is right about this.
PS: IMHO this is not to be done in Java. Use scripting languages for such things. Way easier and way smaller code. For each problem, try to use the right tool, not one tool for all problems.

launching terminal from application

I have created an application using Netbeans 6.9. In the application I want that when the user clicks on the run button then the terminal(Command Prompt) should open and some text should appear on the terminal. The text is actually a command. I want that the command should be executed on the terminal. Can anyone please help me.
I've written the following code....
class test extends Exception{
public static void main(String arg[]) {
String command = "cmd.exe/start cmd";
System.out.println(command);
try {
Process child = Runtime.getRuntime().exec(command);
} catch (Exception e) {
e.printStackTrace();
}
}
}
But its giving the following error...
cmd.exe/start cmd
java.io.IOException: Cannot run program "cmd.exe/start": CreateProcess error=2,
The system cannot find the file specified
at java.lang.ProcessBuilder.start(ProcessBuilder.java:1018)
at java.lang.Runtime.exec(Runtime.java:610)
at java.lang.Runtime.exec(Runtime.java:448)
at java.lang.Runtime.exec(Runtime.java:345)
at test.main(test.java:6)
Caused by: java.io.IOException: CreateProcess error=2, The system cannot find th
e file specified
at java.lang.ProcessImpl.create(Native Method)
at java.lang.ProcessImpl.(ProcessImpl.java:155)
at java.lang.ProcessImpl.start(ProcessImpl.java:99)
at java.lang.ProcessBuilder.start(ProcessBuilder.java:1010)
... 4 more
Can anyone tell me whats the problem??
-Thanks in advance
Here is a really good tutorial on Runtime and Process in Java, which covers off all the points that you are looking to do.
http://www.java-tips.org/java-se-tips/java.util/from-runtime.exec-to-processbuilder.html
Simply, you want to use Runtime to open the command window, and the Process to read and write to the output stream of that process.
The error is in your command.. "cmd.exe/start cmd"
Process prr = rt.exec("cmd /c "+i);
in this case the command you want to execute is in (String i)

Categories