msbuild, how to set environment variables?
Solution 1
A couple of things:
-
If you are only using the variable in the context of MSBuild, then you can just use the standard MSBuild variables instead of trying to set an environment variable
-
If do need to set an env var, well, it's not an out-of-box thing. You need to write a custom task and then leverage it in the project file. Here's a link to an MSDN thread that outlines how to do this.
How to set envrionment variables in MSBuild file?
Solution 2
The coded task can be put right at the project file since MSBuild v4.0. Like this:
<UsingTask
TaskName="SetEnvironmentVariableTask"
TaskFactory="CodeTaskFactory"
AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v$(MSBuildToolsVersion).dll">
<ParameterGroup>
<Name ParameterType="System.String" Required="true" />
<Value ParameterType="System.String" Required="true" />
</ParameterGroup>
<Task>
<Using Namespace="System" />
<Code Type="Fragment" Language="cs">
<![CDATA[
Environment.SetEnvironmentVariable(Name, Value);
]]>
</Code>
</Task>
</UsingTask>
Note that in MSBuild 14+, the AssemblyFile reference should be just:
AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll"
The SetEnvironmentVariableTask can be then used from the target:
<Target Name="SampleTarget" BeforeTargets="Build">
<SetEnvironmentVariableTask Name="TEST_ENV_VAR" Value="$(MSBuildProjectName)" />
</Target>
That's much handier than authoring a separate .DLL for small MSBuild task(s).
Solution 3
In the more recent versions of MS Build (since 2016), you can simply do this:
<Target Name="MyEnvironmentVariables">
<Exec Command="A command that needs environment variables" EnvironmentVariables="HANDY_ENV_VAR_1=500;HANDY_ENV_VAR_2=A Useful Value" />
</Target>
Make sure to separate the variables with a semicolon. You don't need a trailing semicolon though.
Solution 4
You might consider writing the environment variables to a text file (.cmd) as a sequence of SET XXX=$(XXX) lines. Then execute the .cmd in the command window.
e.g. Define an ItemGroup with all the SET commands, then use Task 'WriteLinesToFile' to write each item to a line in the .cmd text file.
<ItemGroup>
<BuildEnvItem Include="REM This file is auto generated. Do not edit" />
<BuildEnvItem Include="SET TEST_ENV_VAR=$(TEST_ENV_VAR)" />
<!-- add more as needed -->
<ItemGroup>
<Target Name="DefineBuildEnvironmentVariables">
<WriteLinesToFile File="Build_env.cmd" Lines="@(BuildEnvItem)" Overwrite="true" Encoding="Unicode"/>
</Target>
This is may be useful in the situation where there is an existing .cmd that is using msbuild. The initial .cmd uses msbuild to generate the Build_env.cmd, and then calls Build_env.cmd before proceeding.
Related videos on Youtube
in His Steps
Updated on September 03, 2021Comments
-
in His Steps over 1 yearI am trying to set environment variables using project file (ex. .vcxproj)
I looked at property functions but it didn't seem to have such function.
I know there is a way to retrieve environment variable but couldn't find how to set it.
I feel like there should be way to set environment variables in project file.
-
Matt Davis about 9 yearsTry as I might, I could not get this to work with Visual Studio 2012. However, I was able to find a solution here. -
ACP over 8 yearsThis seems to work only within the context of a given target; when I tried to read the env var from another target it wasn't there anymore
-
herskinduk about 8 yearsTry Environment.SetEnvironmentVariable(Name, Value, EnvironmentVariableTarget.Machine) or Environment.SetEnvironmentVariable(Name, Value, EnvironmentVariableTarget.User). The default is Environment.SetEnvironmentVariable(Name, Value, EnvironmentVariableTarget.Process)
-
herskinduk about 8 yearsMy experience was that although I could set it the environment variable I had to close/reopen VS2013 to have see the change.
-
minghan almost 7 yearsNote that in MSBuild 14, theAssemblyFilereference should be just:AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll"> -
Robert Cutajar over 6 yearsPlease include a code sample, links cannot be trusted -
Dagrooms about 3 yearsThe answer is to first invent the universe I see. This is so much more convenient than running an application from shell, and providingSET Key="Value"before starting the process. -
Michael Lowman over 2 yearsIf using msbuild on .NET core, you must use RoslynCodeTaskFactory instead. It's available since MSBuild 15.8. Some tasks may work simply by replacingCodeTaskFactorywithRoslynCodeTaskFactory.