【问题标题】:How do I escape a directory correctly when using psake, exec, and msbuild?使用 psake、exec 和 msbuild 时如何正确转义目录?
【发布时间】:2011-10-13 18:52:50
【问题描述】:

我可以在 PowerShell 中执行以下命令:

msbuild "c:\some\spaced path\project.sln" /p:MvcBuildViews=False /p:OutDir="c:\\some\\spaced path\\deploy\\Package\\"

路径已更改,但真实路径也包含间隔组件。双斜线是一个技巧,例如this answer.

如果我直接运行它,msbuild 会理解路径。但是,它需要像这样在psake中运行:

exec { msbuild $SolutionFile "/p:MvcBuildViews=False;OutDir=$OutputDir" }

如果路径没有空格,这可以工作,但我想调整它以使用空格(对于 sln 路径和 OutDir)。我试过了,但我无法弄清楚转义。

编辑:

为了澄清,如果我在 psake 中硬编码完整路径,它也可以工作:

exec { msbuild "c:\some\spaced path\project.sln" /p:MvcBuildViews=False /p:OutDir="c:\\some\\spaced path\\deploy\\Package\\" }

但是,它需要使用 OutputDir 变量(不是双斜杠转义的)。所以,我为此添加了一个临时变量,然后尝试构造命令行。:

$double_slashed_dir = $OutputDir.Replace('\', '\\');
write $double_slashed_dir;
exec { msbuild $SolutionFile /p:MvcBuildViews=False "/p:OutDir=`"$double_slashed_dir`"" }

这不起作用(我尝试了几种变体)。有了上面我得到“MSB1008:只能指定一个项目。”

【问题讨论】:

  • 以防万一,命令不一样(工作的有两个/p:...),你用psake试试同样的命令吗?
  • 另外,我创建了一个测试灵魂,使用了所有带空格的路径,并在 psake 中使用了您的命令。它奏效了。
  • @Roman,我相信我尝试了两者的变体(并且原版将它们放在一起),但你说得对,我应该保持一致。我会坚持单独的版本。您实际在 psake 中工作的代码是否有变量?我可以通过硬编码的 exec 让它工作,但不能用替换。
  • 是的,它适用于变量。任务主体是` $SolutionFile = "C:\TEMP\spaced path\ConsoleApplication1.sln" $OutputDir = "C:\\TEMP\\spaced path2\\" exec { msbuild $SolutionFile "/p:MvcBuildViews=False;OutDir =$OutputDir" }`
  • @Roman,哇,谢谢。这样可行。我以为我试过了。我尝试了其他语法变体,包括原始路径(不是双斜杠)。但我想我从未尝试过使用double_slashed_dir。将其发布为答案,我会接受。

标签: powershell msbuild escaping psake


【解决方案1】:

这种变化对我有用($OutputDir 中的双斜杠和尾部斜杠似乎很重要):

task build {
    $SolutionFile = "C:\TEMP\spaced path\ConsoleApplication1.sln"
    $OutputDir = "C:\\TEMP\\spaced path2\\"
    exec { msbuild $SolutionFile "/p:MvcBuildViews=False;OutDir=$OutputDir" }
}

【讨论】:

  • @Matthew:这不是你一开始的时候吗?什么改变使它起作用?
  • @gprasant,正如我在评论中提到的,我想我试过了,但没有加倍斜线 (.Replace('\', '\\'))。
【解决方案2】:

您想在 OutDir 周围加上引号,但由于参数中的其他引号,加上单引号会混淆命令 shell 解析器,因此您需要通过双引号来转义这些引号:

exec { msbuild $SolutionFile "/p:MvcBuildViews=False;OutDir=`"`"$OutputDir`"`"" }

【讨论】:

  • 不幸的是,MSBuild 仍然在空间上分裂,给出错误“只能指定一个项目”。我确保变量(您的答案中的$OutputDir)包含双斜线路径。但是,它也不适用于单斜杠。
【解决方案3】:

我用以下方法进行了尝试,它奏效了。我唯一添加的是 msbuild 命令后的双引号(“)。这是我尝试过的:

properties{
    $build_Dir="F:\projects\tweet sharp\src";
}

Task Default -depends Build


Task Build {
        Exec { msbuild "$build_Dir\TweetSharp.sln" }
}

如您所见,构建目录包含一个空格('tweet sharp')。只需尝试将 msbuild 任务的所有参数括在双引号中并检查它是否有效。

【讨论】:

  • 对不起,如果我不清楚。问题不是 sln 路径,而是OutDir。两者都需要为间隔路径工作。
【解决方案4】:

我得到了它与Invoke-Expression

$double_slashed_dir = $OutputDir.Replace('\', '\\');
$msbuild_command = 'msbuild "' + $SolutionFile + '" /p:MvcBuildViews=False /p:OutDir="' + $double_slashed_dir + '"';
exec { Invoke-Expression $msbuild_command }

我认为这有点骇人听闻。它需要字符串连接,据我所知,Invoke-Expression 基本上是 eval(尽管它应该是安全的,因为这里没有涉及用户输入)。

所以我暂时保留这个问题,希望得到更好的答案。它应该清楚地显示变量。

【讨论】:

  • 我同意;虽然这解决了问题,但应该有更优雅的方法来解决这个问题,而无需实际形成整个命令文本。 @马特
  • 是的。我想到了一种类似的方法来做到这一点。在实际运行任务之前,重命名适当的目录以中和空格(用 _ 或其他内容替换空格),然后在运行任务后,将目录转换回其原始形式。又一个 hack - 但远不及一个优雅的解决方案。
【解决方案5】:

我也一直在为此苦苦挣扎,最终得出的答案是:引用整个开关,而不仅仅是路径。

所以,例如:

$buildBranch = "a path/with multiple/spaces in/"

# Use an array of arguments for common build settings, note: no trailing slash after Apps
$buildSettings = (
    ('"/Property:SolutionDir=' + $buildBranch + '\My Apps"'),
    '/t:Build', 
    '/p:PlatformTarget=x86', 
    '/p:Configuration=Release')

# Combine the common build settings with the specific project
$arg = $buildSettings + @('"' + $buildBranch + '\My Apps\MyProjectPath\MyProject.vcxproj"')

exec {
    &$msbuild $arg
}

这与我所有其他尝试的主要区别在于 /Property 开关的引用。

我最初是这样做的:

'/Property:SolutionDir="' + $buildBranch + '\My Apps"'

请注意,我要传递给 msbuild 的双引号位于开关名称之后和值之前。

MsBuild 会看到:

/Property:SolutionDir="some path\with spaces\My Apps"

这不起作用。

我改成:

'"/Property:SolutionDir=' + $buildBranch + '\My Apps"'

MsBuild 会看到:

"/Property:SolutionDir=some path\with spaces\My Apps"

这确实有效!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-12
    • 2011-01-25
    • 2014-01-26
    • 2011-03-18
    • 1970-01-01
    相关资源
    最近更新 更多