2017-06-16 2 views
1

Ich versuche, ein MSBuild-Ziel einzurichten, npm install als Teil des Build-Prozesses auszuführen.MSBuild einen Werkzeugpfad finden

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

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

Wenn der Benutzer Node.js selbst installiert hat, möchte ich diese Version verwenden. Unter der Annahme, dass der Speicherort in der Umgebungsvariablen% PATH% unter Windows installiert ist, funktioniert das obige Ziel.

Der Teil, mit dem ich Probleme habe, versucht, ein Fallback zu dem npm-Tool zu verwenden, das mit Visual Studio gebündelt ist (für diejenigen in meinem Team, die keine JS-Entwicklung machen, aber das Projekt als Teil von ihre Lösung). Diese Version kann unter $(VsInstallDir)Web/External Gründer sein.

Obwohl ich eine ItemGroup der möglichen Standorte der npm.cmd Datei erstellen kann, weiß ich nicht, wie man das als eine geordnete Liste nimmt und die erste Version verwendet, die existiert.

Irgendwelche Vorschläge, wie ich MSBuild ein paar Standorte suchen kann, um das Werkzeug zu finden?

Antwort

2

Hier ist ein Ziel, das ich erstellt habe, um verschiedene ausführbare Dateien zu finden; Es sollte leicht für Ihre Anforderung angepasst werden können.

<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> 
+0

Können Sie erklären (vielleicht einige Kommentare hinzufügen), wie dieser Code das erreicht, was Sie sagen? –

+0

@PaulTurner - Fertig. :) – weir

+0

Die umgekehrte geordnete Auswertung ist der Trick, den ich vermisste; tolles Zeug. –