如何将空格参数转义到在 VS 构建后事件中运行的 PS 脚本

pac*_*man 6 powershell parameter-passing visual-studio

更新1:

再次仔细查看输出后,我有点明白了。通过在右括号和引号之间添加尾随空格,它可以工作:

powershell -ExecutionPolicy ByPass -File "$(SolutionDir)\BuildScripts\InjectGitVersion.ps1" "$(ProjectDir) " "$(TargetDir) "
Run Code Online (Sandbox Code Playgroud)

我怀疑 PowerShell 以某种方式解释了)".

有没有更优雅的方法来解决这个问题?

更新2

这很奇怪。我有另一个脚本可以进行清理并在)和之间没有空格的情况下工作",如下所示:

powershell -ExecutionPolicy ByPass -File "$(SolutionDir)\BuildScripts\InjectGitVersionCleanup.ps1" "$(ProjectDir)"
Run Code Online (Sandbox Code Playgroud)

但是添加尾随空格将导致它失败,因为它在内部将文件名附加到路径,因此路径将不正确。

如果有人理解这一点,我很乐意接受该解释作为正确答案!


原来的:

我在 VisualStudio 中有以下预构建命令,我想用它从 Git 标签注入版本:

powershell -ExecutionPolicy ByPass -File "$(SolutionDir)\BuildScripts\InjectGitVersion.ps1" $(ProjectDir) $(TargetDir)
Run Code Online (Sandbox Code Playgroud)

如果路径 $(SolutionDir) 不包含空格(该路径也将出现在 $(ProjectDir) 或 $(TargetDir) 中),则此方法可以正常工作。

当路径 $(SolutionDir) 确实包含空格时,脚本似乎按预期启动,但参数未正确传递,我无法弄清楚如何在 PS 脚本的参数中转义它们。

我尝试添加 sing "、三重 """ 以及 ',这给出了以下内容(每个 PS 命令尝试不同的方法来转义空格):

powershell -ExecutionPolicy ByPass -File "$(SolutionDir)\BuildScripts\InjectGitVersion.ps1" $(ProjectDir) $(TargetDir)
Run Code Online (Sandbox Code Playgroud)

参数[0]:

D:\VisualStudio

参数[1]:

项目\software_git_repo\ProgramEditor\

powershell -ExecutionPolicy ByPass -File "$(SolutionDir)\BuildScripts\InjectGitVersion.ps1" "$(ProjectDir)" "$(TargetDir)"
Run Code Online (Sandbox Code Playgroud)

BS:参数[0]:

D:\VisualStudio 项目\software_git_repo\ProgramEditor" D:\VisualStudio

BS:参数[1]:

项目\software_git_repo\ProgramEditor\bin\Debug”

powershell -ExecutionPolicy ByPass -File "$(SolutionDir)\BuildScripts\InjectGitVersion.ps1" """$(ProjectDir)""" """$(TargetDir)"""
Run Code Online (Sandbox Code Playgroud)

BS:参数[0]:

“D:\VisualStudio

BS:参数[1]:

项目\software_git_repo\ProgramEditor”

powershell -ExecutionPolicy ByPass -File "$(SolutionDir)\BuildScripts\InjectGitVersion.ps1" '$(ProjectDir)' '$(TargetDir)'  
Run Code Online (Sandbox Code Playgroud)

BS:参数[0]:

'D:\VisualStudio

BS:参数[1]:

项目\software_git_repo\ProgramEditor\'

正在做:

echo ProjectDir:
echo $(ProjectDir)
echo TargetDir:
echo $(TargetDir)
Run Code Online (Sandbox Code Playgroud)

我得到:

项目目录:

D:\VisualStudio 项目\software_git_repo\ProgramEditor\

目标目录:

D:\VisualStudio Projects\software_git_repo\ProgramEditor\bin\Debug\

tra*_*arn 5

当 VS 目录宏在带引号的参数中展开时,请注意意外的转义引号。


包含路径的脚本参数应该用引号引起来,以避免在路径包含空格时被解释为多个参数。因此,在 Visual Studio 的预/后构建事件命令行中,以下内容似乎是合理的:-

powershell.exe -file "$(SolutionDir)script.ps1" -projectDirectory "$(ProjectDir)"
Run Code Online (Sandbox Code Playgroud)

但指定目录的宏值始终包含尾部反斜杠;因此,当它们扩展时,该行将变为,例如:-

powershell.exe -file "C:\sln path\script.ps1" -projectDirectory "C:\sln path\project\"
Run Code Online (Sandbox Code Playgroud)

...其中尾随 \" 是转义字符,被解释为参数值的一部分,参数值传递给脚本如下:-

C:\sln 路径\项目"

解决方案

在我的例子中,修复方法是在要转义的目录宏后面插入一个额外的反斜杠而不是引号,这会恢复预期的参数值并防止损坏任何后续参数:-

powershell.exe -file "$(SolutionDir)script.ps1" -projectDirectory "$(ProjectDir)\"
Run Code Online (Sandbox Code Playgroud)

虽然不是很直观。如果我遗漏了一些更明显的东西,请告诉我......


Jas*_*ick 0

我注意到的一件事是 $(SolutionDir) 之后有一个额外的反斜杠。我正在使用 VS2017,并且我认为 $(SolutionDir) 始终有一个反斜杠。但不确定。

我的解决方案文件夹中有一个 .bat,它创建一个 json 配置文件。我的构建后事件如下所示。

call "$(SolutionDir)CreateConfigurationJson.bat" "$(TargetDir)mySettings.json"
{"ProjectName":"$(ProjectName)"}
Run Code Online (Sandbox Code Playgroud)

"$(TargetDir)mySettings.json"是.bat文件的第一个参数

{"ProjectName":"$(ProjectName)"}是第二个参数。

不需要转义字符。希望这可以帮助。

bat文件的代码是:

echo off
set filePath=%1
break>%filePath%
set json=%2
echo %json% >>%filePath%
Run Code Online (Sandbox Code Playgroud)