MSBuild查找刀具路径

MSBuild查找刀具路径,msbuild,Msbuild,我正在尝试设置一个MSBuild目标,以在生成过程中运行npm install <Target Name="EnsureNpmBuildImports" BeforeTargets="PrepareForBuild"> <PropertyGroup> <NpmToolExe Condition="$(NpmToolExe) == '')">npm</NpmToolExe> </PropertyGroup>

我正在尝试设置一个MSBuild目标,以在生成过程中运行
npm install

<Target Name="EnsureNpmBuildImports" BeforeTargets="PrepareForBuild">
   <PropertyGroup>
       <NpmToolExe Condition="$(NpmToolExe) == '')">npm</NpmToolExe>
   </PropertyGroup>

   <Exec Command="$(NpmToolExe) install" />
</Target>

npm
如果用户自己安装了Node.js,我希望使用该版本。假设已将其位置安装到Windows上的%PATH%环境变量中,则上述目标将正常工作

我遇到的问题是试图使用与VisualStudio捆绑在一起的npm工具(适用于我的团队中没有进行JS开发,但仍将项目作为其解决方案的一部分的人)。此版本可以在
$(VsInstallDir)Web/External下安装

虽然我可以为
npm.cmd
文件的可能位置构建一个
ItemGroup
,但我不知道如何将其作为一个有序列表,并使用现有的第一个版本


关于如何让MSBuild搜索几个位置以查找工具,有什么建议吗?

这里是我创建的一个目标,用于查找不同的可执行文件;它应该很容易适应您的要求

  <Target Name="FindBestSqlServerToolsDir">

    <!-- This target populates the property SqlServerToolsDir, which should be used when executing SQLCMD.EXE and BCP.EXE. -->

    <ItemGroup>
      <Temp_SqlServerVersions Include="130" />
      <Temp_SqlServerVersions Include="120" />
      <Temp_SqlServerVersions Include="110" />
      <Temp_SqlServerVersions Include="100" />

      <!-- Create an item for each possible path, ordered from most-preferred to least. -->
      <Temp_SqlServerToolsDirs Include="C:\Program Files\Microsoft SQL Server\%(Temp_SqlServerVersions.Identity)\Tools\Binn\" />
    </ItemGroup>

    <Message Text="About to check the following directories in the order listed for the files BCP.EXE and SQLCMD.EXE. The first one where both are found will be used as the value for $ (SqlServerToolsDir)." />
    <Message Text=" - %(Temp_SqlServerToolsDirs.Identity)" />

     <!-- Create a copy of the list with its order reversed. -->
    <ItemGroup>
      <Temp_SqlServerToolsDirs_Reversed Include="@(Temp_SqlServerToolsDirs->Reverse())" />
    </ItemGroup>

    <PropertyGroup>
      <!-- Test all paths, from the least-preferred to the most. Whenever a path passes -->
      <!-- the condition, set/overwrite the value of this property. The final value -->
      <!-- of this property will thus be the most-preferred path that passes the condition. -->
      <SqlServerToolsDir
        Condition="Exists('%(Temp_SqlServerToolsDirs_Reversed.Identity)BCP.EXE')
              And Exists('%(Temp_SqlServerToolsDirs_Reversed.Identity)SQLCMD.EXE')">%(Temp_SqlServerToolsDirs_Reversed.Identity)</SqlServerToolsDir>
    </PropertyGroup>

    <Error Condition=" '$(SqlServerToolsDir)' == '' " Text="None of the following directories contained both BCP.EXE and SQLCMD.EXE: @(Temp_SqlServerToolsDirs)" />

    <Message Text="$ (SqlServerToolsDir): $(SqlServerToolsDir)" />
  </Target>

%(临时SqlServerToolsDirs.Identity)

您能解释一下(可能添加一些注释),这段代码是如何实现您所说的内容的吗?@PaulTurner-Done.)相反顺序的评估是我遗漏的技巧;很好的东西。非常优雅的解决方案来实现这一点@埃米尔科宁-谢谢!(如果你认为它有用,你可以投票表决。)