我刚刚在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特定的解决方法。
答案 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'