如何使用&amp ;;从PowerShell调用MSBuild运营商?

时间:2009-05-15 15:15:32

标签: 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"

此行失败,并显示不正确的错误消息:

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

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

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

此行有效:

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

请解释一下。我更感兴趣的是为什么&语法不起作用,而不是MSBuild特定的解决方法。

4 个答案:

答案 0 :(得分:34)

呃。

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

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

答案 1 :(得分:30)

您看到的问题来自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>

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

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

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

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

另一种选择是像这样使用Invoke-Expression:

PS> Invoke-Expression "$msbuild $a"

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

答案 2 :(得分:3)

您也可以尝试使用免费的Invoke-MsBuild powershell script/module。这实际上为您提供了一个Invoke-MsBuild PowerShell cmdlet,您可以调用它而不是尝试自己手动调用msbuild.exe。

答案 3 :(得分:0)

对我来说很好:

PS> cmd.exe /c 'C:\Windows\Microsoft.NET\Framework\v3.5\msbuild.exe' /target:Clean /target:Build 'C:\some\project\or\other\src\Solution.sln'