user2963296
user2963296

Reputation: 81

Customize system environment variable Path for MSBuild Exec Task

I'm trying to trying to invoke a batch script that acquired during the MSBuild process using the Exec Task. However, the location of script is not part of the path system environment variable. So I figure I can update the Path property within the target and then trigger the Exec Task:

<Target Name="RestoreNPMPackages">
  <Message Text="$([System.DateTime]::Now.ToString(&quot;yyyy-MM-dd hh.mm.ss.fff&quot;)) Entering Build.xml Target RestoreNPMPackages..." Importance="high" />

  <PropertyGroup>
    <Path>$(Path);$(WorkspaceRoot)\Tools\$(Node_jsPackage)</Path>
  </PropertyGroup>

  <Message Text="Property Path in RestoreNPMPackages=$(Path)" Importance="high" />

  <Exec Command="$(Path)\npm install --no-color --no-optional" />

  <Message Text="$([System.DateTime]::Now.ToString(&quot;yyyy-MM-dd hh.mm.ss.fff&quot;)) Exiting Build.xml Target RestoreNPMPackages..." Importance="high" />

However, I am getting the following error

RestoreNPMPackages: 2015-07-27 06.31.24.334 Entering Build.xml Target RestoreNPMPackages... Property Path in RestoreNPMPackages=d:\Delphi Projects\Libraries;C:\Windows\Microsoft.NET\Framework\v4.0.30319;C:\PROGRA~1\Borland\Delphi5\Projects\Bpl;C:\PROGRA~1\Borland\vbroker\jre\Bin;C:\PROGRA~1\Borland\vbroker\Bin;C:\PROGRA~1\Borland\Delphi5\Bin;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\Microsoft SQL Server\100\Tools\Binn\;C:\Program Files\Microsoft SQL Server\100\Tools\Binn\;C:\Program Files\Microsoft SQL Server\100\DTS\Binn\;C:\Program Files (x86)\Microsoft SQL Server\100\Tools\Binn\VSShell\Common7\IDE\;C:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\IDE\PrivateAssemblies\;C:\Program Files (x86)\Microsoft SQL Server\100\DTS\Binn\;C:\Program Files (x86)\GNU\GnuPG;C:\Program Files\Microsoft\Web Platform Installer\;C:\Program Files (x86)\Microsoft ASP.NET\ASP.NET Web Pages\v1.0\;C:\Program Files\Microsoft SQL Server\110\Tools\Binn\;C:\RealTick\;C:\Program Files (x86)\Graphviz 2.28\bin;D:\PLATFORM\Tools\Eze.Thirdparty.Node.js npm install --no-color --no-optional 'npm' is not recognized as an internal or external command, operable program or batch file.

From the Message task I can see that the folder D:\PLATFORM\Tools\Eze.Thirdparty.Node.js has been added to the Path variable but for some reason it complains 'npm' is not recognized as an internal or external command

If I add the folder D:\PLATFORM\Tools\Eze.Thirdparty.Node.js to the Path variable in Windows instead of in the MSBuild script, the command will work with no error. Of course it doesn't sound very flexible to set the Path variable ahead of time.

How can I make the on the fly update of the Path variable work in MSBuild Exec task? Thanks

Upvotes: 5

Views: 8176

Answers (4)

Ross Youngblood
Ross Youngblood

Reputation: 536

I found an actual solution to this problem at Jeff Hardy's blog post:

<Exec Command="(set PYTHONPATH=C:\Foo) &amp; python script.py" />

You basically set the environment variable on the command line. Alternatively you may run a multiline script:

<PropertyGroup>
  <PythonExec><![CDATA[
set PYTHONPATH=C:\Foo
set FOO=42
python script.py
  ]]></PythonExec>
</PropertyGroup>

<Exec Command="$(PythonExec)" />

All the above was from Jeff Hardy's blog. I tested a case where I used $PATH using the "Long form" technique, and it worked well for me.

Upvotes: 1

Antosha
Antosha

Reputation: 374

Another way to set environment variables for the Exec task is its EnvironmentVariables parameter, which accepts a list of Variable=Value definitions (documentation). For instance, the following code sets the Var1 and Var2 environment variables:

<!-- Outputs [42][forty-two] -->
<Exec Command="echo [%Var1%][%Var2%]" EnvironmentVariables="Var1=42;Var2=forty-two" />

You can set the PATH variable the same way. However, you have to escape all semicolons in its value using percent-encoding:

<PropertyGroup>
  <MyPath>C:\Foo;D:\Bar</MyPath>
</PropertyGroup>

<!-- Outputs [C:\Foo;D:\Bar] -->
<Exec Command="echo [%PATH%]" EnvironmentVariables="PATH=$(MyPath.Replace(';','%3B'))" />

Upvotes: 9

Sven Bieg
Sven Bieg

Reputation: 11

<ItemGroup>
  <ExecLines Include="call C:\esp-idf\export.bat" />
  <ExecLines Include="idf.py build" />
</ItemGroup>

<Exec Command="@(ExecLines->'%(Identity)&amp;')" WorkingDirectory="$(SolutionDir)" />

Upvotes: 1

stijn
stijn

Reputation: 35901

has been added to the Path variable it sure has, but Path is a property within the MsBuild process and that is not the same as an environment variable used by the Exec task. You can verify this:

<Exec Command="echo %PATH%"/>

will print the PATH used by Exec and it will not contain your changes because MsBuild launches a seperate cmd process when using Exec and does not pass environment variables to it.

Furthermore your command for executing npm is wrong: $(Path)\npm evaluates to everything you show in your question followed by \npm (something like d:\Delphi Projects\Libraries;C:\Windows\Microsoft.NET\Framework\v4.0.30319;C:\PROGRA~1\Borland\Delphi5\Projects\Bpl;C:\PROGRA~1\Borland\vbroker\jre\Bin;C:\PROGRA~1\Borland\vbroker\Bin;C:\PROGRA....\npm) so that cannot possibly correct

Since you know where npm is you should just invoke it directly:

<Exec Command="$(WorkspaceRoot)\Tools\$(Node_jsPackage)\npm"/>

If for some reason npm requires the directory where it is located to be added to the PATH then just do that as you would on the command line: (set PATH=...) & npm. To do this for exec you need to escape the & using &amp:

<Exec Command="(set PATH=$(Path)) &amp; npm" />

Where Path is modified as in your question. More explanation here for instance.

Upvotes: 8

Related Questions