views:

802

answers:

2

I'm having two files that I've to invoke from a java program:

  1. a batch file that sets the environment.
  2. an exe file

For running the exe, I need to have some environment variables to be set up, which am doing it with the batch file.

set MSDEV_HOME=C:\Program Files\Microsoft Visual Studio 8\VC
set FOO_ROOT=D:\UGS\Support_Dev\2005SR1
set FOO_DATA=X:
call %FOO_DATA%\FOO_profilevars
set FOO_BIN=B:
set FOO_LIB=L:
set FOO_INCLUDE=I:

FOO_profilevars in the above batch file is another batch file(this also merely sets the environment) that exists on a different hard drive.

Once the environment is set, I'll be calling the exe.

For some reasons, I've to do this separately - i cannot club these two in a another batch file or something and get the things done.

I tried executing:

ProcessBuilder pb = new ProcessBuilder("D:\\newlogin\\setup.bat");
     Process p = pb.start();
     int exitValue = p.waitFor();
     Map<String, String> env = pb.environment();
     System.out.println("exitStatus > " + exitValue);


ProcessBuilder pb2 = new ProcessBuilder("d:\\newlogin\\tcelogin.exe",
"Eid123", "Eid123");     
     Process p2 = pb2.start();
     int exitValue2 = p2.waitFor();
     Map<String, String> env2 = pb2.environment();
     System.out.println("exitStatus > " + exitValue2);

This is not working - may because the environment that is set in the first process is not used while executing the second process. Is there any way that I execute a file in the environment that is set runtime.

Update: Why separately means: 1. I've some 70env that needs to be set. So, a batch file has been preferred. 2. The EXE file will return data that needs to be processed.

...
System.out.println("Process completed");
     BufferedReader reader = null;
     int exitValue = p.exitValue();
     //System.out.println("Exit Value" + exitValue); 
     if(exitValue == 0)
     {
      reader = new BufferedReader(new InputStreamReader(p.getInputStream())); 
     }
     else
     {
      reader = new BufferedReader(new InputStreamReader(p.getErrorStream())); 
     }
     StringBuffer sb = new StringBuffer();
     String temp = reader.readLine();
     while(temp != null)
     {
      sb.append(temp);
      temp = reader.readLine();
     }

     reader.close();
     System.out.println( sb.toString());
+3  A: 

Remember that the batch file gets run in a new instance of cmd.exe, the Windows Command Interpreter. Whatever you set up in the environment there stays in that process. The next process you start will not see any of those changes since the process where they were made is long-dead by then.

You may want to either run the program at the end of the batch file, which ensures that it gets the correct environment.

Or you can just alter the environment in your Java application and then spawn the process. The environment gets inherited from the calling process, thereby the program you start will inherit the environment you set up beforehand in Java.

ETA: This comes from someone who never used Java to spawn a process. It's just how processes and their environments work in Windows. If re-using the ProcessBuilder works better, then use that. Though I still think that setting the environment from within Java is "cleaner" than using a batch file for the same purpose.

Joey
A: 

Can't you just reuse the first ProcessBuilder?

ProcessBuilder pb = new ProcessBuilder("D:\\newlogin\\setup.bat");
....
pb.command("d:\\newlogin\\tcelogin.exe", "Eid123", "Eid123");            
pb.start();
int exitValue2 = p.waitFor();
Map<String, String> env2 = pb.environment();
System.out.println("exitStatus > " + exitValue2);

Or manually append all values from the first environment which aren't already in the second environemtn

ProcessBuilder pb = new ProcessBuilder("D:\\newlogin\\setup.bat");
...
Map<String, String> env = pb.environment();
...
ProcessBuilder pb2 = new ProcessBuilder("d:\\newlogin\\tcelogin.exe",
"Eid123", "Eid123");  
Map<String, String> env2 = pb2.environment();
[PSEUDOCODE]
loop: for key,value in env
  check if key exists in env2
    if not: add (key,value) to env2
    else: check if values different and add
[/PSEUDOCODE]
pb2.start();
....
jitter
Unfortunately, I cannot. Because the pb.environment() itself is not listing the env I set in the batch file.
HanuAthena