I have a batch file on windows machine.
The path to the same is having spaces in it. E.g. C:\Hello World\MyFile.bat
I am trying to execute the batch file through java as:
Runtime.getRuntime().exec(dosCommand + destinationFilePath + batch)
But, as the path has spaces, it says "C:\Hello" is not a valid command or directory.
I tried this too:
Complete command: cmd /c start /wait "C:/Hello World/MyFile.bat" It opens the command prompt, but does not go to the folder Hello World and does not execute the bat file
How do I handle this situation.
Let me know if any additional Info. is required.
Using quotation marks ("C:\Hello World\MyFile.bat") should do the trick. Within Java you'll have to secape the quotation marks with \ (String batch = "\"C:\Hello World\MyFile.bat\"").
I was able to solve it using ProcessBuilder.
The directory in which the bat file is present can be added to the working directory as:
processBuilder.directory(new File("C:\hello world\"));
This works like gem.
int result = 1;
final File batchFile = new File("C:\\hello world\\MyFile.bat");
final File outputFile = new File(String.format("C:\\hello world\\output_%tY%<tm%<td_%<tH%<tM%<tS.txt", System.currentTimeMillis()));
final ProcessBuilder processBuilder = new ProcessBuilder(batchFile.getAbsolutePath());
processBuilder.redirectErrorStream(true);
processBuilder.redirectOutput(outputFile);
processBuilder.directory(new File("C:\\hello world\\"));
try {
final Process process = processBuilder.start();
if (process.waitFor() == 0) {
result = 0;
}
System.out.println("Processed finished with status: " + result);
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
Did you try to escape quotes surrounding the path such as :
Runtime.getRuntime().exec(dosCommand + "\"" + destinationFilePath + batch + "\"")
I just solved this problem using a ProcessBuilder as well, however I gave the directory with a space to processBuilder.directory and ran the command with the bat file name.
ProcessBuilder pb = new ProcessBuilder("cmd", "/c", "start", "/wait", "export.bat");
pb.directory(new File(batDirectoryWithSpace));
pb.redirectError();
try {
Process process = pb.start();
System.out.println("Exited with " + process.waitFor());
}
catch (IOException | InterruptedException ex) {
Exceptions.printStackTrace(ex);
}
Related
I'm trying to compile C source file with gcc using ProcessBuilder. I managed to make it running but there is no output file.
Here is my code (based on this answer) :
public void compileWithGccNoCmd(Path sourcePath) throws IOException {
String sourcePathString = sourcePath.toString();
String outputPathString = sourcePath.getParent().toString() + "\\" + Files.getNameWithoutExtension(sourcePath.toString());
try {
ProcessBuilder pb = new ProcessBuilder("gcc", "-fprofile-arcs -ftest-coverage -o " + outputPathString, sourcePathString);
pb.directory(sourcePath.getParent().toFile()); // this was added later
Process compile = pb.start();
compile.waitFor();
if (compile.exitValue() == -1) {
// if error
System.out.print("COMPILE ERROR");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
My first thought that it has something to do with the working directory so I add pb.directory() but the output file still not there.
Since I can't find any solution to this, I tried another way by running gcc with cmd. I set the working directory to make sure the output files on the right place. This is the alternative code (based on this answer):
public void compileWithGcc(Path sourcePath) throws IOException {
String sourcePathString = sourcePath.toString();
String outputPathString = sourcePath.getParent().toString() + "\\" + Files.getNameWithoutExtension(sourcePath.toString());
ProcessBuilder pb;
try {
pb = new ProcessBuilder("cmd", "/C", "gcc " + sourcePathString + " -o " + outputPathString + " -fprofile-arcs -ftest-coverage");
pb.directory(sourcePath.getParent().toFile());
Process p = pb.start();
p.waitFor();
int x = p.exitValue();
} catch (Exception ex) {
ex.printStackTrace();
}
}
For some reason it works! Why is this happened? I'm pretty sure both is running gcc with the same parameter
This line:
ProcessBuilder pb = new ProcessBuilder("gcc", "-fprofile-arcs -ftest-coverage -o " + outputPathString, sourcePathString)
needs to look like this:
ProcessBuilder pb = new ProcessBuilder("gcc", "-fprofile-arcs", "-ftest-coverage", "-o", outputPathString, sourcePathString)
What you are doing with the first line is passing two arguments to gcc, one of which is "-fprofile-arcs -ftest-coverage -o " + outputPathString, instead of passing the five arguments of my edited line. gcc won't understand that.
When you use cmd like you did, it parses the command that you gave it and passes the arguments correctly, that's why it works.
In an application I am writing, I need to use the javaagent option to call an external jar in the same folder as my current jar file. When I run the code from the jar file, I get told: "Error: Could not find or load main class -javaagent:" but when I am running it from a batch file, it works as excepted.
I am using a ProcessBuilder to start the application:
String java = System.getProperty("java.home") + File.separatorChar + "bin" + File.separatorChar +"java.exe";
File transagent = new File(pluginDir + File.separatorChar + "TransAgent.jar");
String doublequote = String.valueOf('"');
List<String> commandlist = new ArrayList<String>();
commandlist.add(java);
commandlist.add(" -javaagent:");
commandlist.add(doublequote);
commandlist.add(transagent.getAbsolutePath());
commandlist.add(doublequote);
for(int i = 0; i < commandlist.size(); i++){
String part = commandlist.get(i);
System.out.print(part);
}
System.out.println();
ProcessBuilder pb = new ProcessBuilder();
pb.command(commandlist);
pb.redirectError(Redirect.appendTo(errorfile));
pb.redirectOutput(Redirect.appendTo(logfile));
try {
pb.start();
} catch (IOException e) {
e.printStackTrace();
}
But, when I go to the error file, I see "Error: Could not find or load main class -javaagent:"
This would usually be thrown if the option isn't valid, but I've checked the dash to work file. And I put what printed from the application in a batch file, and it worked fine. Why?
You can try this code below:
ProcessBuilder pb = new ProcessBuilder("java", "-javaagent:"+transagent.getAbsolutePath(), "YouMainClass");
pb.redirectError(Redirect.appendTo(errorfile));
pb.redirectOutput(Redirect.appendTo(logfile));
try
{
pb.start();
}
catch(IOException e)
{
e.printStackTrace();
}
I have gone through few questions raised on how to achieve this.
I used process.waitFor() and /wait as mentioned here. The problem is by doing so it waits not just till the command is executed but until cmd prompt is closed (can be done by adding exit in the bat file). But I cannot modify bat file as its a Product file.
Runtime run = Runtime.getRuntime();
try {
String path = "C:/Folder/c.bat";
String executeCmd= "cmd /c start /wait "+path;
final Process process =run.exec(executeCmd);
process.waitFor();
System.out.println("did I wait?");
} catch (Exception e) {
e.printStackTrace();
}
How to make it wait only till the command is executed.
You can create a helper batch file with following content:
start /wait %1\c.bat
exit
Store this helper batch anywhere you want to.
Then start this helper batch file with the path to c.bat as its parameter.
Runtime run = Runtime.getRuntime();
try {
String pathToCBatch = "C:\\Folder\\";
String pathToHelperBatch = "c:/helperBatch.bat";
String executeCmd = "cmd /c start /wait " + pathToHelperBatch + " " + pathToCBatch;
final Process process = run.exec(executeCmd);
System.out.println(System.currentTimeMillis());
process.waitFor();
System.out.println(System.currentTimeMillis());
} catch (Exception e) {
e.printStackTrace();
}
I have also the same issue: "call a Batch file and wait until it's finished" (Windows PC). This solution works for me :
StringBuilder command = new StringBuilder("cmd /c start /wait C:\\script.bat");
// my script take 2 file as arguments
command.append(" ").append(inputFile);
command.append(" ").append(outputFile);
try {
final Process p = Runtime.getRuntime().exec(command.toString());
p.waitFor();
} catch (InterruptedException e) {
System.out.println(e);
}
also if the directory has space in it then the command wont work from string of arrey
so instead do this
File file = new File("E:\\NetBeans Projects\\Test.bat");
String[] command = {"cmd.exe", "/c", "start", file.getName() };
Runtime rt = Runtime.getRuntime();
Process pr = rt.exec(command , null , file.getParentFile());
dont work for me to exit cmd from java
i have come with a solution
i added "exit" in my .bat file at the end and it works now
example :
this is my "adservice.google.com.bat" bat file which dont exit after executing from java
netsh advfirewall firewall add rule name="adservice.google.com.bat" protocol=any dir=out action=block remoteip=2404:6800:4009:80f::2002,216.58.203.34
so i have to add "exit" in it , in the last line
netsh advfirewall firewall add rule name="adservice.google.com.bat" protocol=any dir=out action=block remoteip=2404:6800:4009:80f::2002,216.58.203.34
exit
I am trying to execute .bat file using java process builder but it does not starts the process. Please tell me what i am doing wrong here. This code works fine with linux envoirnment when I replace file.bat with ./file.sh
final ArrayList<String> command = new ArrayList<String>();
command.add(WORKING_DIR+File.separator+"file.bat");
final ProcessBuilder builder = new ProcessBuilder(command);
try {
builder.redirectErrorStream(true);
builder.start();
} catch (IOException e) {
logger.error("Could not start process." ,e);
}
First element in array must be an executable. So you have to invoke cmd.exe in order to call you batch file.
ProcessBuilder builder = new ProcessBuilder(Arrays.asList(new String[] {"cmd.exe", "/C", WORKING_DIR + File.separator + "file.bat"}));
Make sure the path to the bat file is correct. You can either debug it using a debugger or put a sysout to determine that:
final ArrayList<String> command = new ArrayList<String>();
System.out.println("Batch file path : " + WORKING_DIR+File.separator+"file.bat")
command.add(WORKING_DIR+File.separator+"file.bat");
final ProcessBuilder builder = new ProcessBuilder(command);
try {
builder.redirectErrorStream(true);
builder.start();
} catch (IOException e) {
logger.error("Could not start process." ,e);
}
I have a java application that downloads a file from a web service using wget. When executing the command through java it returns with: "wget: not an http or ftp url:"
When i execute the command directly it runs without problems. Here is my code:
try {
Debug.println("Starting copy of "+srcFile+" to "+destFile);
String command = "wget -O " + destFile + " \""+ srcFile +"\"";
Process p = Runtime.getRuntime().exec(command);
int exitCode = p.waitFor();
if(Debug.isDebugMode())
{
Debug.println(command);
BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getErrorStream()));
String s;
while((s = stdInput.readLine()) != null)
{
Debug.println(s);
}
}
Debug.println("Finished with code: " + String.valueOf(exitCode));
}
catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return false;
And this is the output:
24/04/2013 10:11:05 Starting copy of stoppenmetroken.webcolors.local/service/track?track=3b1ac68a288345c183a08c714901a398&mac=089000A09090 to /opt/byato/data/song/3b1ac68a288345c183a08c714901a398
24/04/2013 10:11:05 wget -O /opt/byato/data/song/3b1ac68a288345c183a08c714901a398 "stoppenmetroken.webcolors.local/service/track?track=3b1ac68a288345c183a08c714901a398&mac=089000A09090"
24/04/2013 10:11:05 wget: not an http or ftp url: "http://stoppenmetroken.webcolors.local/service/track?track=3b1ac68a288345c183a08c714901a398&mac=089000A09090"
24/04/2013 10:11:05 Finished with code: 1
ps: i removed the http:// part of the output because i dont have enough reputation points -.-
What am i missing?
Can you try to execute the command like this :
Process p = Runtime.getRuntime().exec("/bin/bash -c "+command); //for linux
or
Process p = Runtime.getRuntime().exec("cmd.exe /c "+command); //for Windows
Sometimes we need to explicitly invoke Linux shell or command prompt.
Hope this will work.
I suspect this:
String command = "wget -O " + destFile + " \""+ srcFile +"\"";
is the problem. When you run in a shell, the quotes around the URL will be removed. However when you run via Java you're not running via a shell and your URL starts with "http... (look closely at the error message).
If you don't want Runtime.exec() to parse and split your arguments then you might consider the variant that takes individual arguments. A more efficient solution still would be to download using HttpComponents.