Reputation: 455
I want to use ProcessBuilder to create an environment that I can reuse for multiple batch files, in order to automate some testing I repeatedly perform. Specifically, I need to run vcvars64.bat
(x64 Native Tools Command Prompt for VS 2019) to set up the system environment, before I run my tests.
To manually run the tests, I would bring up a command prompt, run vcvars64.bat, and then manually run a number of batch files.
I have been able to use ProcessBuilder to launch my test batch files, but they return the error that I see if I forgot to run vcvars64.bat before running the tests.
My attempts so far have been to instantiate a ProcessBuilder using vcvars64.bat as the command, .start()
it, .waitFor()
the Process to finish, then reuse that same ProcessBuilder for Test1.bat then Test2.bat etc, in the hopes it would retain the environment settings.
Here is the relevant section of my code:
ProcessBuilder processBuilder = new ProcessBuilder();
Process process;
Map<String, String> envMap = processBuilder.environment();
for( Map.Entry<String, String> entry : envMap.entrySet() )
{
System.out.println( "1 - Key: \"" + entry.getKey() + "\", Value: \"" + entry.getValue() + "\"" );
}
try
{
process = processBuilder.command( "C:\\Windows\\system32\\cmd.exe", "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Enterprise\\VC\\Auxiliary\\Build\\vcvars64.bat" )
.directory( new File( "C:\\bat\\" ) )
.redirectInput( new File( "C:\\bat\\", "cr4.txt" ) )
.redirectOutput( new File( edgePath, "tempFile.txt" ) )
.start();
MAIN_LOGGER.log( Level.INFO, "Waiting for the CMD process to finish..." );
process.waitFor();
envMap = processBuilder.environment();
for( Map.Entry<String, String> entry : envMap.entrySet() )
{
System.out.println( "2 - Key: \"" + entry.getKey() + "\", Value: \"" + entry.getValue() + "\"" );
}
// Now try to run my batch file that requires parameters normally set by vcvars64.bat
process = processBuilder.command( "C:\\bat\\TestBatch.bat" )
.directory( new File( "C:\\bat\\" ) )
.redirectInput( new File( "C:\\bat\\", "cr4.txt" ) )
.redirectOutput( new File( "C:\\bat\\", "tempFile.txt" ) )
.start();
}
catch( IOException | InterruptedException e )
{
System.out.println( e.getLocalizedMessage() );
}
Is my plan correct, and my implementation buggy? Or do I need a new plan?
Upvotes: 1
Views: 646
Reputation: 15136
Unfortunately processBuilder.environment() won't pick up any changes inside the VC bat file so your double launch won't help. However depending on what vcvars64.bat looks like you may be able to package up your own launch.cmd
file which you call passing two parameters: path to VC batch, and the path to your actual script to run. Then your ProcessBuilder command is just something like:
String launch = "C:\\bat\\launch.cmd";
String vcenv = "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Enterprise\\VC\\Auxiliary\\Build\\vcvars64.bat";
String task = "C:\\bat\\TestBatch.bat";
String[] cmd = new String[] {"cmd.exe", "/c", launch, vcenv, task};
process = processBuilder.command(cmd);
Example launch.cmd:
call %1
call %2
exit /b %errorlevel%
Example task.bat:
echo RUNNING TASK %0
Upvotes: 1