msbuild, how to set environment variables?

32,987

Solution 1

A couple of things:

  1. 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

  2. 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.

Share:
32,987

Related videos on Youtube

in His Steps
Author by

in His Steps

Updated on September 03, 2021

Comments

  • in His Steps
    in His Steps over 1 year

    I 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
    Matt Davis about 9 years
    Try 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 years
    This 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 years
    Try 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 years
    My experience was that although I could set it the environment variable I had to close/reopen VS2013 to have see the change.
  • minghan
    minghan almost 7 years
    Note that in MSBuild 14, the AssemblyFile reference should be just: AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core‌​.dll">
  • Robert Cutajar
    Robert Cutajar over 6 years
    Please include a code sample, links cannot be trusted
  • Dagrooms
    Dagrooms about 3 years
    The answer is to first invent the universe I see. This is so much more convenient than running an application from shell, and providing SET Key="Value" before starting the process.
  • Michael Lowman
    Michael Lowman over 2 years
    If using msbuild on .NET core, you must use RoslynCodeTaskFactory instead. It's available since MSBuild 15.8. Some tasks may work simply by replacing CodeTaskFactory with RoslynCodeTaskFactory.