2

I have a batch file setEnv.bat.

@echo off
set input=C:\Program Files\Java\jdk1.8.0_131
SET MY_VAR=%input%

I want to run this batch file from C# application and want to access the newly set value of MY_VAR from c# application.

C#:

System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.StartInfo.FileName= "D:\\Check\\SetJavaHome.bat";
proc.StartInfo.WorkingDirectory = 
System.Environment.CurrentDirectory;
proc.Start();

string myVar = Environment.GetEnvironmentVariable("MY_VAR");

Can someone help me in getting this working as expected?

Thanks in advance.

5
  • 2
    you can access the variable only if it's written in the registry with SETX or if the program called from the batch file. Commented Aug 25, 2017 at 11:45
  • I am calling the batch file from C# program. Commented Aug 25, 2017 at 11:52
  • You could read the file as text, and just use regex to parse the file and get the value :p Commented Aug 25, 2017 at 12:10
  • 2
    @npocmaka I don't think SETX will work: it sets the master environment, so new processes/shells will see the new value, but the (already running) C# program won't see any changes. Commented Aug 25, 2017 at 13:43
  • 2
    @Ashley You can't do it this way. The environment changed by the batch file will only be visible within the batch file and anything it calls -- it will never affect the C# process that called it. The point of using environment variables inside a program is that they are set outside the program before it is started. Either have a batch file that calls your existing batch file and then launches the C# program or use `Environment.SetEnvironmentVariable() inside your C# program (either reading the value from a file or configuration setting or parsing the existing batch file as Derek says Commented Aug 25, 2017 at 13:52

2 Answers 2

3

Check out this answer with the sample code: https://stackoverflow.com/a/51189308/9630273

Getting the Environment variables directly from another process is not possible, but a simple workaround can be like:

Create a dummy bat file (env.bat) that will execute the required bat and echo the environment variable. Get the output of this env.bat inside the process execution of C#.

Sign up to request clarification or add additional context in comments.

Comments

1

The reason why you want to do this is a bit vague but if your only option is to run that batchfile from a call to Process.Start then the following trickery will let you promote the environment vars from the batch file to your own process.

This is the batch file I use:

set test1=fu
set test2=bar

The followng code opens a standard Command Prompt and then uses the StandardInput to send commands to the command prompt and receive the results with OutputDataReceived event. I basically caputure the output of the SET command and the parse over its result. For each line that contains an environment var and value I call Environment.SetEnvironmentVaruable to set the environment in our own process.

var sb = new StringBuilder();
bool capture = false;

var proc = new Process();
// we run cms on our own
proc.StartInfo.FileName = "cmd";
// we want to capture and control output and input
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.RedirectStandardInput = true;

// get all output from the commandline
proc.OutputDataReceived += (s, e) => { if (capture) sb.AppendLine(e.Data); };

// start
proc.Start();
proc.BeginOutputReadLine(); // will start raising the OutputDataReceived

proc.StandardInput.WriteLine(@"cd \tmp"); // where is the cmd file
System.Threading.Thread.Sleep(1000); // give it a second
proc.StandardInput.WriteLine(@"setenv.cmd"); // run the cmd file
System.Threading.Thread.Sleep(1000); // give it a second

capture = true; // what comes next is of our interest
proc.StandardInput.WriteLine(@"set"); // this will list all environmentvars for that process
System.Threading.Thread.Sleep(1000); // give it a second
proc.StandardInput.WriteLine(@"exit"); // done
proc.WaitForExit();

// parse our result, line by line
var sr = new StringReader(sb.ToString());
string line = sr.ReadLine();
while (line != null)
{
    var firstEquals = line.IndexOf('=');
    if (firstEquals > -1)
    {
        // until the first = will be the name
        var envname = line.Substring(0, firstEquals);
        // rest is the value
        var envvalue = line.Substring(firstEquals+1);
        // capture what is of interest
        if (envname.StartsWith("test"))
        {
            Environment.SetEnvironmentVariable(envname, envvalue);
        }
    }
    line = sr.ReadLine();
}
Console.WriteLine(Environment.GetEnvironmentVariable("test2")); // will print > bar

This will bring the environment variables that are set by a command file into your process.

Do note you can achieve the same by creating a command file that first calls your batchfile and then start your program:

rem set all environment vars
setenv.cmd 
rem call our actual program
rem the environment vars are inherited from this process
ConsoleApplication.exe 

The latter is easier and works out of the box, no brittle parsing code needed.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.