I have a couple of apps that I use on my desktop and my Surface - and it's a pain when I change them, as I always forget to update the Surface to run the latest EXE. So I figured I'd add a post-build step to Visual Studio to automate a copy of Release (and Release only) files (the EXE and all its related / supporting DLLs) to my NAS for easy access. Turns out it's not that trivial.
Background
After much Googling, and a good deal of experimentation, I ended up with this.
Start by adding a post-build step:
Open your solution and then the Properties page for your "startup project".
Select the Build Events tab on the left and copy this string to the "post-build event command line":
if "$(ConfigurationName)" == "Release"
( xcopy "$(SolutionDir)$(TargetName)\bin\$(Configuration)" "S:\My Utils\MediaMaster\" /s /i /y )
Save the properties, and build a Release build.
What the string Does
if <condition> ( <command> )
The brackets allow for multiple commands: if you use them, put them on separate lines:
if <condition> (
command1
command2
...
commandn
)
The condition could be simplified:
"$(ConfigurationName)" == "Release"
The double quotes aren't technically needed, but ... if you don't have them and your configuration contains a space, it will all fall apart with a syntax error. Leave 'em there: you know it makes sense!
$(...)
is a Visual Studio macro : Macro names
$(ConfigurationName)
is the name of the config you have selected to build: VS automatically generates "Debug" and "Release" for you when you create a project, but you can change the names or add custom configs if you need to. In this case, I'm only interested in Release builds as I don't want Debug EXE files to mess up apps on the Surface.
The brackets '(
' and ')
' delimit a list of DOS / Shell commands you want to run: again, they aren't necessary for a single command (provided it's on the same line as the condition) but again, it costs nothing to add them and may make your life easier later.
The command itself is a PITA: I went through several iterations of Google provided "close but gives Error 4" solutions before I ended up with:
xcopy "$(SolutionDir)$(TargetName)\bin\$(Configuration)" "S:\My Utils\MediaMaster\" /s /i /y
xcopy
is a DOS / Shell file copy utility which copies files, directories, and subdirectories: XCopy (MS Docs)
Its parameters come in three parts.
The Source File(s) are First
"$(SolutionDir)$(TargetName)\bin\$(Configuration)"
$(SolutionDir) is the root folder for the project. In my case "D:\Documents\AA Backed Up\My Projects\MediaMaster".
$(TargetName) is the name of the startup project. In my case "MediaMaster
".
\bin\ is the folder VS keeps compiler outputs in.
$(Configuration) isn't listed in the MS documentation, but appears to be the same as $(ConfigurationName)
. It works. I'm not changing it to find out.
Then the Destination
"S:\My Utils\MediaMaster\"
Just the folder name I want all my release files copied to.
Finally the XCopy switches
/s /i /y
/s
specifies it should copy directories and subdirectories.
/i
creates new folders as required.
/y
overwrites existing files without prompting.
History
- 8th September, 2020: First version