views:

772

answers:

2

I don't know how to describe exactly what I'm trying to do but here's an example batch file that demonstrates what I can't figure out.:

I've got a batch file. Inside that batch file I'm trying to create a directory:

Set CopyFrom = %~dp0

if Exist "%ProgramFiles(x86)" (
  Set TargetDir = %ProgramFiles(x86)%\My Directory Name has spaces
)

md %TargetDir%\NewSubFolder
copy %CopyFrom%\SourceFile.zip %TargetDir%\NewSubFolder

My batch file is failing on line 4 Set TargetDir =... with:

\My was unexpected at this time

I'm assuming this is because I have spaces in my path name. I thought I could just wrap my variable with quotes:

Set TargetDir = "%ProgramFiles(x86)%\My Directory Name has spaces"

But then when I get to the line that creates the directory it fails because %TargetDir% is now wrapped in quotes. md "%TargetDir%"\NewSubFolder

Can this be fixed or should I just write a VBScript to sort things out?

+1  A: 

Just put your expression in quotes like this:

C:\>Set "TargetDir=%ProgramFiles%\My Directory Name has spaces"
C:\>echo %TargetDir%
C:\Program Files\My Directory Name has spaces

Note: It will expand the variable within the quotes, and if it too has spaces, it will need to be quoted.

Now you can quote it to perform your operation:

md "%TargetDir%\NewSubFolder"
zdan
Thanks, that was just the ticket, much appreciated.
BobTheBuilder
It never occurred to me that I could wrap the whole item after Set in quotes... of course, it's not exactly intuitive?
BobTheBuilder
No, not intuitive. (Not much about the windows command line is - that's why I switched to powershell). I think of it like this: both sides of the "=" are a single argument to the set command.
zdan
A: 

The problem in question here are not the spaces as others suggested, but rather the closing parenthesis in the environment variable ProgramFiles(x86) This causes the parser to think that the block ends prematurely (shameless self-promotion).

Quotes do help in this case because they make the parser jump over the whole quoted part and rightly assume the following parenthesis to be the actual closing one. but the fix might be much easier than that:

if Exist "%ProgramFiles(x86)%" Set TargetDir=%ProgramFiles(x86)%\My Directory Name has spaces

Why use a parenthesized block at all if all you do it put exactly one command into it?

set itself doesn't need any quotes, except when its arguments contain special characters like <, >, |, & which the shell itself aready handles. It isn't a panacea, though which makes handling user input or file contents correctly a pain at times.

Also, please never ever put spaces around the = in a set command. This will cause an environment variable to be created with its name ending in a space and its contents starting with a space. This was partially corrected in Windows 7 by silently creating both the variable with the space at the end and one without:

> set foo = bar
> set foo
foo=bar
foo = bar

But in previous versions of Windows this didn't happen so just never use spaces around the = unless you know this is what you want :-)

Joey