How to put double quotes in VS2010 post build step
Asked Answered
O

7

17

I'm trying to create a post build file copy step in VS2010 which handles path macros when they have embedded spaces. I've tried surrounding the copy commands in double quotes but I get error from when copy is invoked if $(SolutionDir) contains a space. the echoed command line in the error message does not show the double quotes.

copy "$(SolutionDir)$(Configuration)\*" "$(TargetDir)"

I also tried separately \" and "" but both of these cause the 2 character escape sequence to appear in the echoed command line? How does one properly escape a double quote in a build step?

Overture answered 20/7, 2012 at 21:50 Comment(8)
Sorry, but why do you want to punish yourself in this way. Move your solution to a path without spaces.Palmation
Try escaping the speechmarks by using %22 instead of "Idiomorphic
@Palmation Mine project location doesn't have spaces but another team member unknowingly placed his workspace under "Documents/Microsoft Visual Studio\Projects". Looking for a solution to not having solution break based on its location.Overture
Could you try with a batch file? Passing the arguments inside as %1 %2 and using quotation marks if needed inside the batch?Palmation
@Idiomorphic Tried %22 and still get error. Error 1 The command "copy %22C:\NGLS\Debug*%22 %22C:\NGLS\DauServer\bin\Debug\%22" exited with code 1.Overture
@Palmation I'd have the same quoting issue passing the parameters to a batch file. The problem is I need to get VS2010 to put quotes in its command line no matter if I'm calling a batch file or a copy command.Overture
Putting quotes around macros (as you attempted to do) should work, are you sure the failure isn't due to some other problem? For example, "$(SolutionDir)$(Configuration)*" should probably have a backslash between $(Configuration) and the asterisk.Fortin
In C++ projects the default value for the output Directory (aka TargetDir) is `$(SolutionDir)$(Configuration)\` so unless your project has a different value for Output Directory your copy is going to copy a directory onto itself. Assuming of course that you're building a C++ project here.Fortin
R
12

I was having trouble using double quotes with a pre-build event command in Visual Studio. I have seen the batch file solutions to this problem, but it seems a batch file would not solve all problems and is not elegant. I found the solution was to put a space before the closing double quote. The details are as follows.

The following command worked, but would not support spaces in the path:

subwcrev $(SolutionDir) $(SolutionDir)subwcrev_template.txt $(SolutionDir)version.h

I have little control over where other developers will place the solution, so I had to support spaces in the path. Trying to use quotes around paths to support spaces, I came up with the following command. It always fails.

subwcrev "$(SolutionDir)" "$(SolutionDir)subwcrev_template.txt" "$(SolutionDir)version.h"

Almost by accident, I found the solution, put a space between the last character of the path and the double quote.

subwcrev "$(SolutionDir) " "$(SolutionDir)subwcrev_template.txt " "$(SolutionDir)version.h "

This worked. I tested this in AVR Studio 6.1, which uses a Visual Studio Shell.

Rampageous answered 23/7, 2013 at 17:46 Comment(2)
Sweet, in VS2017 this suggestion worked whereas escaping with backslash or triple quotes or using XML entities failed utterly.Someplace
It's because "$(SolutionDir)" resolves to "some folder\" thus the escaping your quote; "$(SolutionDir)\" will work though.Nadenenader
S
10

Visual Studio project files are XML files. Some special characters, such as the double quote, have to be escaped by using named entities. I think they're similar to what's used for encoding strings to html.

MSDN has a reference on How To Use Reserved XML Characters in Project Files. In your example, all you would need to do to accomplish your copy is this in the .csproj/.vbproj file:

copy "$(SolutionDir)$(Configuration)\*" "$(TargetDir)"

That will wrap both paths in double quotes. You'll get errors when referencing paths with spaces and that's why the double quotes are required.

Satirical answered 15/10, 2013 at 18:48 Comment(2)
This doesn't work in VS2017 - "'quot' is not recognized as an internal or external command"Someplace
@SørenBoisen this answer is specific to VS2010.Satirical
H
6

You need to put a double quote within two double quotes.

Example of a copy file in a post build step: copy /Y """C:\source path with spaces\somefile.txt""" """C:\destination path with spaces\"""

How answered 17/8, 2012 at 15:3 Comment(0)
S
6

I couldn't get the other answers to work.

I finally just escaped the last "\":

"$(TargetDir)\"
Sickening answered 11/2, 2015 at 12:9 Comment(4)
I could not understand the reason of escaping the double quote but it worked.Pinon
Very rarely, we software developers have to do something just because it works. It makes you feel dirty without a logical reason to do so. But in this case, it is due to a design limitation (aka a bug). Hopefully MS will fix this in the future.Sickening
@Pinon The \ isn't escaping the double quote but rather unescaping the prior trailing \ from $(TargetDir) so that it isn't interpreted as an escape character itself for the double quote and instead as a normal independent backslash.Coquelicot
Just to add to my previous comment, unfortunately using the C# verbatim syntax of @ before the string, does not make \ a literal character in this context and instead just includes the @ in the string!Coquelicot
I
5

Please, oh please don't use post build events.
Instead, use the power of MSBuild's AfterBuild target:

Right click on your project and select Edit Project File. Add an AfterBuild event:

  <Target Name="AfterBuild">
    <ItemGroup>
      <FilesToCopy Include="$(SolutionDir)$(Configuration)\*" />
    </ItemGroup>
    <Copy SourceFiles="@(FilesToCopy)"
          DestinationFolder="$(TargetDir)"
          OverwriteReadOnlyFiles="true" SkipUnchangedFiles="false" Condition="'@(FilesToCopy)' != ''" />
  </Target>

Unlike the PostBuildEvent which executes by raw cmd.exe, BeforeBuild/AfterBuild targets run by managed code, which ensures more robust execution, better maintainability and traceability.

Iodism answered 23/7, 2012 at 21:20 Comment(5)
Does this take care of spaces in path?Gratt
@Gratt Yes. Spaces can also be escaped using '%22'Iodism
Not sure how... Assume $(SolutionDir) expands to C:\Path With Spaces\src. Care to show an example?Gratt
Then %22$(SolutionDir)%22 will become "C:\Path With Spaces\src". For the example above you don't need to escape spaces as Copy task takes care of it.Iodism
you can also escape the quotes (") with &quot; in XMLMuddleheaded
C
1

It is possible to just separate the trailing \ from the " with a . like so:

"$(TargetDir)."

The . just means "the current directory" (as opposed to .. to mean "the directory one level up from the current directory"); I've never actually had a use for it until this problem hit me too!

Coquelicot answered 25/10, 2019 at 12:50 Comment(0)
D
0

I had another situation. Running a tool inside the Solution Dir with two parameters containing paths with spaces. This was my solution:

"$(SolutionDir)Tool.exe" --solution-dir "$(SolutionDir)\" --project-dir "$(ProjectDir)\"

Put double quotes on the inital command, use double quotes on all paths AND use a backslash before the last double quote of each path.

Disentangle answered 23/4, 2018 at 8:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.