"Program Files" command intern not found CMD - java

I use java to excute a command line to create a database, i get an error when i excute this piece of code:
private final String POSTGRES_PATH = "\"C:\\Program Files\\PostgreSQL\\9.3\\bin\\psql.exe\"";
private final String DATA_BASE = "bd_name";
private void creerDataBase() {
String command = this.POSTGRES_PATH + " -U postgres -d postgres -c \"CREATE DATABASE " + this.DATA_BASE + "\"";
System.out.println("command = " + command);
String creerBDD = executerCommande(command);
System.out.println("Resultat : " + creerBDD);
}
public String executerCommande(String command) {
String line;
String resultat = "";
try {
ProcessBuilder builder = new ProcessBuilder("cmd.exe", "/c", command);
builder.redirectErrorStream(true);
Process p = builder.start();
BufferedReader r = new BufferedReader(new InputStreamReader(p.getInputStream()));
while (true) {
line = r.readLine();
if (line == null) {
break;
}
resultat += line + "\n";
}
} catch (Exception e) {
System.out.println("Exception = " + e.getMessage());
}
return resultat;
}
I get this result:
command = "C:\Program Files PostgreSQL\9.3\bin\psql.exe"\ -U postgres -d postgres -c "CREATE DATABASE bd_name"
and this error:
'C:\Program' n'est pas reconnu en tant que commande interne
This mean that Program is not an intern command.
but when i excute this command in CMD it work fine?
Is there any way to Build this Path because the ProcessBuilder not recognize C:\Program Files

Thanks for #Aaron his idea helps me so i solved this problem using this:
private final String POSTGRES_PATH = "C:\\PROGRA~1\\PostgreSQL\\9.3\\bin\\psql.exe";
this C:\\PROGRA~1 inteed of this: C:\\Program Files

A possible solution would be to remove the path (with spaces) from your constant field and use the directory method:
Sets this process builder's working directory. Subprocesses subsequently started by this object's start() method will use this as their working directory. The argument may be null -- this means to use the working directory of the current Java process, usually the directory named by the system property user.dir, as the working directory of the child process.
Changing your code to:
private final String POSTGRES_DIR = "C:\\Program Files\\PostgreSQL\\9.3\\bin\\"
private final String POSTGRES_COMMAND = "psql.exe";
....
ProcessBuilder builder = new ProcessBuilder("cmd.exe", "/c", command).directory(new File(POSTGRES_DIR));
.....

Don't run cmd.exe if you want to run a separate binary program.
cmd.exe is for scripts like *.cmd or *.bat
With cmd.exe you have to pass your command as an argument of CMD, and you should manage all OS-specific pitfalls like long paths with whitespaces, quotes inside qoutes etc.
Instead, you had better run psql itself.
The ProcessBuilder takes a command and all the arguments as a list of separate strings. And ProcessBuilder is clever enough to do all the necessary magic with quotes and whitespaces by itself.
And take attention to the list of arguments - shells separate arguments by whitespaces, while psql might recognize the sequence of strings as a single argument.
We may assume that -U postgress is a single argument for psql, but for shell (cmd.exe in our case) these are two separate arguments - -U and postgress, so we should pass them to the ProcessBuilder separately
So the better way to run psql is to run it directly, something like that:
new ProcessBuilder("C:\\Program Files\\PostgreSQL\\9.3\\bin\\psql.exe",
"-U", "postgres",
"-d", "postgres",
"-c", "\"CREATE DATABASE " + this.DATA_BASE + "\"");

What you could try is instead of the space between program and files is %20 or \s.
So like:
command = "C:\\Program%20Files\\PostgreSQL\\9.3\\bin\\psql.exe"
or
command = "C:\\Program\sFiles\\PostgreSQL\\9.3\\bin\\psql.exe"
I hope one of them works for you, please let me know
EDIT: use double \ to get it to recognize the \

Related

How to run multiple cmd commands through Java?

I have a simple GUI which selects an executable and a batch file. Clicking "run" should launch a command line instance, then run the executable given the selected batch. However, hiccups seem to show up at different points. This is the relevant code snippet:
String[] commands = {"cmd.exe", "/c", "C:\\Xilinx\\14.7\\ISE_DS\\settings64.bat && cd /d ",
"\"" + simFile.getParent() + "\"", " && ping localhost && ",
"\"" + jTextField1.getText() + "\"", " -tclbatch \"" + jTextField2.getText() + "\""};
ProcessBuilder simBuilder = new ProcessBuilder(commands);
simBuilder.redirectErrorStream(true);
Process simulation = simBuilder.start();
BufferedReader reader = new BufferedReader(new InputStreamReader(simulation.getInputStream()));
String line;
while (true) {
line = reader.readLine();
if (line == null)
break;
System.out.println(line);
}
I chose to create a process through a ProcessBuilder rather than "Runtime.getRuntime().exec" because having the command and arguments as a String array is more readable and manageable. I took a look through the documentation of Runtime, Process, and ProcessBuilder. I also searched for similar questions, the following being the closest: Run cmd commands through Java. However, I'm still having issues getting all commands to run properly, if it all. First point: The program successfully executes the commands until "ping", which I placed to determine where the issue occurs. I get the cmd output in the console through the BufferedReader just fine. However, the next command, which should run the executable indicated by "jTextField1.getText()", gives an error of "The filename, directory name, or volume label syntax is incorrect" although I made sure the path is within escaped double quotes to account for spaces. Is it something in my syntax? Something to do with where the double ampersands are placed? Does every separate command with its argument need to be its own string in the array? I tried that and different things, but it always seems to result in an error.
You should check that your path names are correct, and try the cmd as one parameter value not as comma separated after cmd.exe /c. This will ensure the arguments are passed to CMD correctly as a single argument for the CMD shell to handle:
import java.nio.file.Files
System.out.println("Files.isDirectory(simFile.getParent())="+Files.isDirectory(simFile.getParent()));
System.out.println("Files.isExecutable(jTextField1.getText())="+Files.isExecutable(Path.of(jTextField1.getText())));
String cmd = "C:\\Xilinx\\14.7\\ISE_DS\\settings64.bat && cd /d "+
"\"" + simFile.getParent() + "\" && ping localhost && "+
"\"" + jTextField1.getText() + "\" -tclbatch \"" + jTextField2.getText() + "\"";
String[] commands = {"cmd.exe", "/c", cmd};

How to get By Process, Runtime and ProcessId Java [duplicate]

I am writing several java programs and will need to kill off/clean up in a seperate JVM after I am done with whatever I wanted to do. For this, I will need to get the PID of the java process which I am creating.
jps -l works both on Windows and Unix. You can invoke this command from your java program using Runtime.getRuntime().exec. Sample output of jps -l is as follows
9412 foo.bar.ClassName
9300 sun.tools.jps.Jps
You might need to parse this and then check for the fully qualified name and then get the pid from the corresponding line.
private static void executeJps() throws IOException {
Process p = Runtime.getRuntime().exec("jps -l");
String line = null;
BufferedReader in = new BufferedReader(new InputStreamReader(
p.getInputStream(), "UTF-8"));
while ((line = in.readLine()) != null) {
String [] javaProcess = line.split(" ");
if (javaProcess.length > 1 && javaProcess[1].endsWith("ClassName")) {
System.out.println("pid => " + javaProcess[0]);
System.out.println("Fully Qualified Class Name => " +
javaProcess[1]);
}
}
}
you can try execute command
pidof <program name>
for you to find the pid of your program.
It is in Linux env.
Note that Java 9 is going to expose some system-agnostic methods such as:
System.out.println("Your pid is " + Process.getCurrentPid());

mysqldump does not work in java

I am using this command line argument to clone a database :-
"C:\Program Files\MySQL\MySQL Server 5.6\bin\mysqldump" -u root -ppass -d oldDB | mysql -u root -ppass -DnewDB
This piece works fine when directly pasted into command line. But, when I tried running this argument using java, it did not work. My java code is :-
String serverLoc = "C:\\Program Files\\MySQL\\MySQL Server 5.6\\";
String a = "\"" + serverLoc + "bin\\mysqldump\" " ;
String cmd = a + "-u root -ppass -d oldDB | mysql -u root -ppass -DnewDB";
Process runtimeProcess = Runtime.getRuntime().exec(executeCmd);
int processComplete = runtimeProcess.waitFor();
if (processComplete == 0) {
System.out.println("SUCCESS");
} else {
System.out.println("ERROR");
}
//OUTPUT : ERROR
Exception handling not shown as no stack trace is printed. When I print cmd, the above desired string is printed which works when pasted into command line. Please help me solve this dilemma.
I believe on windows you have to call the command this way:
Runtime.getRuntime().exec("cmd " + ecuteCmd)
Also I think it is better to use Runtime.getRuntime().exec(String[]) method
String prog = "C:\\program files\\server\\xampp\\mysql\\bin\\mysql";
String user = "-uroot";
String pass = "-ppass";
Process runtimeProcess = Runtime.getRuntime().exec(new String[] { prog, user, pass });
The modern way by using ProcessBuilder: thx #Daniel
String prog = "C:\\program files\\server\\xampp\\mysql\\bin\\mysql";
String user = "-uroot";
String pass = "-ppass";
ProcessBuilder builder = new ProcessBuilder(prog, user, pass);
Process runtimeProcess = builder.start();
int result = runtimeProcess.waitFor();
//...

Can't run ProcessBuilder

I am struggling with ProcessBuilder folks! I want to run the utility 'nativetoascii' in. I can run it on the command line and also via Runtime.exec() with no problems.
My code is:
'
String command = "\"C:\\Program Files (x86)\\Java\\jdk1.6.0_32\\bin\\native2ascii\"";
String encoding = " -encoding ";
String utf8 = "UTF8 ";
String inputFile = "C:\\Users\\joe\\Desktop\\resources\\encoding\\orig.properties ";
String outputFile ="C:\\Users\\joe\\Desktop\\resources\\encoding\\convertedViaProcessBuilder.properties";
List<String> commandArgs = new ArrayList<String>();
commandArgs.add(command);
commandArgs.add(encoding);
commandArgs.add(utf8);
commandArgs.add(inputFile);
commandArgs.add(outputFile);
ProcessBuilder builder = new ProcessBuilder(commandArgs);
Process p = builder.start();
p.waitFor();
I have also written code to read the output from the process and it says:
Usage: native2ascii [-reverse] [-encoding encoding] [inputfile [outputfile]]
Clearly I'm doing something wrong with the command and its arguments. Can anyone tell me what I'm doing wrong? Thanks.
Your second argument is " -encoding " which it would be "-encoding" Spaces matter when you run a command. ;)

Java - Exec console

I want to create a full cross-plateform console in Java.
The problem I have is when I use the cd command, the path is reset. For example, if I do cd bin, then cd ../, I will execute the first one from the directory of my app and the second one exactly from the same directory.
If I want to go to a specific folder and execute a program I have to do something like that:
cd C:\mydir & cd bin & start.exe
What I want to do is to split this cmd in different parts:
cd C:\mydir then cd bin then start.exe
How can I do that? Is there a way to store the current cd path and use it then?
Here is the code I use:
String[] cmd_exec = new String[] {"cmd", "/c", cmd};
Process child = Runtime.getRuntime().exec(cmd_exec);
BufferedReader in = new BufferedReader(new InputStreamReader(child.getInputStream()));
StringBuffer buffer = new StringBuffer();
buffer.append("> " + cmd + "\n");
String line;
while ((line = in.readLine()) != null)
{
buffer.append(line + "\n");
}
in.close();
child.destroy();
return buffer.toString();
It executes the command, then return the content of the console. (This is for windows for the moment).
If you want to run a command from a specific directory, use ProcessBuilder instead of Runtime.exec. You can set the working directory using the directory method before you start the process. Don't try to use the cd command - you're not running a shell, so it doesn't make sense.
If you do cd you don't want to execute it. You just want to check if the relative path exists and then change a
File currentDir
to that directory. So I would propose you split your commands up in three: cd, dir/ls and other stuff. cd changes the dir, as I mentioned, by using a File currentDir, dir should just get folders and files of currentDir and list them and then the rest you should just execute as you do know.
Remember you can split a command string by "".split("&"); this way you can do "cd C:\mydir & cd bin & start.exe".split("&"); => {"cd C:\mydir", "cd bin", "start.exe"} and then you can execute them in order.
Good luck.
Thanks to Mads, I was able to do the trick:
Here is the code I used:
if (cmd.indexOf("cd ") >= 0)
{
String req_cmd = cmd.substring(0, 3);
String req_path = cmd.substring(3);
if (req_path.startsWith(File.separator) || req_path.substring(1, 2).equals(":"))
path = req_path;
else
if (new File(path + cmd.substring(3)).exists())
path += cmd.substring(3);
else return "[Error] Directory doesn't exist.\n";
if (!path.endsWith(File.separator)) path += File.separator;
cmd = req_cmd + path;
}
else cmd = "cd " + path + " & " + cmd;
Then you can execute the command calling:
Runtime.getRuntime().exec(new String[] {"cmd", "/c", cmd});
Don't forget to add this attribute in your class:
private static String path = System.getProperty("user.dir") + File.separator;

Categories

Resources