Execute ".bat" file that contains multiple lines from Java - java

I have a folder named A that contains a .bat file: a.bat.
If I wanted to write a .bat file I could write:
cd A/
call a.bat
and I would see the results, but if I want to run it from Java I have problems.
I'm trying to do this:
String command = "cmd.exe /c start cd A/\ncall a.bat";
try {
Runtime.getRuntime().exec(command);
} catch (IOException e) { }
I tried to replace \n with ; and with \r and with && but that didn't work. (It doesn't recognize that there exist two lines).
How can I run multiple lines from a .bat from Java?

You can set the working directory for the process from the Java side at the point where you spawn cmd, rather than needing a cd command:
ProcessBuilder pb = new ProcessBuilder("cmd.exe", "/c", "a.bat");
pb.directory(new File("path\\to\\A"));
Process p = pb.start();

Related

How to execute vimdiff command from inside a java program

I have a list of files for which I have to run the vimdiff command and save the output as a html file.I am doing this with Java. Below is the command I am trying to execute
String cmd = "vimdiff -c 'set foldlevel=9999' src/test/resources/testdata/output/html_output_before_changes/file1.html src/test/resources/testdata/output/html_output_after_changes/file2.html -c TOhtml -c 'w! different.html' -c 'qa!'"
When I run the below code, the code is getting executed. But I am not able to see the file getting generated.
Runtime rt = Runtime.getRuntime();
Process process = rt.exec(cmd);
The command is running fine when executed from a terminal. But its not working when executed inside a java program. Can someone help me with this issue? I did a lot of search but not able to proceed with this.
You're using :TOhtml and write the result as different.html. If you're not sure where to locate the file, check the current working directory of the Java process, do a file search of your hard disk, or specify an absolute path in the Vim command to be sure.
You won't see anything from Vim's operation itself. Using process.getInputStream(), you could obtain what Vim wrote to the terminal during its operation, but that would just amount to a garble of characters, as Vim is using special ANSI escape sequences to control the terminal, position the cursor, etc.
To use Vim non-interactively, it is recommended to pass the following options:
-T dumb Avoids errors in case the terminal detection goes wrong.
-n No swapfile.
-i NONE Ignore the |viminfo| file (to avoid disturbing the
user's settings).
-c 'set nomore' Suppress the more-prompt when the screen is filled
with messages or output to avoid blocking.
Without a possibility to interact with Vim (from inside your Java program), a troubleshooting tip is enabling verbose logging: You can capture a full log of a Vim session with -V20vimlog. After quitting Vim, examine the vimlog log file for errors.
After Two days I found the below Solution:
I added the vimdiff command to a shell script and executed it using the following method and it worked like a gem.
Java method
try {
File[] uiDiffDir = getFiles();
for (File file : uiDiffDir) {
String[] cmd = {"sh", shellScriptPath, file1, file2,
outputfile};
Process p = Runtime.getRuntime().exec(cmd);
p.waitFor();
BufferedReader reader = new BufferedReader(new InputStreamReader(
p.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
shell.sh
vimdiff -c 'set foldlevel=9999' $1 $2 -c TOhtml -c 'w! '"$3"'' -c 'qa!'
Note:
file1 will be passed as a argument in the place of $1
file2 will be passed as a argument in the place of $2
outputfile will be passed as a argument in the place of $3

Java - Open command prompt, run two commands

Noobish question I'm sure, but I'm trying to open a command prompt, switch to a directory, then run a second command. I've got:
try {
// Execute command
String command = "cmd /c start cmd.exe";
Process child = Runtime.getRuntime().exec(command);
// Get output stream to write from it
OutputStream out = child.getOutputStream();
out.write("cd C:\Users\Me\Desktop\Reports\Scripts /r/n".getBytes());
out.flush();
out.write("for %f in (*.txt) do type "%f" >> Export.txt /r/n".getBytes());
out.close();
} catch (IOException e) {
}
My ignorant guess is the "%f" in the second command needs to be written properly, but I know so little about java I'm not sure how to do it.
You can use Runtime.getRuntime().exec("...") to run command lines, and you can use "&&" to execute more than one command, e.g.:
Runtime.getRuntime().exec("cmd /c \"start something.bat && start somethingelse.bat \"");

Concatenate two DOS commands in a java program

I want to concatenate two dos commands in a java program. First I want to change directory then list the files and folders in that. So I wrote that like
try
{
Process process = UI.this.rt.exec("cmd.exe /c cd C:\\Users & start dir");
process.waitFor();
InputStream in = process.getInputStream();
while (in.read() != -1) {}
}
catch (Exception e)
{
System.out.println(e);
}
But this is not working. When I execute this in desktop it is not change the directory and display the files and folders which is in the desktop. Could you please help me to fix this problem? I'm using windows 7 machine.
Thanks
Isuru Liyanage
Write the commands to a batch file on the disk and execute the batch.
If you don't want to have such a batch on the disk, create it on demand and delete it after usage.
Or just use the java build-in features to list files.
EDIT
But your code works. I tried it.
It opens a dos-box an lists the directory after changing the directory.
You can use ProcessBuilder to set the working directory of the Process you exec later.
Or, do as suggested else-thread and use the Java API for listing files in a directory, which is saner.
While creating a process you can pass a string array of commands as below:
String[] command = new String[3];
command[0] = "cmd";
command[1] = "/c";
command[2] = " cd c:\\Users && dir";
Process p = Runtime.getRuntime().exec(command);
Drop the start, it runs files in a new window. Plus as there in no cmd in the NEW command DIR won't be recognised as a command. If you must use start for some reason add cmd /c to the dir part as well.
also dir c:\users is all you actually need to do. No need or reason to change directory.

Write result from command line in file using Java

I tried to run command line from Java code.
public void executeVcluto() throws IOException, InterruptedException {
String command = "cmd /c C:\\Users\\User\\Downloads\\program.exe C:\\Users\\User\\Downloads\\file.txt 5 >> C:\\Users\\User\\Downloads\\result.txt";
Process process = Runtime.getRuntime().exec(command);
process.waitFor();
if (process.exitValue() == 0) {
System.out.println("Command exit successfully");
} else {
System.out.println("Command failed");
}
}
However, the file where output result should be written result.txt is not created. When I execute this command from cmd on windows the file is created and the result is written in it. I get Command exit successfully message. Could someone help me?
output redirection is shell feature, java Process does not understand that.
Some other alternatives are
1. create a single batch file with above lines and invoke it using ProcessBuilder/Runtime
2. Use ProcessBuilder and redirect output using output streams.
Example (it is for shell, will work for batch files too) is here
ProcessBuilder builder = new ProcessBuilder("cmd", "/c", "C:\\Users\\User\\Downloads\\program.exe", "C:\\Users\\User\\Downloads\\file.txt" , "5");
builder.redirectOutput(new File("C:\\Users\\User\\Downloads\\result.txt"));
builder.redirectError(new File("C:\\Users\\User\\Downloads\\resulterr.txt"));
Process p = builder.start(); // throws IOException
(above is tweaked from Runtime's exec() method is not redirecting the output)
Try cmd.exe, including a path, if necessary.
You're creating an entirely new process, which is different than giving a command to a shell.

How to open the command prompt and insert commands using Java?

Is it possible to open the command prompt (and I guess any other terminal for other systems), and execute commands in the newly opened window?
Currently what I have is this:
Runtime rt = Runtime.getRuntime();
rt.exec(new String[]{"cmd.exe","/c","start"});
I've tried adding the next command after the "start", I've tried running another rt.exec containing my command, but I can't find a way to make it work.
If it matters, I'm trying to run a command similar to this:
java -flag -flag -cp terminal-based-program.jar
EDIT Unfortunately I have had some strange findings. I've been able to successfully launch the command prompt and pass a command using this:
rt.exec("cmd.exe /c start command");
However, it only seems to work with one command. Because, if I try to use the command separator like this, "cmd.exe /c start command&command2", the second command is passed through the background (the way it would if I just used rt.exec("command2");). Now the problem here is, I realized that I need to change the directory the command prompt is running in, because if I just use the full path to the jar file, the jar file incorrectly reads the data from the command prompt's active directory, not the jar's directory which contains its resources.
I know that people recommend staying away from rt.exec(String), but this works, and I don't know how to change it into the array version.
rt.exec("cmd.exe /c cd \""+new_dir+"\" & start cmd.exe /k \"java -flag -flag -cp terminal-based-program.jar\"");
If you are running two commands at once just to change the directory the command prompt runs in, there is an overload for the Runtime.exec method that lets you specify the current working directory. Like,
Runtime rt = Runtime.getRuntime();
rt.exec("cmd.exe /c start command", null, new File(newDir));
This will open command prompt in the directory at newDir. I think your solution works as well, but this keeps your command string or array a little cleaner.
There is an overload for having the command as a string and having the command as a String array.
You may find it even easier, though, to use the ProcessBuilder, which has a directory method to set your current working directory.
Hope this helps.
public static void main(String[] args) {
try {
String ss = null;
Process p = Runtime.getRuntime().exec("cmd.exe /c start dir ");
BufferedWriter writeer = new BufferedWriter(new OutputStreamWriter(p.getOutputStream()));
writeer.write("dir");
writeer.flush();
BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
BufferedReader stdError = new BufferedReader(new InputStreamReader(p.getErrorStream()));
System.out.println("Here is the standard output of the command:\n");
while ((ss = stdInput.readLine()) != null) {
System.out.println(ss);
}
System.out.println("Here is the standard error of the command (if any):\n");
while ((ss = stdError.readLine()) != null) {
System.out.println(ss);
}
} catch (IOException e) {
System.out.println("FROM CATCH" + e.toString());
}
}
The following works for me on Snow Leopard:
Runtime rt = Runtime.getRuntime();
String[] testArgs = {"touch", "TEST"};
rt.exec(testArgs);
Thing is, if you want to read the output of that command, you need to read the input stream of the process. For instance,
Process pr = rt.exec(arguments);
BufferedReader r = new BufferedReader(new InputStreamReader(pr.getInputStream()));
Allows you to read the line-by-line output of the command pretty easily.
The problem might also be that MS-DOS does not interpret your order of arguments to mean "start a new command prompt". Your array should probably be:
{"start", "cmd.exe", "\c"}
To open commands in the new command prompt, you'd have to use the Process reference. But I'm not sure why you'd want to do that when you can just use exec, as the person before me commented.
You just need to append your command after start in the string that you are passing.
String command = "cmd.exe /c start "+"*your command*";
Process child = Runtime.getRuntime().exec(command);
String[] command = {"cmd.exe" , "/c", "start" , "cmd.exe" , "/k" , "\" dir && ipconfig
\"" };
ProcessBuilder probuilder = new ProcessBuilder( command );
probuilder.directory(new File("D:\\Folder1"));
Process process = probuilder.start();
You can use any on process for dynamic path on command prompt
Process p = Runtime.getRuntime().exec("cmd.exe /c start dir ");
Process p = Runtime.getRuntime().exec("cmd.exe /c start cd \"E:\\rakhee\\Obligation Extractions\" && dir");
Process p = Runtime.getRuntime().exec("cmd.exe /c start cd \"E:\\oxyzen-workspace\\BrightleafDesktop\\Obligation Extractions\" && dir");
Please, place your command in a parameter like the mentioned below.
Runtime.getRuntime().exec("cmd.exe /c start cmd /k \" parameter \"");
You have to set all \" (quotes) carefully. The parameter \k is used to leave the command prompt open after the execution.
1) to combine 2 commands use (for example pause and ipconfig)
Runtime.getRuntime()
.exec("cmd /c start cmd.exe /k \"pause && ipconfig\"", null, selectedFile.getParentFile());
2) to show the content of a file use (MORE is a command line viewer on Windows)
File selectedFile = new File(pathToFile):
Runtime.getRuntime()
.exec("cmd /c start cmd.exe /k \"MORE \"" + selectedFile.getName() + "\"\"", null, selectedFile.getParentFile());
One nesting quote \" is for the command and the file name, the second quote \" is for the filename itself, for spaces etc. in the name particularly.

Categories