如何使用&运算符从PowerShell调用MSBuild?

Pet*_*ale 31 powershell

我刚刚在PowerShell v1.0上测试了这个.设置如下:

 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"
Run Code Online (Sandbox Code Playgroud)

.

此行失败,并显示不直观的错误消息:

 Id CommandLine
 -- -----------
  5 & $msbuild $a
Run Code Online (Sandbox Code Playgroud)

.

此行失败,因为&期望第一个参数是命令本身.

 Id CommandLine
 -- -----------
 10 & "$msbuild $a"
Run Code Online (Sandbox Code Playgroud)

.

这条线有效:

 Id CommandLine
 -- -----------
 16 cmd /c "$msbuild $a"
Run Code Online (Sandbox Code Playgroud)

.

请解释.我更感兴趣的是&语法不起作用,而不是MSBuild特定的解决方法.

Pet*_*ale 37

啊.

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

这有效.&获取参数集合,因此必须将包含多个参数的字符串拆分为字符串参数的集合.


Kei*_*ill 32

您看到的问题来自PowerShell解析参数.在第一个示例中,当PowerShell看到$ a时,它将其作为单个参数msbuild传递.我们可以使用PSCX的echoargs实用程序看到这个:.

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>
Run Code Online (Sandbox Code Playgroud)

第二个例子甚至更糟,因为你告诉powershell调用"$ echoargs $ a"作为命令名,它不是一个有效的命令名.

第三行有效,因为CMD.exe将扩展形式的"$ echoargs $ a"作为单个参数进行解析并执行:

你有几个选择.首先我这样做:

PS> & $msbuild C:\some\project\or\other\src\Solution.sln `
    /target:Clean /target:Build
Run Code Online (Sandbox Code Playgroud)

另一种选择是使用Invoke-Expression,如下所示:

PS> Invoke-Expression "$msbuild $a"
Run Code Online (Sandbox Code Playgroud)

一般来说,我会特别小心使用Invoke-Expression,特别是如果用户提供了被调用的字符串的任何部分.