I'm trying to do something very simple here, but it isn't working.
Basically I have a program and an input file sitting at a certain directory, let's call it "programDir".
I'm writing a plugin in Eclipse that will call this program and run it on the input file.
Essentially two steps must be done: 1) cd to programDir 2) run the program by calling "idp input.txt"
I have done this manually in the cmd and it works as expected. However in Java I can't get it to work. I tried 2 approaches:
Runtime rt = Runtime.getRuntime();
Process proc = rt.exec("cmd.exe /c cd \""+programDir+"\" & \"idp input.txt\"");
Here I get the following from the errorStream: "idp output.txt" is not recognized as an intern or extern command, program or batch file
I'm not sure why. I have left out the second part of the command to ensure that I am in the correct location. When i add "start", a console window pops up and it is in the programDir folder. If I then manually type "idp input.txt" I get the expected behavior.
Second approach:
I also used ProcessBuilder after some googling on the subject. I tried this piece of simple code:
String[] command = {"CMD", "/C", "idp input.txt"};
ProcessBuilder pb = new ProcessBuilder(command);
pb.directory(new File(programDir));
Process proc = pb.start();
Now nothing happens and the program does not terminate.
Again, if I add "start" as one of the parameters in "command", a console window pops up in the right location and if I then manually type "idp input.txt", it works. So I have no idea why the code doesn't work.
One interesting thing: the idp.bat file calls a kbs.exe process. When I run the second piece of code, no kbs.exe appears in my task manager. However, as soon as I terminate the program, it briefly makes an appearance. Does that mean my code gets stuck in a loop somewhere or something?
Any help appreciated!
Related
I'm using Intellij IDEA and i'm trying to run a shell script with arguments, and read the result of the execution.
this script is on my java SRC packge,
myScript.sh run a compiled c program
String[] cmd = { "/bin/bash", "-c", "myScript" };
Runtime.getRuntime().exec(cmd);
i resolved this by making a copy of myScript.sh in /ect/bin.
so this make my script as an environment path and give me the ability to read all the out put or add supplement arguments.
no changes has been made
on my Java code
.
Use ProcessBuilder:
Process process = new ProcessBuilder(cmd).start();
Then process.getInputStream() gives you access to the process standard output (stdout) which you can read as usual; process.getErrorStream() allows to read standard error (stderr).
Also you can do process.waitFor() to wait for the project to finish.
Note that to read anything from the stdout of a process you need to wait for the process to finish (or read it in a loop) and not just finish your main program.
I'm trying to use Process and ProcessBuilder to execute a ps1 file through powershell. I'm struggling with the entire thing and cant even get the powershell.exe to run. Ive tried :
// Wont Run
// Defined specific path for powershell - trying to simply run the exe file
ProcessBuilder pb = new ProcessBuilder("C:\\Windows\\system32\\WindowsPowerShell\\v1.0\\powershell.exe");
Process p = pb.start();
I've look at Running Powershell from Java and Run a powershell on a remote machine using JAVA trying to implement methods from these examples but I dont understand why mine wont even run an instance of powershell.
I do eventually want to incorporate running ps1 files through here but I need to walk before I can run.
Also, I have checked Task Manager and it IS running as a process.
Could anyone point me in the right direction as to why this wont even run ?
Thanks in advance
I have to execute a xyz.cmd file which is in a directory E:/abc. So the absolute path of the file to be executed is E:/abc/xyz.cmd. When executed, a new window is created by the file itself.
My code snippet is:-
String path = “E:\\abc”;
String cmd = path + “\\xyz.cmd”;
ProcessBuilder processBuilder = new ProcessBuilder(cmd);
processBuilder.redirectErrorStream(true);
processBuilder.directory(new File(path));
processBuilder.start();
This does not work, but gives no error or exception. But the cmd file works fine, it can be executed manually from its directory using explorer or cmd-prompt.
Tried using different versions of jdk, but in vain. I am using windows 7 OS. I do not see the process running in the Task Manager also.
Any idea what is going wrong? The same code works fine in a different computer with the same config.
===EDIT====
Can this be a security issue? Something like the user executing the program is not having enough priveleges to execute a file?
You need to call cmd.exe as first part of your process builder String in order for the command processor to be able to call the .cmd file. This is also true for .bat files, or any OS type command. For example, please look here.
Also, please look here: When Runtime.exec() won't
Edit
You state:
please understand, this is not the problem of not adding cmd.exe in the processbuilder; because of the previous commands, cmd.exe will be taken care.
I see no documentation in your posts so far that this is true, and all my experience strongly suggests otherwise.
You also state:
Can this be a security issue? Something like the user executing the program is not having enough priveleges to execute a file?
No way to know unless you capture and display the process's input stream. In fact if you don't capture this stream, you could prevent your process from functioning at all. Often we have to also capture the error stream as well, but you've combined them with
processBuilder.redirectErrorStream(true)
Please read my "When Runtime.exec() won't" link above for more on the necessity of capturing streams.
Both, Runtime.exec() as well as ProcessBuilder seem to attach a console to the started process. On Windows 7, one can see a conhost.exe popping up in the Task Manager. My problem is now that the C process I'm trying to start performs following test to determine whether it has a console window to which it can issue prompts:
HANDLE cons = CreateFile("CONOUT$", GENERIC_WRITE,
FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, NULL);
if (cons != INVALID_HANDLE_VALUE) {
// Prompt user; this makes my application hang
}
Is it possible with Java to start the C process in a way that upper test fails in order to avoid the prompt?
At least on OpenJDK 6, CreateProcess is being called with CREATE_NO_WINDOW. I would imagine that the Sun JDK's code is pretty similar. This makes me wonder if something else is causing that console to be present. Have you tried running your program with javaw.exe instead of java.exe?
Thinking outside of the box, maybe JGit is a better way to solve your particular problem.
Try this:
ProcessBuilder pb = new ProcessBuilder( "cmd", "/C start /B myprogram.exe param1 param2" );
The /B flag tells start to not create a new console, though I don't know whether or not start itself will end up allocating a console when called from Java.
Using Runtime is tricky cause you need to consume the output and input with streams.. See this article:
http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html
Instead try using the exec library of apache commons.. Here's something that will get you started:
http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html
I want to set a path in my Java program with this Windows command (this path contains some DLL files that are used in a native peripheral of my program):
c:\>path=%path%;"C:\Users\NetBeansProjects\IPTV1.7\3rd_party"
But this causes an exception when the program runs:
java.io.IOException: Cannot run program "path=%path%;C:\Users\NetBeansProjects\IPTV1.7\3rd_party\": CreateProcess error=2, The system cannot find the file specified
I don't know why I can set the path with no problem in the command prompt but then get an exception thrown in the code.
String path = "C:\\Users\\NetBeansProjects\\IPTV1.7\\3rd_party\\";
Runtime rt = Runtime.getRuntime();
Process p = rt.exec("path=%path%;"+ path);
Your command
path=%path%;"C:\Users\NetBeansProjects\IPTV1.7\3rd_party"
is not a "real" windows command, but only a variable assignment, interpreted by your shell (cmd.exe), visible only in the same shell session and any commands (other programs) started from there.
When trying to execute this from Java with Runtime.exec(), the windows CreateProcess function tries to find a executable file with this strange name, which obviously does not exist (can't exist, I think), and you get this error.
Even if you could execute this, for example by calling cmd.exe, it would only influence this same cmd.exe process (and any programs started from there, not your own Java process (and programs started from here).
Depending on what you in fact want, you could, for example:
give the path with ProcessBuilder directly to the process which in fact needs it (like Aaron showed)
search by yourself for executable files, if you want this for finding commands in the next exec
put the variable assignment and other commands together in a .BAT or .CMD file and execute this.
When you type this on the command prompt, the cmd program processes it and changes the PATH variable for you. When you try this with Runtime, no cmd process is created and there is no command "path=%path%;C:\Users\NetBeansProjects\IPTV1.7\3rd_party\" on your harddisk (Windows actually tries to find a program with this exact name).
Put the commands in a .BAT or .CMD file. Windows automatically creates a cmd process to execute them for you.
You can use ProcessBuilder in java to spawn a process and control the environment that it gets. So you would use the ProcessBuilder environment method to set the PATH environment variable, then set the relevant command line, then launch. SO something like (untried):
ProcessBuilder b = new ProcessBuilder();
b.environment().put("PATH", whatever);
b.command(whatever);
Process p = b.start();