I just need to ask if this is expected behaviour, it sure surprised me.

We have a batch file that copies some files from a sub-directory of where it is located, to another location on every developers machine. Since for some developers, this target directory differs from the rest, we've set a user environment variable, and used that in the batch file.

This is a sample line from the batch file:

ROBOCOPY Staging\*.* "%DISTRIBUTE_TARGET%" *.* /IS

This failed on one machine, and after some experimentation, it dawned on me that on this machine, the variable had a trailing backslash as part of the variable content.

On most machines (in fact, all the other machines, where it worked), the variable looked like this:

DISTRIBUTE_TARGET=C:\Some\Directory

but on this machine, it was:

DISTRIBUTE_TARGET=C:\Some\Directory\

notice the added backslash there.

The error message given by ROBOCOPY was that there was something wrong with the second parameter, but it seemed to think that everything from the start of that variable, and to the end of the line, was all in the 2nd parameter.

Ie. the error message looked like this:

Error in second parameter: "C:\Some\Directory\" *.* /IS"

What I assume happened is that the backslash "escaped" the quote character, which removed its meaning as "end of quoted parameter", and thus the rest of the line was just grabbed as part of the argument.

Is this expected behavior? Does this mean that variables with a trailing backslash, for whatever reason or purpose, just cannot be safely used?

link|improve this question

feedback

2 Answers

up vote 2 down vote accepted

From this article:

If either the source or destination are a "quoted long foldername" do not include a trailing backslash as this will be treated as an escape character, i.e. "C:\some path\" will fail but "C:\some path\\" or "C:\some path" will work.

This is a problem specific to robocopy. I would even go as far as to call it a bug.

You have no other solution but to add code to your batch file that will check and delete a backslash from the end of the source and destination.

link|improve this answer
feedback

Indeed this is not specific to robocopy, but rather the CommandLineToArgvW Windows API function.

CommandLineToArgvW has a special interpretation of backslash characters when they are followed by a quotation mark character ("), as follows:

2n backslashes followed by a quotation mark produce n backslashes followed by a quotation mark.

(2n) + 1 backslashes followed by a quotation mark again produce n backslashes followed by a quotation mark.

n backslashes not followed by a quotation mark simply produce n backslashes.

The same rules are described in Parsing C++ Command-Line Arguments

A workaround is to append . to everything you know is a directory (e.g. "C:\Program Files\.")

link|improve this answer
feedback

Your Answer

 
or
required, but never shown

Not the answer you're looking for? Browse other questions tagged or ask your own question.