I have a VB script to which I need to pass username and password.
I want to run this VB script through Java code programmatically.
Is there a way that I can pass the Windows credentials to the VB script in Java programmatically?
You can have the credentials on the OS environment and read them from there:
String credentials = System.getenv().get("encrypted_credentials_or_something");
And then run your command from Java. However, Runtime.exec() won't work in some cases:
When the command is not on the System's PATH
When arguments are involved
When you want to have access to the process output
When you need to be able to kill the process
When you need to check if it terminated successfully or in error (status code != 0 - which is why you write System.exit(int) to terminate a Java application. The System.exit(1), for example, indicates abnormal termination)
That's why I created this utility class to execute external processes with arguments and everything. It works very well for me:
import java.io.*;
import java.util.*;
public class ExternalCommandHelper {
public static final void executeProcess(File directory, String command) throws Exception {
InputStreamReader in = null;
try {
//creates a ProcessBuilder with the command and its arguments
ProcessBuilder builder = new ProcessBuilder(extractCommandWithArguments(command));
//errors will be printed to the standard output
builder.redirectErrorStream(true);
//directory from where the command will be executed
builder.directory(directory);
//starts the process
Process pid = builder.start();
//gets the process output so you can print it if you want
in = new InputStreamReader(pid.getInputStream());
//simply prints the output while the process is being executed
BufferedReader reader = new BufferedReader(in);
String line = null;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
int status = 0;
//waits for the process to finish. Expects status 0 no error. Throws exception if the status code is anything but 0.
if ((status = pid.waitFor()) != 0) {
throw new IllegalStateException("Error executing " + command + " in " + directory.getAbsolutePath() + ". Error code: " + status);
}
} finally {
if (in != null) {
in.close();
}
}
}
//Splits the command and arguments. A bit more reliable than using String.split()
private static String[] extractCommandWithArguments(String command) {
StringTokenizer st = new StringTokenizer(command);
String[] cmdWithArgs = new String[st.countTokens()];
for (int i = 0; st.hasMoreTokens(); i++) {
cmdWithArgs[i] = st.nextToken();
}
return cmdWithArgs;
}
}
Related
I'm launching from my jar 3 programs with their own parameters.
First and second programs do their job, but not the second one.
Here the code
Runtime rt = Runtime.getRuntime();
String cmdGet= "something";
try {
infolog("Executing command: " + cmdGet);
rt.exec(cmdGet);
}
catch(Exception ex){
infolog("Unable to launch program 2");
saveLog();
}
Here the command for something
D:\Root\Module\Translators\L2Fo\SE_Draft_Update.exe -se_file="F:\Disp\Stage\DC\Ude34ea24x591ecb1c412x\M8486.dft" -input_file="F:\Disp\Stage\DC\Ude34ea24x591ecb1c412x\result\AttributeFile_M8486.txt" -log_file="F:\Disp\Stage\DC\Ude34ea24x591ecb1c412x\result\SELogg_M8486.txt"
In the log I find the proper command launched, but I see that its jobs are not done. So by copying the string manually in the cmd prompt it works
The third program after this one works too.
I do not understand why.
Sometimes a command needs its own cmd-shell.
Then you had to add a "CMD.EXE /C " prefix. This is the reason why
the 'something' line works fine in the cmd-Window.
if (b_shell == true) cmd = "CMD.EXE /C " + cmdstr;
else cmd = cmdstr;
...
rt.exec(cmd);
I pass the b_shell as argument to a wrapper method:
public static void systemCall(String cmdstr,boolean b_shell,Path logfile) throws IOException
Sorry for that answer, perhaps you like to try a version which
is able to wait for the terminating command and returns the output of the command as an ArrayList.
/**
* Executes command 'cmdstr'. The output of the command is stored in a ArrayList-String array
* #param cmdstr The command line to be executed not containing a redirect to an outputfile ( > x.txt )
* #param b_wait If true the command waits until it is finished and 'errmsg' contains the exit value
* #param b_shell If true the command will be started in a shell (uses prefix CMD.EXE /C)
* #param errmsg OUT: Error message
* #return ArrayList-String output or null on error, see errmsg
* #since Last change: 2014.04.30
*/
public static ArrayList<String> systemCallOutputArray(String cmdstr,boolean b_wait,boolean b_shell,/*IO*/StringBuffer errmsg)
{
final String fn="systemCallOutputArray()";
errmsg.setLength(0);
if (cmdstr == null || cmdstr.isEmpty()) { errmsg.append(fn + ": Invalid arg. 'cmdstr' (null or empty)"); return null; }
ArrayList<String> output = new ArrayList<String>();
String cmd ="";
try
{
int exit_value = -1;
Runtime r = Runtime.getRuntime();
Process p = r.exec(cmd);
String line="";
if (b_wait == true)
{
p.waitFor(); // waits until prozess is terminated, throws InterruptedException if wait is interrupted
exit_value = p.exitValue();
BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));
while ((line = input.readLine()) != null)
{ if (line.isEmpty() == false) output.add(line);
}
input.close();
return output;
}
// the following lines are for b_wait = false
BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));
while ((line = input.readLine()) != null)
{ if (line.isEmpty() == false) output.add(line);
}
input.close();
return output;
}
catch (Exception e)
{
errmsg.append(fn + " failed: " + e.toString() + " cmd: '" + cmd + "'");
return null;
}
} //---------------- end of systemCallOutputArray()
Created this function to input unix commands and output the outputs of that unix command. But, I am having trouble with the unix commands I use. "ls" works to output the list of files, but if I do "ls -lart" it will output null. Having trouble further debugging or why this doesn't work. Code below.
private String[] unixCommand (String command, Boolean boolOutput) throws IOException, InterruptedException{
Process run;
int i = 0;
String output = "";
String[] finalOutput = new String[1000];
sendToProcessView("Unix Command: " + command);
run = Runtime.getRuntime().exec(command);
run.waitFor();
sendToProcessView("In Unix Command");
if (boolOutput == true){
sendToProcessView("In Output Mode of Unix Command");
BufferedReader stdInput = new BufferedReader(new InputStreamReader(run.getInputStream()));
sendToProcessView("Passed Buffer Reader");
while ((output = stdInput.readLine()) != null) {
sendToProcessView("Output: " + output);
finalOutput[i] = output;
i++;
}
}
return finalOutput;
}
When interacting with the console, you should exec the console itself, and then use the Process input stream to send commands, eg (pseudocode - I'm not set up to test java code from my location, sorry)
sendToProcessView("Unix Command: " + command);
run = Runtime.getRuntime().exec("bash");
PrintStream in = new PrintStream(run.getOutputStream());
in.println("ls -lart");
You can then shut the process down by sending "exit" and reading the results the way you were, or using a threaded listener, like DataFetcher
I am trying to untar a file on a Unix machine, using a Java batch application.
Source Code:
String fileName = "x98_dms_12";
Runtime.getRuntime().exec("gunzip "+ fileName + ".tar.gz");
System.out.println(" Gunzip:"+"gunzip "+ fileName + ".tar.gz");
Runtime.getRuntime().exec("tar -xvf "+ fileName + ".tar");
System.out.println(" Extract:tar -xvf "+ fileName + ".tar");
Problem Description:
When I run the batch program it does not (completely) work. Only the gunzip command works, converting my fileName.tar.gz to fileName.tar. But the untar command does not seem to do anything, and there is no error or exception in my log or Unix console.
When I run the same commands in a Unix prompt they work fine.
Notes:
The path of execution is correct because it converts my *.tar.gz to *.tar
I cannot use "tar -zxvf fileName.tar.gz" since the attribute "z" does not work on my system.
There is no error or exception thrown.
Please do help.
A couple of things:
The tar command will expand a file relative to your working directory, which might need to be set for your Java Process objects
You should wait for the unzip process to complete before launching into the untar process
You should process the output streams from the processes.
Here is a working example that you can extend/adapt. It uses a separate class to deal with the process output streams:
class StreamGobbler implements Runnable {
private final Process process;
public StreamGobbler(final Process process) {
super();
this.process = process;
}
#Override
public void run() {
try {
final BufferedReader reader = new BufferedReader(
new InputStreamReader(process.getInputStream()));
String line = null;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
reader.close();
} catch (final Exception e) {
e.printStackTrace();
}
}
}
public void extractTarball(final File workingDir, final String archiveName)
throws Exception {
final String gzFileName = archiveName + ".tar.gz";
final String tarFileName = archiveName + ".tar";
final ProcessBuilder builder = new ProcessBuilder();
builder.redirectErrorStream(true);
builder.directory(workingDir);
builder.command("gunzip", gzFileName);
final Process unzipProcess = builder.start();
new Thread(new StreamGobbler(unzipProcess)).start();
if (unzipProcess.waitFor() == 0) {
System.out.println("Unzip complete, now untarring");
builder.command("tar", "xvf", tarFileName);
final Process untarProcess = builder.start();
new Thread(new StreamGobbler(untarProcess)).start();
System.out.println("Finished untar process. Exit status "
+ untarProcess.waitFor());
}
}
The code below will print the output of the command executed. Check if it returns any error.
Process p = Runtime.getRuntime().exec("tar -xvf "+ fileName + ".tar");
BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = null;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
The problem is the commands which we give is UNIX command so it wont work in windows environment. I had written a script file to overcome this problem thanks all for you help. The Runtime.getRuntime.exec() will take some time to execute the command given so after each exec() give thread.wait(3000) to complete the process and goto next thread.
I've been trying to make it where I can download a .exe file from the web, read it, and write it to a file locally, and then execute.
URL url = new URL("http://www.ddlands.com/downloads/Calc.exe");
URLConnection c = url.openConnection();
BufferedReader br = new BufferedReader(new InputStreamReader(c.getInputStream()));
String line = "";
File file = new File("analbread"+".exe");
BufferedWriter bw = new BufferedWriter(new FileWriter(file));
while((line = br.readLine()) != null){
bw.write(line + "\n");
}
br.close();
bw.close();
Process r = Runtime.getRuntime().exec("analbread" + ".exe");
System.out.println(r.toString());
System.out.println("WORKS!");
Although I know that doesn't work due to using BufferedWriter, and i'm not sure if it runs the exe.
For the downloading part, you'll need to use binary read/write. See this for further details: Working unbuffered streams.
For the executing part, the problem is that the Runtime.exec()-method can't launch your executable file.
At least under Linux (I can't test it on Windows), you'll need the full path to the executable file (or use ./[file] when the file is in the same directory as your application) to be able to execute it.
Only giving the command works for executables which are part of your systems PATH-variable.
Have a look at ClickOnce: http://en.wikipedia.org/wiki/ClickOnce
We've used that succesfully.
Ive used the following with good results to run command line scripts. You can create a batch script that runs the executable or run it directly using the exec method - probably pass "cmd ". This opens a command prompt from which you can run anything.
public static void runScript(String batchFile, boolean waitForExit0, int retryTime)
{
try
{
String runString = "cmd /c start " + (waitForExit0?"/wait ":"") + "/MIN " + batchFile;
Process p = Runtime.getRuntime().exec(runString); // /c start /wait
while (true)
{
try
{
int exit = p.exitValue();
if (exit == 0)
{
System.out.println("completed: " + runString);
return;
}
}
catch(Exception e)
{
String s = "";
}
Thread.sleep(retryTime);
}
}
catch(Exception e)
{
String s = "";
}
}
I want to run a C/C++ program's exe file using java.......and handle its input and output......
my code is
import java.io.*;
class run2 {
public static void main(String[] args) throws java.io.IOException {
String[] command = new String[3];
command[0] = "cmd";
command[1] = "/C";
// command[2] = "java Run1";
command[2] = "start C:\\WE.EXE";
Process p = Runtime.getRuntime().exec(command);
String i = "20";
BufferedReader stdInput = new BufferedReader(new InputStreamReader(
p.getInputStream()));
BufferedWriter st = new BufferedWriter(new OutputStreamWriter(
p.getOutputStream()));
String s = null;
System.out.println("Here is the standard output of the command:\n");
s = stdInput.readLine();
System.out.println(s);
st.write(i);
st.newLine();
st.flush();
while ((s = stdInput.readLine()) != null) {
System.out.println("Stdout: " + s);
}
try {
System.out.println("Exit status = " + p.waitFor());
}
catch (InterruptedException e) {
}
stdInput.close();
}
}
i am getting an error which says pipes is closed
do help me out.....
Well, first of all, if there isn't a WE.EXE in C:/, that could be an issue. If no process is ever launched, of course you can't do anything with its input/output pipes.
However, presuming you have a WE.EXE, your error is probably at:
st.flush();
Your application is opening up WE.EXE in command prompt, or cmd.exe, who will take care of both standard input and standard output. Your call stdInput.readLine(); will wait until WE.EXE, and therefore cmd.exe, terminates, at which point the output stream will be closed (and you obviously can't write onto a closed pipe).
So if you want to handle input and output yourself, you should launch WE.exe directly, like:
Process p = Runtime.getRuntime().exec("C://WE.EXE");
Additionally, you may consider using ProcessBuilder instead of Runtime.exec.
Small detail, but consider using Java's naming conventions--for example, your class name would be Run2 (or something more descriptive) instead of run2.
You are trying to read from a stream (stdInput) that does not exist yet.
It won't exist until the WE.EXE program writes something to it.
Just wait until you send the commands to the program.
In other words, take out the first input line, and it will work fine.
//s = stdInput.readLine();
System.out.println(s);
st.write(i);
st.newLine();
st.flush();
while ((s = stdInput.readLine()) != null)
{ System.out.println("Stdout: " + s); }