2
votes

I'm currently writing a bunch of batch files, and accompanying unit/integration tests to ensure that they've had the desired effects.

However one of the batch files is supposed to set an environment variable. As far as I can tell the only way to set an environment variable in DOS at the machine level is to use the SetX command:

setX My_Variable_Name My_Variable_Value -m

And that does what it's supposed to. But the catch is that because this modifies the registry, the environment variable isn't recognised as being set until after the DOS window is closed. So, the relevant bit of my code that runs the batch file looks like this:

        ProcessStartInfo p = new System.Diagnostics.ProcessStartInfo(filePath + fileToRun);
        p.WorkingDirectory = filePath;
        Process proc = new System.Diagnostics.Process();
        proc.StartInfo = p;

        proc.Start();
        proc.WaitForExit();

And then after that's been called in the unit test, I check for the environment variable as follows:

 Assert.AreSame("My_Variable_Value", Environment.GetEnvironmentVariable("My_Variable_Name"), "Primary Customers Server Name improperly set");

But this fails - stepping through it with QuickWatch reveals that Environment.GetEnvironmentVariable("My_Variable_Name") is null.

I'm somewhat confused by this behaviour. Since I'm calling WaitForExit on the process that runs the batch file, surely by the time my Assertion is called, the batch will have finished executing and the environment variable should be set? And if you open a new dos window after the test has failed and check for the existence of My_Variable_Name it's been set to the expected value.

So the code works, but I can't design a test that checks it properly. Is there anything I can do so that the test will be able to pick up the value of the environment variable?

Cheers, Matt

2

2 Answers

0
votes

OK, bit jumping through hoops, but here's how you can do it for anyone else that finds this question.

You need powershell, but it's out of the box in windows since vista, so shouldn't be a problem.

Create a powershell file that sets the environment variable:

$MyVariable = "My_Variable_Value"
[Environment]::SetEnvironmentVariable("My_Variable_Name", $MyVariable, "Machine")

Then run that from the batch file:

 powershell.exe SetEnvironmentVariable.ps1

And then the test will pass. As far as CMD is concerned the variable still doesn't exist until the process is closed but - for reasons that escape me - if you use PowerShell to set the Environment variable using the same class that the c# uses to check it, then c# is able to pick it up.

Cheers, Matt

0
votes

Typically environment variables are inherited, that means your process sees only the variables which present when the process was started.

Changes to the existing environment variables (even in the registry) can only apply to new processes.