定制系统环境变量Path以供MSBuild Exec任务使用

5

我正在尝试使用Exec任务调用在MSBuild过程中获得的批处理脚本。然而,脚本的位置不是系统环境变量路径的一部分。所以我想我可以在目标中更新Path属性,然后触发Exec任务:

<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" />

然而,我遇到了以下错误:

RestoreNPMPackages: 2015-07-27 06.31.24.334 进入 Build.xml 目标 RestoreNPMPackages... 属性路径在 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' 不是内部或外部命令,也不是可运行的程序或批处理文件。

从 Message 任务中可以看到,文件夹 D:\PLATFORM\Tools\Eze.Thirdparty.Node.js 已经被添加到 Path 变量中,但由于某种原因它抱怨 'npm' 不是内部或外部命令。

如果我在 Windows 中将文件夹 D:\PLATFORM\Tools\Eze.Thirdparty.Node.js 添加到 Path 变量中而不是在 MSBuild 脚本中,该命令将无错误地工作。当然,提前设置 Path 变量并不太灵活。

如何使 MSBuild Exec 任务中的实时更新 Path 变量工作?谢谢。

4个回答

8

已添加到路径变量中确实是这样,但路径变量是MsBuild进程内的一个属性,不同于Exec任务使用的环境变量。您可以验证一下:

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

将打印Exec使用的PATH,并且不会包含您的更改,因为当使用Exec时,MsBuild启动一个单独的cmd进程,并且不会将环境变量传递给它。

此外,您执行npm的命令是错误的:$(Path)\npm计算出您在问题中显示的所有内容,后跟\npm(类似于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),因此这不可能是正确的。

既然您知道npm的位置,就应该直接调用它:

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

如果因为某些原因npm需要将其所在的目录添加到PATH中,则只需像在命令行上一样执行此操作:(set PATH=...) & npm。要在exec中执行此操作,您需要使用&amp转义&
<Exec Command="(set PATH=$(Path)) &amp; npm" />

在你的问题中,Path已被修改。更多解释可以在这里找到


非常感谢!我的构建服务器上的路径有Node.js v0.12,但其他地方安装了Node.js v6.x,我使用这个方法让我的ASP.NET Core 2 webpack项目使用更新的Node.js。不过我需要做一个小改动,加上PATH=$(Path)周围的引号,因为其中一些路径中有空格。我已经在你的答案中添加了引号。 - IGx89
如果PATH包含')',会不会导致括号不平衡?(“传统”的PATH包括“Program Files(x86)”) - Shmil The Cat
@ShmilTheCat 是的,说得好。OP使用了短路径名,没有括号或空格,否则您需要引号或链接中或Ross答案下面发布的其他解决方案。 - stijn

7

设置Exec任务的环境变量的另一种方法是使用其EnvironmentVariables参数,该参数接受Variable=Value定义的列表(文档)。例如,以下代码设置了Var1Var2环境变量:

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

你可以按照相同的方式设置PATH变量。但是,在其值中必须使用百分号编码转义所有分号:
<PropertyGroup>
  <MyPath>C:\Foo;D:\Bar</MyPath>
</PropertyGroup>

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

我更喜欢这个答案,胜过我的答案 :) - stijn

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

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

1

我在Jeff Hardy的博客帖子中找到了一个实际的解决方案:

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

你可以在命令行上设置环境变量。或者你也可以运行一个多行脚本:
<PropertyGroup>
  <PythonExec><![CDATA[
set PYTHONPATH=C:\Foo
set FOO=42
python script.py
  ]]></PythonExec>
</PropertyGroup>

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

以上内容来自Jeff Hardy的博客。我测试了使用“长格式”技术使用$PATH的情况,对我很有效。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接