I am trying to run reg files with Java. I tried this with no luck:
import java.awt.Desktop;
import java.io.File;
import java.io.IOException;
public class RegEdit {
public static void main(String[] args) throws IOException {
// Desktop.getDesktop().open(new File("ihindi.reg"));
String[] cmd = {"regedit", "ihindi.reg"};
Process p = Runtime.getRuntime().exec(cmd);
try {
p.waitFor();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
ihindi.reg
Windows Registry Editor Version 5.00
[HKEY_CURRENT_USER\Software\Policies\Microsoft\Internet Explorer\Control Panel]
"HomePage"=dword:00000001
When I run it, it doesn't make anything and errors. Where am I doing wrong ?
I think you would need to add the "/s" statement in between, your process probably got disturb while you're writing the data into the regedit.
I was in the exactly same situation as yours, no error, but it just couldn't write into the regedit. the "/s" did the job.
try{
// silence all the process without prompting the dialog box to ask if user wanna proceed.
String[] cmd = { "regedit.exe", "/s", regFilePath};
Process process = Runtime.getRuntime().exec(cmd);
process.waitFor();
}catch (InterruptedException e){
System.out.println(e);
}
There are all sorts of problems with this. The following line:
String[] cmd = {"regedit", "ihindi.reg"};
should pass the full path to the ihindi.reg file, not just the file name.
Also,
It is possible that a dialog box is preventing that waitFor() call from ever returning.
You should call regedit with the /s switch to silence those dialog boxes.
Also, you might consider using a ProcessBuilder like so:
import java.awt.Desktop;
import java.io.File;
import java.io.IOException;
public class RegEdit {
public static void main(String[] args) throws IOException {
// Desktop.getDesktop().open(new File("ihindi.reg"));
//you will need to figure this out
String ihindiPath = getIhindiPath();
ProcessBuilder processBuilder = new ProcessBuilder("regedit", "/s", ihindiPath)
try {
processBuilder.start().waitFor();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
I think the problem is your paths, with your current code *.reg would have to be in the same directory as the jar file. You can however set the working directory explictly when usong ProcessBuilder:
ProcessBuilder pb = new ProcessBuilder("regedit", "myreg.reg");
pb.directory("c:/");//thus our file should be located in c:\myreg.reg
Process p = pb.start();
This can achieved through Process Builder in JAVA. Please consider the following example for this:
ProcessBuilder processBuilder = new ProcessBuilder("regedit", "reg_file_to_run.reg");
Process processToExecute = processBuilder.start();
And then you can optionally wait for the completion of process execution with this line:
processToExecute.waitFor();
Note: If command in your registry file asks for confirmation prompts while making changes in registry entries, you can perform it silently as well with '/s' option. Like this:
ProcessBuilder processBuilder = new ProcessBuilder("regedit", "/s", "reg_file_to_run.reg");
Withthis command would be executed silently without any confirmation prompt.
Related
I have a problem with my Java program where I have a button that opens the command prompt and opens a batch file to run a series of commands. To do this, I need to change directory.
Here is my code:
private void CommandPromptButtonActionPerformed(java.awt.event.ActionEvent evt) {
try {
new java.lang.ProcessBuilder("cmd.exe").start();
java.lang.Runtime.getRuntime().exec(new String[]{
//I need to change the directory in command prompt and I do not want to use escape
"cmd.exe","/c","start","cd C:\Users\Faz"
});
} catch (IOException ex) {
Logger.getLogger(TMISGUIInstallerPage.class.getName()).log(Level.SEVERE, null, ex);
}
}
Any suggestions and advice are appreciated.
The following code should work
Process p = Runtime.getRuntime().exec("cmd.exe /c start cd \"C:\\Users\\Faz\" && dir");
You could change the directory in the ProcessBuilder using the ProcessBuilder#directory() and then start the process. Here is a sample code:
ProcessBuilder start = new ProcessBuilder("cmd.exe", "/c", "start");
start.directory(new File("C:\\Users"));
start.start();
Upvoted Aukta's answer, it should solve your problem.
But as you asked:
To do this, I need to change directory.
Actually with ProcessBuilder and its directory(File directory), we can easily set the working directory. Here is a simple demo to list all files in a specified directory to show you how it can be used.
public static void main(String... args) {
ProcessBuilder processBuilder = new ProcessBuilder("ls"); // pass in your command and options;
processBuilder.directory(new File("/home")); // specify you directory here;
try {
Process process = processBuilder.start();
String line = null;
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
while((line = bufferedReader.readLine()) != null) {
System.out.println(line);
}
} catch (IOException ignored) {
ignored.printStackTrace();
}
}
The output:
gitlab-runner
hearen
ubuntu
Thanks for all of your help and suggestions. I have finally found an answer. I forgot to add that I tried using Java runtime but that does not run all commands. I have found that if I add another quotation mark, I can change the directory.
private void CommandPromptButtonActionPerformed(java.awt.event.ActionEvent evt) {
try {
new java.lang.ProcessBuilder("cmd.exe").start();
java.lang.Runtime.getRuntime().exec(new String[]{
//I need to change the directory in command prompt and I do not want to use escape
"cmd.exe","/c","start","cd C:\"Users\"Faz"
});
} catch (IOException ex) {
Logger.getLogger(TMISGUIInstallerPage.class.getName()).log(Level.SEVERE, null, ex);
}
}
Thank you for all of your help. Probs submit some more questions later. Cheers!
Please know that stanford is not exe. it is a folder consists many programs
I open the cmd.exe by using following statement:
public static void runStanfordCMD() throws IOException{
List<String> cmds = Arrays.asList("cmd.exe", "/C", "start", "java", "-mx4g", "-cp", "*", "edu.stanford.nlp.pipeline.StanfordCoreNLPServer");
ProcessBuilder builder = new ProcessBuilder(cmds);
builder.directory(new File("D:/Desktop/stanford-corenlp-full-2015-12-09"));
Process proc = builder.start();
}
so how to close the cmd.exe after I finished some process?
by using ProcessBuilder or Runtime?
If using ProcessBuilder how to write the statement according to my case?
how to write the statement to the Runtime according to my case?
public static void closeStanfordCMD() throws IOException{
try {
Runtime.getRuntime().exec("command.exe /C" + "Your command"); // how to write the statement?
} catch (Exception e) {
e.printStackTrace();
}
}
The method
Runtime.getRuntime().exec
returns an object of Process.
Process has a method destroy() which kills the process you're running.
So what you need is to store the Process object returned by the exec method and call destroy() on it when you want to kill the process.
Also you can call waitFor() method to wait for the process to stop (Causes the current thread to wait, if necessary, until the process represented by this Process object has terminated).
To make it clear, try this code (or modify for your needs):
try {
Process p = Runtime.getRuntime().exec("java -mx4g -cp * D:/Desktop/stanford-corenlp-full-2015-12-09/edu.stanford.nlp.pipeline.StanfordCoreNLPServer");
p.waitFor();
}
catch (IOException e) {
e.printStackTrace();
}
catch (InterruptedException e) {
e.printStackTrace();
}
// how to write the statement?
if you want to close command prompt:
Runtime.getRuntime().exec("taskkill /IM " + "cmd.exe");
if you want to close stanford.exe:
Runtime.getRuntime().exec("taskkill /IM " + "stanford.exe");
I am writing a program in which I want to start a shell in the background, and send and receive the input and output. I already have managed to do this, and can successfully read and write to this process. This is where I run into trouble.
I would like to have a method in ShellManager (see below code) that waits until whatever the process is doing finishes/fails, and returns input to the user.
For example, if I send tar xzf something_that_will_take_a_while.tar.gz,
I can see in the output how it takes its time, and then echoes this:
]0;~
[32mMe#MyComputer [33m~[0m
I already tried blocking the thread until ]0;~ was received, this did not work. (Never returned)
I also tried \u001B, same problem :(
I'm not sure what the symbol is, and can't find much on how to detect when the process returns.
Here is my code:
package buildSystem.shell;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import base.TermConstants;
public class ShellManager {
private InputStream termOut;
private OutputStream termIn;
private ProcessBuilder build;
private Process main;
BufferedReader reader;
BufferedWriter writer;
public ShellManager() {
build = new ProcessBuilder(TermConstants.getShellLocation());
build.redirectErrorStream(true);
}
public void start() throws IOException {
try {
main = build.start();
termOut = main.getInputStream();
termIn = main.getOutputStream();
reader = new BufferedReader (new InputStreamReader(termOut));
writer = new BufferedWriter(new OutputStreamWriter(termIn));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void writeLine(String s) throws IOException {
writer.write(s);
writer.newLine();
writer.flush();
}
public String readNextLine() throws IOException {
return reader.readLine();
}
public void end() {
try {
writeLine("exit\n");
main.waitFor();
termOut.close();
termIn.close();
reader.close();
writer.close();
} catch (IOException | InterruptedException e) {
kill();
}
}
public void kill() {
main.destroyForcibly();
try {
termOut.close();
termIn.close();
reader.close();
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
/*THE PART I AM HAVING TROUBLE WITH:*/
public void waitForReturn() {
try {
while(reader.readLine() != "\u001B") {}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Basically, I want a reliable way to detect when a program exits from a bash shell. The bash process will still be running, but the program running from that bash instance will have returned. Because of this I cannot use process.waitFor().
I tried waiting for ]0;~, and then the [32mMe#MyComputer [33m~[0m, which worked until an tar exited with an error code, in which case the two lines would be reversed. I am unsure how to proceed, as detecting that bash has returned to the user should be a relatively easy task.
Thanks for your help!
If this represents the way you have been trying to match output, it's your problem:
while(reader.readLine() != "\u001B") {}
Except in special cases, you have to use the equals() method on String instances:
while (true) {
String line = reader.readLine();
if ((line == null) || "\u001B".equals(line))
break;
}
I'm not sure why you expect ESC and a newline when a process exits though.
I believe you need to call the Process.waitFor() method.
So you need something like:
Process p = build.start();
p.waitFor()
If you are trying to simulate a bash shell, allowing input of a command, executing, and processing output without terminating. There is an open source project that may be a good reference for code on how to do this. It is available on Git. Take a look at the Jediterm Pure Java Emulator.
Thinking about simulating a bash, I also found this example for Piping between processes also be be relevant.
It does show how to extract the output of a process executing and piping that data as the input into another Java Process. Should be helpful.
I'm trying to run a simple command from console using this
public void execute(File file, String... command){
Process p = null;
ProcessBuilder builder = new ProcessBuilder("ls");
builder.directory(file.getAbsoluteFile());
builder.redirectErrorStream(true);
try {
p = builder.start();
} catch (IOException e) {
LOGGER.error("", e);
}
}
but it kept saying that I cant run ls, permission denied. Is there any missing step here?
Thanks
You should use pass the commands and the flags to the constructor of the ProcessBuilder separately (as per the docs):
public void execute(File file, String... command) {
ProcessBuilder builder = new ProcessBuilder("ls", "-l");
builder.directory(file.getAbsoluteFile());
builder.redirectErrorStream(true);
try {
Process p = builder.start();
} catch (IOException e) {
LOGGER.error("", e);
}
}
It seems you want to execute command, though. To do this, you can pass command to ProcessBuilder's constructor.
public void execute(File file, String... command) {
ProcessBuilder builder = new ProcessBuilder(command);
builder.directory(file.getAbsoluteFile());
builder.redirectErrorStream(true);
try {
Process p = builder.start();
} catch (IOException e) {
LOGGER.error("", e);
}
}
Here's the ideone to the working code
You'll notice that when I run it with "ls -l", there's a problem executing the command. This is because the first argument is treated as the command to be executed and the remaining arguments are treated as flags.
To change permissions of bash commands in EC2 instances, execute
chmod u+x /home/admin/ec2-api-tools-*/bin/*
This depends on a couple of things:
1) The user that runs java (your process will be ran as that user)
2) The directory where your JAR or class resides.
Also make sure that your account has proper permissions if the java user is not the same as the user you are logged in as.
ProcessBuilder builder = new ProcessBuilder("ls -l");
There is no process named "ls -l". You want to use the process named "ls" with the arguments "-l", for that you need:
ProcessBuilder builder = new ProcessBuilder("ls", "-l");
I am trying to convert an HTML file to pdf and view it using my pdf viewer(vsmartpdf.exe).Its a cmd command which goes like "vmartpdf.exe -c 'path of html file' 'path of output folder' ". I am trying to execute this command using java program . Below is what i did.
import java.io.IOException;
public class LoadTesting implements Runnable {
#Override
public void run() {
try {
//String command = "C:\\Users\\vishalt\\Desktop\\New Source\\deliver\\vsmartpdf\\vsmartpdf.exe";
//Runtime.getRuntime().exec("cmd /c "+command);
//Process process = new ProcessBuilder("cmd.exe", "/c", "cd \"C:\\Users\\vishalt\\Vsmartfinal\" && dir").start();
Runtime rt = Runtime.getRuntime();
String[] cmd = { "C:\\Users\\Desktop\\Vsmartfinal\\vsmartpdf.exe", "-c", "C:\\Users\\vishalt\\Desktop\\output\\SCB_MOLPU.HTML", " C:\\Users\\vishalt\\Desktop\\output\\"};
Process p = rt.exec(cmd);
System.out.println("Called");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
then i am calling this thread . But i am getting error as
CreateProcess error=2, The system cannot find the file specified.
Can somebody please help me with it
The error message means that C:\Users\Desktop\Vsmartfinal\vsmartpdf.exe doesn't exist at the time when the code is executed.
A common source for this problem is that this executable exists in a developer machine but not on the production server.