2009-05-15 16 views
24

Ho appena provato questo su PowerShell v1.0. L'installazione è la seguente:Come richiamare MSBuild da PowerShell usando l'operatore &?

Id CommandLine 
-- ----------- 
    1 $msbuild = "C:\Windows\Microsoft.NET\Framework\v3.5\msbuild.exe" 
    4 $a = "C:\some\project\or\other\src\Solution.sln /target:Clean /target:Build" 

.

Questa linea fallisce con un messaggio di errore poco intuitivo:

Id CommandLine 
-- ----------- 
    5 & $msbuild $a 

.

Questa riga non riesce perché & prevede che il primo argomento sia il comando stesso.

Id CommandLine 
-- ----------- 
10 & "$msbuild $a" 

.

Questa linea funziona:

Id CommandLine 
-- ----------- 
16 cmd /c "$msbuild $a" 

.

Spiegare per favore. Sono più interessato al motivo per cui la sintassi & non funziona, rispetto a una soluzione alternativa specifica di MSBuild.

+0

Suggerisco di utilizzare un cmdlet di supporto come ['Invoke-MSBuild'] (http://sedodream.com/2014/07/19/IntroducingPSBuildAnImprovedInterfaceForMsbuildexeInPowerShell.aspx) anziché chiamare direttamente MSBuild. – orad

risposta

26

I problemi che si vedono risultano dagli argomenti di analisi di PowerShell. Nel primo esempio, quando PowerShell rileva $ a, lo passa come un singolo parametro msbuild. Possiamo vederlo usando l'utility echoargs da PSCX:.

PS> $a = "C:\some\project\or\other\src\Solution.sln /target:Clean /target:Build" 
PS> & echoargs $a 
Arg 0 is <C:\some\project\or\other\src\Solution.sln /target:Clean /target:Build> 

Il secondo esempio è ancora peggio, perché si sta dicendo PowerShell per invocare "$ echoargs $ a", come il nome del comando e non è un nome di comando valido.

La terza linea funziona perché CMD.exe ottiene la forma estesa di "$ echoargs $ a" come un unico argomento che è analizza ed esegue:

Hai un paio di opzioni qui. In primo luogo lo faccio in questo modo:

PS> & $msbuild C:\some\project\or\other\src\Solution.sln ` 
    /target:Clean /target:Build 

L'altra opzione è quella di utilizzare Invoke-Expression in questo modo:

PS> Invoke-Expression "$msbuild $a" 

In generale cerco di essere molto attenti con Invoke-Expression in particolare se una qualsiasi parte del la stringa che viene invocata viene fornita dall'utente.

28

Ugh.

$collectionOfArgs = @("C:\some\project\or\other\src\Solution.sln", 
    "/target:Clean", "/target:Build") 
& $msbuild $collectionOfArgs 

Questo funziona. & accetta una raccolta di argomenti, quindi è necessario suddividere stringhe contenenti più argomenti in una raccolta di argomenti stringa.

+0

Ottimo ...Ha funzionato per me con un elenco di log di argomenti a causa della registrazione. –

+0

Ottima soluzione! Insieme alla spiegazione fornita da @ keith-hill, questo ha perfettamente senso. – simonlchilds

+0

#blessYou Questo mi stava rubando. – granadaCoder

2

Si può anche provare a utilizzare il Invoke-MsBuild powershell script/module gratuito. Questo essenzialmente ti dà un cmdlet Invoke-MsBuild PowerShell che puoi chiamare invece di provare a richiamare manualmente msbuild.exe.

Problemi correlati