During my forays into the MSDN TFS Forums, I came across a question from someone trying to set an environment variable in the build and retrieve it from a called MSBuild task. A problem arose when the called MSBuild task was seeing the old value of the environment variable instead of the new value. This perplexed the writer for a bit until a few pieces of information came together to shed some light on what was going on.
Here's a couple of tidbits that will help to explain this situation:
- The Windows OS fires a "An Environment Variable Has Changed" event (no, not the real name) when an environment variable is created or changed.
- When a process starts, Windows gives it a copy of all of the environment variables in force at that moment.
- When the MSBuild task is invoked from within an MSBuild file, the newly invoked MSBuild is run in the same process space as the existing MSBuild.
In this case, what occurred was:
- The initial MSBuild process was created and Windows gave it a copy of the environment variables as they existed at that moment.
- During the MSBuild run, one of those environment variables was updated to a new value.
- The MSBuild process wasn't written to listen for the "An Environment Variable Has Changed"message, so the change went unnoticed.
- A new MSBuild task was fired within the existing process, so it only had access to the old version of the environment variable.
The writer wanted the spawned MSBuild to utilize the new environment variable value when it compiled his solution.
If you have a need invoke MSBuild and have it pick up a recently modified environment variable, you should fire MSBuild.exe with an Exec task. This will run the spawned MSBuild.exe in its own process, thus getting an updated set of environment variables to play with.