Post-构建事件适用于一个项目,但不适用于另一个项目

Post-Build Event Works With one Project But Not the Other

我有 2 个项目正在尝试为其创建通用 Post-Build 事件批处理文件。

这是 Visual Studio 中的命令:

Post-构建事件

if $(ConfigurationName) == Release ("$(ProjectDir)PostBuildRelease.bat" "$(TargetDir)" @(VersionNumber) "$(TargetFileName)" "$(TargetName)")

所以我用 4 个参数调用文件 PostBuildRelease.bat

项目 1

这与这个批处理脚本完美配合:

CMD

SET parameter=%1 REM Full path to new bin\release\
SET parameter=%2 REM Full Version Number
SET parameter=%3 REM File name + extension
SET parameter=%4 REM File name - extension
SET "productionpath=Z:\Unused\Apps\LyncVdiChecker\"

MOVE %productionpath%%3 %productionpath%"_archive\"%4"."%DATE:~0,2%%DATE:~3,2%%DATE:~6,4%"-"%2
XCOPY %3 %productionpath%

程序集复制到 Z:\Unused\Apps\LyncVdiChecker\,现有版本复制到同一文件夹中的 _archive。存档版本也有日期和版本号替换文件扩展名。

项目 2

这个批处理脚本也能完美运行(它做同样的事情,但在不同的文件夹和不同的项目中):

CMD

SET parameter=%1 REM Full path to new bin\release\
SET parameter=%2 REM Full Version Number
SET parameter=%3 REM File name + extension
SET parameter=%4 REM File name - extension
SET "productionpath=Z:\Unused\Apps\IT Support App\"

MOVE "Z:\Unused\Apps\IT Support App\"%3 "Z:\Unused\Apps\IT Support App\_archive\"%4"."%DATE:~0,2%%DATE:~3,2%%DATE:~6,4%"-"%2
XCOPY %3 "Z:\Unused\Apps\IT Support App"

但是,如果我尝试在 Project2 中使用来自 Project1(更通用的版本)的相同脚本,即使这 2 个脚本是等效的,我也会出错:

错误

The command "if Release == Release ("C:\Users\Seb.Kotze\Source\Repos\Applications\ITSelfHelp\ITHelp\PostBuildRelease.bat" "C:\Users\Seb.Kotze\Source\Repos\Applications\ITSelfHelp\ITHelp\bin\Release\" 2.0.6100.20905 "IT Self Help.exe" "IT Self Help")" exited with code 4.

输出Window:

The syntax of the command is incorrect.

Invalid number of parameters

这个错误是相当无用的,所以我尝试注释掉 MOVEXCOPY 两行并重新构建:

删除了 MOVE

同上错误。

输出window:

Invalid number of parameters

删除 XCOPY

没有 Visual Studio 错误,但这出现在输出中 window:

The syntax of the command is incorrect.


参数输出

当我回显 Project2 中使用的参数时,一切似乎都井井有条:

"Path\to\Bin\Release"
2.0.6100.21082
"IT Self Help.exe"
"IT Self Help"
Z:\Unused\Apps\IT Support App\

如何调试这个问题?我的脚本 运行 怎么可能没有任何问题,但是当 运行 针对不同项目 none 的命令被识别时?非常感谢任何帮助!

我找到了解决方法,但我仍然不确定是什么原因。

我怀疑它与以下任何一个有关:

  • productionpath中的空格导致命令参数声明转义

  • 引用一个或多个参数创建不存在的文件路径

尝试对脚本进行一些更改后,我发现将 productionpath 声明更改为 SET productionpath="Z:\Unused\Apps\IT Support App\" 解决了问题:

CMD

SET parameter=%1 REM Full path to new bin\release\
SET parameter=%2 REM Full Version Number
SET parameter=%3 REM File name + extension
SET parameter=%4 REM File name - extension
SET productionpath="Z:\Unused\Apps\IT Support App\"

MOVE "Z:\Unused\Apps\IT Support App\"%3 "Z:\Unused\Apps\IT Support App\_archive\"%4"."%DATE:~0,2%%DATE:~3,2%%DATE:~6,4%"-"%2
XCOPY %3 "Z:\Unused\Apps\IT Support App"

Project1 脚本进行相同的更改也没有导致脚本中断,因此这似乎是安全的。


更新

在阅读了一些其他答案后,我再次将脚本修改为以下内容:

CMD

SET "TargetDir=%~1"
SET "VersionNumber=%~2"
SET "TargetFileName=%~3"
SET "TargetName=%~4"

SET "ProductionPath=Z:\Unused\Apps\IT Support App\"
SET "ArchivePath=%ProductionPath%_archive\"
SET "DateStamp=%DATE:~0,2%%DATE:~3,2%%DATE:~6,4%"

MOVE "%ProductionPath%%TargetFileName%" "%ArchivePath%%TargetName%.%DateStamp%-%VersionNumber%"
XCOPY "%TargetFileName%" "%ProductionPath%"

注意参数的 "normalisation" - 这会从它们的值中删除所有引号。

现在也使用命名参数。

问题是脚本混淆了双引号,导致路径无效和传递的参数数量无效。在处理动态构建的路径时,最好将已经存在的"从部分中去掉,路径完成后,用"包围起来。

MSDN. Same thing for variables can be found on SS64 上解释了批处理参数的处理。

我已经对文件进行了一些操作,并且能够 运行 它(从命令行)。您应该在 (Project1) 文件中进行的更改:

SET productionpath="Z:\Unused\Apps\LyncVdiChecker\"
MOVE "%productionpath:"=%%~3" "%productionpath:"=%_archive\%~4.%DATE:~0,2%%DATE:~3,2%%DATE:~6,4%-%~2"
XCOPY "%~3" "%productionpath:"=%"

我将 "productionpath 行移动到其内容的开头。这种方式将适用于包含 [=44 的路径=] s.

MOVEXCOPY行,我做了我上面解释的:即使语法不是那么清楚,它更健壮(最后的"%productionpath:"=%"可能很简单写成 %productionpath%,但为了保持一致性,我将其保留在第一种形式。

注意:您可以删除批处理开头的 CMD 命令,因为它会启动一个新的 cmd没有结束的实例(进程)。

你应该规范化你所有的参数,这样它们就不会包含外引号。
然后你就可以以可靠的方式使用它们了。
语法 set "variable=%~1" 避免在变量本身中使用外引号。

set "TargetDir=%~1"
set "VersionNumber=%~2"
set "TargetFileName=%~3"
set "TargetName=%~4"
SET "productionpath=Z:\IT Support App\"
set "dateStamp=%DATE:~0,2%%DATE:~3,2%%DATE:~6,4%"

MOVE "Z:\IT App\%TargetFileName%" "Z:\IT App\_archive\%TargetName%.%dateStamp%-%VersionNumber%"
XCOPY "%TargetFileName%" "Z:\IT App"