我正在尝试设置一个 Cake 任务,该任务将使用 MsDeploy 将 powershell 脚本同步到远程服务器,然后将该脚本作为后同步命令执行。
我面临的问题是在 cake 文件中找到引号和转义符的组合,这使得命令可以通过正确引用的文件路径一直到 powershell 以允许 powershell 找到脚本;路径中有空格。
由于此命令在运行时要经过的执行链,这似乎非常困难。
首先,因为它是用 C# 编写的,字符串要么需要逐字逐句( @"command here"
),要么用 \
转义所有内部双引号。
接下来 Cake 对参数执行了几个操作,尽管在它实际执行之前似乎都不会影响引用和转义等操作,此时它使用 C# Process.Start()
静态方法来运行 MsDeploy 可执行文件。在我的阅读中,有人建议这种运行命令的方法需要正确转义三个双引号,尽管这与我尝试时所看到的不符。
然后一旦在远程机器上,MsDeploy 使用 CMD.exe
来执行命令,该命令明显不支持单引号,因此双引号需要使用 \"
或 ""
进行转义。
我得到的最接近的看起来像这样:
Task("InitializeIISApplication")
.IsDependentOn("InjectVariables")
.Does(() => {
MsDeploy(new MsDeploySettings
{
Verb = Operation.Sync,
RetryAttempts = 3,
RetryInterval = 10000,
Source = new FilePathProvider
{
Direction = Direction.source,
Path = MakeAbsolute(File(@".\MyPowershell.ps1")).ToString()
},
Destination = new FilePathProvider
{
Direction = Direction.dest,
Path = File(deployParameters.ApplicationDestinationPath + @"\MyPowershell.ps1").ToString(),
Username = deployParameters.MsDeployUserName,
Password = deployParameters.MsDeployUserPassword,
WebManagementService = deployParameters.DeploymentTargetUrl
},
AllowUntrusted = true,
EnableRules = new List<string> {
"DoNotDeleteRule"
},
PostSyncCommand = new CommandProvider {
AppendQuotesToPath = false,
Direction = Direction.dest,
Path = $"powershell -file '{deployParameters.ApplicationDestinationPath}\\MyPowershell.ps1' ",
}
});
MsDeploy(new MsDeploySettings
{
Verb = Operation.Delete,
Destination = new FilePathProvider
{
Direction = Direction.dest,
Path = File(deployParameters.ApplicationDestinationPath + "\MyPowershell.ps1").ToString(),
Username = deployParameters.MsDeployUserName,
Password = deployParameters.MsDeployUserPassword,
WebManagementService = deployParameters.DeploymentTargetUrl
},
AllowUntrusted = true
});
});
任务依赖只是设置
deployParameters
对象。启用 Cake 的诊断详细程度后,会在日志中生成以下命令(为清晰起见,添加了新行):
"C:/Program Files/IIS/Microsoft Web Deploy V3/msdeploy.exe"
-verb:sync
-source:filePath="Y:/PathToBuildArtifact/Deploy/MyPowershell.ps1"
-dest:filePath="C:/Application - With Spaces/MyPowershell.ps1",wmsvc="https://deploy-server/msdeploy.axd",userName=msdeployuser,password=********
-enableRule:DoNotDeleteRule
-retryAttempts:3
-retryInterval:10000
-allowUntrusted
-postSync:runCommand="powershell -file 'C:\Application - With Spaces\MyPowershell.ps1' "
然后以错误结束:
我在 postSync 命令中使用双引号尝试过的任何变体都会导致此错误:
如果重要的话,这是在 Bamboo CI 服务器上完成的。
最佳答案
结果证明很可能是 -file
参数导致了一些奇怪的解析行为。
在命令提示符中调用 powershell -help
会显示以下代码段:
这暗示那里有一些特殊的逻辑。
因此,我尝试使用调用运算符 ( &
) 执行文件,经过几次不同的引用尝试后,我最终得到了以下成功运行的同步后命令:
PostSyncCommand = new CommandProvider {
Direction = Direction.dest,
Path = $"powershell \"\"& \"\"\"\"{deployParameters.ApplicationDestinationPath}\\MyPowershell.ps1\"\"\"\" \"\"",
}
请注意,
powershell
之后的所有内容都包含在两个双引号内,第一个用作对 msdeploy 调用的转义,其中的字符串必须有四个引号,第一个和第三个转义第二个和第四个引号以转义对 msdeploy 的调用,第二个然后转义第四个是对 powershell 的最后一次调用。关于c# - 如何在执行 powershell 脚本的 msdeploy post sync 命令中转义引号?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/56299189/