Q:

Access denied when outputting to filename using variable

Windows 10, in my own Videos folder under UserProfile.
I'm trying to string together a couple of things to make a complete txt file containing various information, in one single command line, right.
The goal is to make a single txt with a header, some generated information and a footer. The txt will be named the same thing as the folder name with .txt at the end, for simplicity's sake.
I'm aiming to run the string of commands once per folder, and since there are quite a few calls to the folder's name that's being targeted, I figured to use a variable to shorten it.
type header.txt > VeryLongFolderNameFooBar\VeryLongFolderNameFooBar.txt & c:\mediainfo\mediainfo.exe --output=file://template.txt ./VeryLongFolderNameFooBar/*.mkv >> VeryLongFolderNameFooBar\VeryLongFolderNameFooBar.txt & type footer.txt >> VeryLongFolderNameFooBar\VeryLongFolderNameFooBar.txt
This worked absolutely perfectly, but got quite tedious to change the folder name for all occurrences, so why not use a variable right?
set a=VeryLongFolderNameFooBar && type header.txt>%a%\%a%.txt & c:\mediainfo\mediainfo.exe --output=file://template.txt ./%a%/*.mkv>>%a%\%a%.nfo & type footer.txt>>%a%\%a%.txt
This gives three access denied messages. Initially I was using spaces before and after the variable calls and removed them after reading a post that spaces can mess things up, but still no avail and I am really stuck on this. When I do echo %a% it returns the folder name with no issues at all.
What am I missing?

A:

CMD scans the entire line for variables
before it actually processes any of it. 
Therefore, it replaces %a% with null
(or whatever it was previously set to)
before it processes the set a=... command. 
You'll need to do that on a separate line:
set a=VeryLongFolderNameFooBar
type header.txt>%a%\%a%.txt & c:\mediainfo\mediainfo.exe --output=file://template.txt ./%a%/*.mkv>>%a%\%a%.nfo & type footer.txt>>%a%\%a%.txt

But, in addition (as you discovered), the set command
(stupidly, IMHO) includes everything up to a command separator. 
So
set a=SoLong & echo /%a%/

will set a to SoLong  (with a trailing space). 
One way to handle that is to leave out the space before the &:
set a=SoLong& echo ...

but that's widely considered to be less readable. 
A slightly nicer solution
is to put the set command in parentheses:
(set a=SoLong) & echo ...

so the value gets terminated by the ).

