2

I have 2 projects for which I am trying to create a generic Post-Build event batch file.

Here is the command in Visual Studio:

Post-Build event

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

So I am calling the file PostBuildRelease.bat with 4 parameters:

  • Bin\Release Directory
  • Project Version
  • File Name With Extension
  • File Name Without Extension

Project 1

This works perfectly with this batch script:

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%

Where the assembly is copied to Z:\Unused\Apps\LyncVdiChecker\ and the existing version copied to _archive in the same folder. The archived version also has the date and version number replace the file extension.

Project 2

This batch script also works perfectly (it does the same thing but in a different folder and for a different project):

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"

However, if I try using the same script from Project1 (the more generic version) in Project2, I get errors, even though the 2 scripts are equivalent:

Errors

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.

Output Window:

The syntax of the command is incorrect.

Invalid number of parameters

This error is rather unhelpful, so I tried commenting out the 2 lines MOVE and XCOPY and build again:

Removed MOVE

Same error as above.

Output window:

Invalid number of parameters

Remove XCOPY

No Visual Studio Error, but this appears in the output window:

The syntax of the command is incorrect.


Parameter Output

When I echo out the parameters being used in Project2, everything seems to be in order:

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

How can I debug this issue? How is it possible that my script runs fine without any issues, but when run against a different project none of the commands are recognised? Any help with this is much appreciated!

Bassie
  • 9,529
  • 8
  • 68
  • 159
  • 1
    You are aware of the wrong syntax in `SET parameter=%2 REM Full Version Number`? The REM... will be part of your variable – jeb Sep 13 '16 at 11:35
  • @jeb When I echo out the parameters, `rem` is not present – Bassie Sep 13 '16 at 11:37
  • That last "parameter" you list doesn't have double-quotes around the path name, even though the path contains a space. Not healthy and very likely to cause these error messages. You would need something like XCOPY %3 "%productionpath%" to get it quoted again. Same issue with the MOVE command. – Hans Passant Sep 13 '16 at 12:04
  • @Bassie As you used always the same variable name, I suppose you echo the parameter with `echo %1` instead of `echo %parameter%` – jeb Sep 13 '16 at 12:15

3 Answers3

1

The problem is that the script is messing with the double quotes resulting in invalid paths and invalid number of arguments passed. When dealing with paths built dynamically, it's best to strip any existing " from the parts, and after the path is complete, surround it in ".

Dealing with batch arguments is explained on MSDN. Same thing for variables can be found on SS64.

I've played a bit with the file, and I was able to run it (from command line). The changes you should make in your (Project1) file:

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:"=%"

I moved the " from the productionpath line to the beginning of its contents. That way will work with paths that contain SPACE s.

In the MOVE and XCOPY lines, I did what I explained above: even if the syntax is not that clear, it's more robust (the last "%productionpath:"=%" could be simple written as %productionpath%, but I left it in the the 1st form for consistency).

Note: You could remove the CMD command at the beginning of your batch, since it starts a new cmd instance(process) that doesn't end.

CristiFati
  • 38,250
  • 9
  • 50
  • 87
1

You should normalize all your arguments, so they don't contain outer quotes.
Then you can use them in a reliable way.
The syntax set "variable=%~1" avoids outer quotes in the variable itself.

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"
jeb
  • 78,592
  • 17
  • 171
  • 225
  • Thanks for the tips Jeb - I added a secondary solution in my own answer which is similar to yours but more generic (no need to specify `Z:\...\..` each time it is called). Interested to know your thoughts on that if you have any! – Bassie Sep 13 '16 at 11:54
  • It's always better to avoid hardcoded paths, at least it's better to define them only once, like in your solution. – jeb Sep 13 '16 at 12:13
0

I found a solution to this, but I am still not sure what the cause was.

I suspect it has something to do with either one of:

  • Spaces in productionpath causing the command parameter declaration to escape

  • Quotes around one or more of the parameters creating a non-existent file path

After trying out a few changes to the script, I found that changing the productionpath declaration to SET productionpath="Z:\Unused\Apps\IT Support App\" solved the issue:

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"

Making the same change to the Project1 script did not cause that to break either, so this seems safe.


Update

After reading some of the other answers, I amended the script once again to the following:

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%"

Notice the "normalisation" of the paramaters - this removes all quotation marks from their values.

Also now using named parameters.

Bassie
  • 9,529
  • 8
  • 68
  • 159
  • 2
    The escaping of the quotes is nonsense, it enables only more possible problems, think of a path containing `&` like in `Sources&Docs` – jeb Sep 13 '16 at 12:11