none
How to set envrionment variables in MSBuild file?

    Question

  • Experts,
       In a msbuild file, How do I set a environment variable?

    Thanks,
    Tuesday, August 16, 2005 2:57 AM

Answers

  • I wrote a task to do this.  It is pretty simple:



    using System;
    using System.Collections.Generic;
    using System.Text;
    using Microsoft.Build.Framework;
    using Microsoft.Build.Utilities;

    namespace MSBuildTasks
    {
        public class SetEnvVar : Task
        {
            private string _variable;
            private string _value;

            [Required]
            public string Variable
            {
                get { return _variable; }
                set { _variable = value; }
            }

            [Required]
            public string Value
            {
                get { return _value; }
                set { _value = value; }
            }
     
            public override bool Execute()
            {
                Environment.SetEnvironmentVariable(_variable, _value);
                return true;
            }
        }
    }

     



    Use it like so:



     <UsingTask TaskName="MSBuildTasks.SetEnvVar"
             AssemblyFile="$(RootDir)Tools\Bin\MSBuildTasks.dll"/>

     <PropertyGroup>
      <DevEnvDir>$(VS80COMNTOOLS)..\IDE</DevEnvDir>
      <VsInstallDir>$(VS80COMNTOOLS)..\..</VsInstallDir>
      <VcInstallDir>$(VS80COMNTOOLS)..\..\VC</VcInstallDir>
      <FrameworkDir>$(windir)\Microsoft.NET\Framework</FrameworkDir>
      <FrameworkVersion>v2.0.50712</FrameworkVersion>
      <FrameworkSDKDir>$(VsInstallDir)\SDK\v2.0</FrameworkSDKDir>
      <PATH>$(DevEnvDir);$(VcInstallDir)\BIN;$(VS80COMNTOOLS);$(VS80COMNTOOLS)Bin;$(VcInstallDir)\PlatformSDK\bin;$(FrameworkSDKDir)\bin;$(FrameworkDir)\$(FrameworkVersion);$(VcInstallDir)\VCPackages;$(PATH)</PATH>
      <INCLUDE>$(VcInstallDir)\ATLMFC\INCLUDE;$(VcInstallDir)\INCLUDE;$(VcInstallDir)\PlatformSDK\include;$(FrameworkSDKDir)\include;$(INCLUDE)</INCLUDE>
      <LIB>$(VcInstallDir)\ATLMFC\LIB;$(VcInstallDir)\LIB;$(VcInstallDir)\PlatformSDK\lib;$(FrameworkSDKDir)\lib;$(LIB)</LIB>
      <LIBPATH>$(FrameworkDir)\$(FrameworkVersion)</LIBPATH>
     </PropertyGroup>

     <Target Name="PrepareBuildEnvironment">
      <!-- To dump the env run msbuild with /p:DumpEnv=y switch -->
      <SetEnvVar Variable="DevEnvDir" Value="$(DevEnvDir)"/>
      <SetEnvVar Variable="VsInstallDir" Value="$(VsInstallDir)"/>
      <SetEnvVar Variable="VcInstallDir" Value="$(VcInstallDir)"/>
      <SetEnvVar Variable="FrameworkDir" Value="$(FrameworkDir)"/>
      <SetEnvVar Variable="FrameworkVersion" Value="$(FrameworkVersion)"/>
      <SetEnvVar Variable="FrameworkSDKDir" Value="$(FrameworkSDKDir)"/>
      <SetEnvVar Variable="PATH" Value="$(PATH)"/>
      <SetEnvVar Variable="INCLUDE" Value="$(INCLUDE)"/>
      <SetEnvVar Variable="LIB" Value="$(LIB)"/>
      <SetEnvVar Variable="LIBPATH" Value="$(LIBPATH)"/>
      <Warning Condition="!Exists('$(FrameworkDir)\$(FrameworkVersion)')" Text="Framework dir '$(FrameworkDir)\$(FrameworkVersion)' doesn't exist. Check version number."/>
      <Message Condition="'$(DumpEnv)' != ''" Text="DumpEnv Requested:" />
      <Exec Condition="'$(DumpEnv)' != ''" Command="set" />
     </Target>

     


    Thursday, August 18, 2005 5:37 PM

All replies

  • You'd have to write a task - there's no way to set environment variables by default.

    But what is your scenario?  What are you trying to do that you wish to use environment variables for?

    jeff
    tester on msbuild

    Thursday, August 18, 2005 2:19 AM
    Moderator
  • I wrote a task to do this.  It is pretty simple:



    using System;
    using System.Collections.Generic;
    using System.Text;
    using Microsoft.Build.Framework;
    using Microsoft.Build.Utilities;

    namespace MSBuildTasks
    {
        public class SetEnvVar : Task
        {
            private string _variable;
            private string _value;

            [Required]
            public string Variable
            {
                get { return _variable; }
                set { _variable = value; }
            }

            [Required]
            public string Value
            {
                get { return _value; }
                set { _value = value; }
            }
     
            public override bool Execute()
            {
                Environment.SetEnvironmentVariable(_variable, _value);
                return true;
            }
        }
    }

     



    Use it like so:



     <UsingTask TaskName="MSBuildTasks.SetEnvVar"
             AssemblyFile="$(RootDir)Tools\Bin\MSBuildTasks.dll"/>

     <PropertyGroup>
      <DevEnvDir>$(VS80COMNTOOLS)..\IDE</DevEnvDir>
      <VsInstallDir>$(VS80COMNTOOLS)..\..</VsInstallDir>
      <VcInstallDir>$(VS80COMNTOOLS)..\..\VC</VcInstallDir>
      <FrameworkDir>$(windir)\Microsoft.NET\Framework</FrameworkDir>
      <FrameworkVersion>v2.0.50712</FrameworkVersion>
      <FrameworkSDKDir>$(VsInstallDir)\SDK\v2.0</FrameworkSDKDir>
      <PATH>$(DevEnvDir);$(VcInstallDir)\BIN;$(VS80COMNTOOLS);$(VS80COMNTOOLS)Bin;$(VcInstallDir)\PlatformSDK\bin;$(FrameworkSDKDir)\bin;$(FrameworkDir)\$(FrameworkVersion);$(VcInstallDir)\VCPackages;$(PATH)</PATH>
      <INCLUDE>$(VcInstallDir)\ATLMFC\INCLUDE;$(VcInstallDir)\INCLUDE;$(VcInstallDir)\PlatformSDK\include;$(FrameworkSDKDir)\include;$(INCLUDE)</INCLUDE>
      <LIB>$(VcInstallDir)\ATLMFC\LIB;$(VcInstallDir)\LIB;$(VcInstallDir)\PlatformSDK\lib;$(FrameworkSDKDir)\lib;$(LIB)</LIB>
      <LIBPATH>$(FrameworkDir)\$(FrameworkVersion)</LIBPATH>
     </PropertyGroup>

     <Target Name="PrepareBuildEnvironment">
      <!-- To dump the env run msbuild with /p:DumpEnv=y switch -->
      <SetEnvVar Variable="DevEnvDir" Value="$(DevEnvDir)"/>
      <SetEnvVar Variable="VsInstallDir" Value="$(VsInstallDir)"/>
      <SetEnvVar Variable="VcInstallDir" Value="$(VcInstallDir)"/>
      <SetEnvVar Variable="FrameworkDir" Value="$(FrameworkDir)"/>
      <SetEnvVar Variable="FrameworkVersion" Value="$(FrameworkVersion)"/>
      <SetEnvVar Variable="FrameworkSDKDir" Value="$(FrameworkSDKDir)"/>
      <SetEnvVar Variable="PATH" Value="$(PATH)"/>
      <SetEnvVar Variable="INCLUDE" Value="$(INCLUDE)"/>
      <SetEnvVar Variable="LIB" Value="$(LIB)"/>
      <SetEnvVar Variable="LIBPATH" Value="$(LIBPATH)"/>
      <Warning Condition="!Exists('$(FrameworkDir)\$(FrameworkVersion)')" Text="Framework dir '$(FrameworkDir)\$(FrameworkVersion)' doesn't exist. Check version number."/>
      <Message Condition="'$(DumpEnv)' != ''" Text="DumpEnv Requested:" />
      <Exec Condition="'$(DumpEnv)' != ''" Command="set" />
     </Target>

     


    Thursday, August 18, 2005 5:37 PM
  • sorry, this doesnt work on my end.

     <PropertyGroup>
      <DevEnvDir>$(VS80COMNTOOLS)..\IDE</DevEnvDir>
     </PropertyGroup>


    How can i get the current DevEnvDir? Thanks.
    Monday, September 18, 2006 4:04 AM
  • Hmm... that should work. Here's example script -

    <Project DefaultTargets="T"
             xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

     <PropertyGroup>
      <DevEnvDir>$(VS80COMNTOOLS)..\IDE</DevEnvDir>
     </PropertyGroup>

         <Target Name="T">
              <Message Text=" $(VS80COMNTOOLS) "/>
                   <Message Text=" $(DevEnvDir) "/>
         </Target>

        
    </Project>

    Here's the output

    Target T:
         C:\Program Files\Microsoft Visual Studio 8\Common7\Tools\
         C:\Program Files\Microsoft Visual Studio 8\Common7\Tools\..\IDE

    Build succeeded.
        0 Warning(s)
        0 Error(s)

    Time Elapsed 00:00:00.04
    Monday, September 18, 2006 2:53 PM
    Moderator
  • Hi Jeffery - I know this is an Ancient Post, but you asked for a usage scenario and I can give you one.  Sandcastle (www.codeplex.com/Sandcastle) would be much easier to work with if we could set the DXROOT environment variable and the PATH before we use it to build.  Something like this would be very helpful:

    <Exec CommandLine="program.exe">
      <EnvironmentVariables>
        <DXROOT>c:\Program Files\Sandcastle</DXROOT>
        <Path>c:\Program Files\Sandcastle\bin;%path%</Path>
      </EnvironmentVariables>
    </Exec>

    Note....Nant does it like this.

    Best regards, Doug
    • Proposed as answer by scott_m Saturday, April 13, 2013 2:41 AM
    Tuesday, September 15, 2009 12:41 PM
  • I am in need of this same ability.
    Especially when it comes to porting over non .Net projects into TFS 2010.
    (you know, building java projects with Maven, etc)
    I need lots of things to be in the environment context before I start the build.
    Especially "folders" that you want to be in scope like %Path% would be.
    I don't want to have to list out a million different files from that folder as Properties.

    Possible?

    Sunday, January 31, 2010 5:22 AM
  • Just wanted to add this to this thread to save anyone else the trouble of learning this the hard way.  Apparently, when the SetEnvVar ONLY applies within a Target.  When the Target completes, the environment variables revert to their original values.

    I had a setup like this:

    <Target Name="PrepareBuildEnvironment">
    <SetEnvVar Variable="PATH" Value="$(Path)" />
    </Target>
    <Target Name="BuildStuff" DependsOnTargets="PrepareBuildEnvironment">
     <csc ...>
    </Target>

    Unfortunately, the PATH was not what I expected in BuildStuff.  It was as if the PATH had never been set.  I assume this is working a little like launching CMD.EXE multiple times: after you type EXIT, the child's environment is discarded and you are back to the parent's environment.

    So, the right way to do this is:

    <Target Name="BuildStuff" >
     <SetEnvVar Variable="PATH" Value="$(Path)" />
     <csc ...>
    </Target>
    Happy coding!

    Saturday, May 01, 2010 10:58 PM