Odd issue when feeding icacls an external variable - batch-file

Good morning.
I am having an issue with a batch script I have. I have a program that feeds it a variable and I use that variable to create a folder and then apply Icalcs permissions on it. For some reason it will create the folder with the variable name but Icalcs will be blank where the variable should be. Here is the code -
set whodo=%2
set username=%whodo%
set path="\\example\shares\Student\%username%"
md %path%
md %path%\Desktop
md %path%\Contacts
md %path%\Favorites
md %path%\Links
md %path%\Music
md %path%\Pictures
md %path%\Saved Games
md %path%\Searches
md %path%\Video
md %path%\Documents
c:\windows\system32\icacls.exe %path% /T /C /inheritance:e /grant:r %username%:(OI)(CI)M
The %2 is pulling the variable from the program that runs this script, I was then putting the variable into another variable to see if that would make Icacls happy, but it doesn't. Without the variable pulled from the program this script works fine. I cannot figure out why the Path and Username variables work everywhere but Icacls. Is this some flaw icacls has?
Thanks

Open a command prompt window and run set to get output the list of predefined environment variables. For a description of each predefined environment variable see for example Wikipedia article about Windows Environment Variables.
The predefined environment variables USERNAME and PATH should not be modified in a batch file except there is a really good reason to do that.
Also be careful on using set variable="value" instead of set "variable=value" because in first case the double quotes are also assigned as part of the string value to the environment variable and perhaps existing trailing spaces/tabs, too. For a detailed description read the answers on
How to set environment variables with spaces?
Why is no string output with 'echo %var%' after using 'set var = text' on command line?
And strings containing 1 or more spaces must be enclosed in double quotes as the space character is used as string separator if not found within a double quoted string. The name of the user could contain a space. The directory name Saved Games contains definitely a space.
I suggest to use this batch code:
rem Get name of user with surrounding double quotes removed.
set "whodo=%~2"
set "NameUser=%whodo%"
set "PathUser=\\example\shares\Student\%NameUser%"
rem Create directories for this user on server. With command extensions
rem enabled as by default the command MD creates the entire directory
rem tree if that is necessary. Therefore it is not necessary to create
rem separately the profile directory of the user first.
md "%PathUser%\Desktop"
md "%PathUser%\Contacts"
md "%PathUser%\Favorites"
md "%PathUser%\Links"
md "%PathUser%\Music
md "%PathUser%\Pictures"
md "%PathUser%\Saved Games"
md "%PathUser%\Searches"
md "%PathUser%\Video"
md "%PathUser%\Documents"
%SystemRoot%\System32\icacls.exe "%PathUser%" /T /C /inheritance:e /grant:r "%NameUser%:(OI)(CI)M"
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
call /? ... explains %~2 (second argument without surrounding quotes).
cmd /? ... explains on last help page when double quotes are needed.
icacls /?
md /?
rem /?
set /?

Related

How can I copy and rename a file using an environment variable?

I'm working with the command prompt for nearly the first time and am required to create a batch file that prompts the user for a filename with an extension. The bat is supposed to be able to copy and rename said file. The instructor has directed us to use environmental variables to accomplish this task, but I keep getting directory or syntax errors.
I've tried using the variable that the user sets with a previous prompt, but unfortunately this particular instructor hasn't given us practical examples about how to accomplish this particular goal, so I'm flailing. I've tried attaching the variable to the target directory with a generic name for the file. The file and the copy should be in the dame directory.
set /P file_var=Please enter a file name and extension:
copy %file_var% Templatecopy.doc
The file should be copied with the new default name of "Templatecopy.doc" in the target directory.
Churns out syntax and directory errors.
I suggest the following commented code to make this batch file fail-safe as described in answer on How to stop Windows command interpreter from quitting batch file execution on an incorrect user input?
#echo off
:FileNamePrompt
rem Undefine environment variable FileToCopy.
set "FileToCopy="
rem Prompt user for the file name.
set /P "FileToCopy=Please enter a file name and extension: "
rem Has the user not entered anything, prompt the user once more.
if not defined FileToCopy goto FileNamePrompt
rem Remove all double quotes from user input string.
set "FileToCopy=%FileToCopy:"=%"
rem Has the user input just one or more ", prompt the user once more.
if not defined FileToCopy goto FileNamePrompt
rem Check if the user input string really references an existing file.
if not exist "%FileToCopy%" (
echo File "%FileToCopy%" does not exist.
goto FileNamePrompt
)
rem Check if the user input string really references
rem an existing file and not an existing directory.
if exist "%FileToCopy%\" (
echo "%FileToCopy%" references a directory.
goto FileNamePrompt
)
copy /B /Y "%FileToCopy%" "%~dp0Templatecopy.doc" >nul
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
call /? ... explains %~dp0 which is expanding to drive and path of argument 0 which is the batch file path always ending with a backslash.
copy /?
echo /?
goto /?
if /?
rem /?
set /?

having trouble using spaces in folder names

When the user enters a space in the folder name, I can create and remove the folder with the following code, but the line to start or open the folder will not work.
I have tried several different things. If I use the "%input%" in the start line the quotes are used as part of the folder name so it is not recognized. If I eliminate the ""'s only the first word in the name is recognized so the folder is not found. the Md and Rd lines work perfectly with the quotes.
#echo off
echo Type in the name of your folder and hit enter.
set /P x=Please type the folder name here:
md %userprofile%\desktop\"%x%"
start %userprofile%\desktop\"%x%"
pause
rd %userprofile%\desktop\"%x%"
I expected the folder to open on the desktop and just get an error that the name is not recognized.
Please read answer on How to stop Windows command interpreter from quitting batch file execution on an incorrect user input? and the commends in batch code below for understanding why this code is much better for your task.
It is usually necessary to enclose the entire argument string in double quotes and not just parts of it as it can be seen below.
#echo off
setlocal EnableExtensions DisableDelayedExpansion
echo Type in the name of your folder and hit ENTER.
:UserPrompt
set "Folder="
set /P "Folder=Please type the folder name here: "
rem Has the user entered a string at all?
if not defined Folder goto UserPrompt
rem Remove all double quotes of user input string.
set "Folder=%Folder:"=%"
rem Was not only one or more double quotes entered by the user?
if not defined Folder goto UserPrompt
rem Create the folder with suppressing the error message.
md "%UserProfile%\Desktop\%Folder%" 2>nul
rem Could the folder name be created at all which means the user
rem input string was valid and the folder did not exist already?
if errorlevel 1 goto UserPrompt
rem Open the just created folder on user's desktop.
start "" "%UserProfile%\Desktop\%Folder%"
pause
rd "%UserProfile%\Desktop\%Folder%"
endlocal
Instead of the command line
start "" "%UserProfile%\Desktop\%Folder%"
it is also possible to use
%SystemRoot%\explorer.exe "%UserProfile%\Desktop\%Folder%"
or use
%SystemRoot%\explorer.exe /e,"%UserProfile%\Desktop\%Folder%"
explorer.exe is an exception of general rule to enclose an entire argument string in double quotes. "/e,%UserProfile%\Desktop\%Folder%" would not work because in this case the argument string would be interpreted as folder with an invalid relative path to root directory of current drive instead of option /e with folder to open.
But Windows Explorer does not offer options to define window position and size. Whatever the user used the last time and is therefore most likely preferred by the user is used again by Windows Explorer on opening an Explorer window for a folder.
It would be of course possible with additional code to send to the just opened Explorer window being top-level foreground window a message for changing window position and size. See for example:
How can a batch file run a program and set the position and size of the window?
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
echo /?
endlocal /?
if /?
md /?
pause /?
rd /?
rem /?
set /?
setlocal /?
start /?

Making a directory on a path stored inside a variable in batch file

I'm new in batch programming. The thing is I have a path and a new folder name in 2 variables, so I want to concatenate it and make a new folder in that result path. I tried many things but nothing worked. Please help
I tried this code
#echo off
setlocal EnableDelayedExpansion
set ver=project
set spath=d:\a\svn\
set path=!%spath%%ver%!
mkdir %path%
pause
endlocal
Do not use path as name for an environment variable because such an environment variable is defined already by default with a very important meaning, see the answers on What is the reason for 'sort' is not recognized as an internal or external command, operable program or batch file?
To concatenate two environment variable values just reference those two environment variables on assigning the value to one of the two environment variables or a new environment variable.
#echo off
setlocal EnableExtensions DisableDelayedExpansion
set "ProjectVersion=project"
set "SvnPath=d:\a\svn\"
set "ProjectPath=%SvnPath%%ProjectVersion%"
mkdir "%ProjectPath%"
pause
endlocal
See also answer on Why is no string output with 'echo %var%' after using 'set var = text' on command line? for the reason using set "variable=value" with double quotes around string value to variable assignment, i.e. around the argument string of command SET.
The commands SETLOCAL and ENDLOCAL would not be really necessary here.
Possible would be also:
#echo off
set "ProjectVersion=project"
set "SvnPath=d:\a\svn\"
set "ProjectPath=%SvnPath%%ProjectVersion%"
mkdir "%ProjectPath%" 2>nul
if not exist "%ProjectPath%\" echo Failed to create directory "%ProjectPath%" & pause & goto :EOF
The batch file above creates the directory with suppressing any error message by redirecting STDERR to device NUL. An error message is output if the directory already exists or it was not possible to create the directory because NTFS permissions denies folder creation for current user or in directory path there is a file with the name of a directory in path, e.g. there is a file with name project in directory d:\a\svn or there is a file svn in directory d:\a. The next command with a backslash appended to directory path checks if the directory exists after execution of command MKDIR and outputs an error message with PAUSE and next exiting batch file when the directory still does not exist.
Read also the Microsoft article about Using Command Redirection Operators for an explanation of 2>nul and Single line with multiple commands using Windows batch file for an explanation of & operator.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
echo /?
endlocal /?
goto /?
if /?
mkdir /?
pause /?
set /?
setlocal /?
#echo off
setlocal EnableDelayedExpansion
set version=project
set spath=d:\a\svn\
set mypath=%spath%%version%
mkdir %mypath%
pause
endlocal
path is a reserved name - it defines the sequence of directories that is searched for an executable if the executable is not found in the current directory. If you change it, well - in short, gloom
ver is not a reserved name, but it is the name of a inbuilt utility and makes a poor choice for variable-name.
Your code was attempting to set your desired new pathname to the contents of the variable d:\a\svn\project. Since this variable is very unlikely to exist, you would have attempted to make a directory named nothing.
btw - there is no need to set mypath - md %spath%%ver% would work just as well. MD is a synonym of mkdir and is used more often.

Why is a subfolder with space recognized as file on execution of my batch script?

In my code I'm searching for only files in folder and all subfolders. When the name of subfolder has one blank (space) between the words this subfolder is recognized as a file, too. This is not correct behavior. The parameter /a-d doesn't help here.
#echo on
Setlocal EnableDelayedExpansion
set "input=C:\Users\NekhayenkoO\test\"**
set "output=C:\Users\NekhayenkoO\outputxml\"**
set string1=Well-Formed and valid
set string2=Well-Formed, but not valid
set string3=Not well-formed
set /a loop=0
set /a loop1=0
set /a loop2=0
set /a loop3=0
for /f %%a in ('dir /b /a-d /s %input%') do (
CALL jhove -m PDF-hul -h xml -o %output%\%%~na.xml %%a
if !ERRORLEVEL! EQU 0 (echo Errorlevel equals !errorlevel! )
if !ERRORLEVEL! GEQ 1 (Errorlevel equals !errorlevel! )
set /a loop3+=1
)
The output of the script on running in directory C:\Users\NekhayenkoO\jhove-beta:
Setlocal EnableDelayedExpansion
set "input=C:\Users\NekhayenkoO\test\"**
set "output=C:\Users\NekhayenkoO\outputxml\"**
set string1=Well-Formed and valid
set string2=Well-Formed, but not valid
set string3=Not well-formed
set /a loop=0
set /a loop1=0
set /a loop2=0
set /a loop3=0
for /F %a in ('dir /b /a-d /s "C:\Users\NekhayenkoO\test\"') do (
echo Verarbeite %~na
CALL jhove -m PDF-hul -h xml -o "C:\Users\NekhayenkoO\outputxml\\%~na.xml" "%a"
if !ERRORLEVEL! EQU 0 (echo Errorlevel equals !errorlevel! )
if !ERRORLEVEL! GEQ 1 (Errorlevel equals !errorlevel! )
set /a loop3+=1
)
(
echo Verarbeite 757419577
CALL jhove -m PDF-hul -h xml -o "C:\Users\NekhayenkoO\outputxml\\757419577.xml" "C:\Users\NekhayenkoO\test\757419577.pdf"
if !ERRORLEVEL! EQU 0 (echo Errorlevel equals !errorlevel! )
if !ERRORLEVEL! GEQ 1 (Errorlevel equals !errorlevel! )
set /a loop3+=1
)
Verarbeite 757419577
Errorlevel equals 0
Verarbeite GBV58575165X
Errorlevel equals 0
Verarbeite GBV85882115X
java.lang.ClassCastException: edu.harvard.hul.ois.jhove.module.pdf.PdfSimpleObject cannot be cast to edu.harvard.hul.ois.jhove.module.pdf.PdfDictiona
at edu.harvard.hul.ois.jhove.module.PdfModule.readDocCatalogDict(PdfModule.java:1344)
at edu.harvard.hul.ois.jhove.module.PdfModule.parse(PdfModule.java:521)
at edu.harvard.hul.ois.jhove.JhoveBase.processFile(JhoveBase.java:803)
at edu.harvard.hul.ois.jhove.JhoveBase.process(JhoveBase.java:588)
at edu.harvard.hul.ois.jhove.JhoveBase.dispatch(JhoveBase.java:455)
at Jhove.main(Jhove.java:292)
Errorlevel equals 0
Verarbeite GBV858852357
Errorlevel equals 0
Verarbeite nicht_valide_PDF
Errorlevel equals 0
Verarbeite not_Wellformed_intern
Errorlevel equals 0
Verarbeite pp1788_text
Errorlevel equals 0
Verarbeite Rosetta_Testdatei
Errorlevel equals 0
Verarbeite script
Errorlevel equals 0
Verarbeite java
Errorlevel equals 0
Verarbeite java
Errorlevel equals 0
Verarbeite java
Errorlevel equals 0
Verarbeite java
Errorlevel equals 0
Verarbeite GBV58525785X
Errorlevel equals 0
Verarbeite GBV58574517X
Errorlevel equals 0
Drücken Sie eine beliebige Taste . . .
What is jhove?
Oleg Nekhayenko, you have asked several jhove related questions in the last days, but you have always forgotten to explain what jhove is which is important to know for all of your questions.
Therefore I searched in world wide web for jhove, found very quickly the homepage
JHOVE | JSTOR/Harvard Object Validation Environment, read quickly its documentation and command-line interface description and finally downloaded also jhove-1_11.zip from SourceForge project page of JHOVE.
All this was done by me to find out that jhove is a Java application which is executed on Linux and perhaps also on Mac using the shell script jhove and on Windows the batch file jhove.bat for making it easier to use by users.
You could have saved yourself and all readers of your questions a lot of time if you would have written jhove.bat instead of just jhove in your code snippets or at least mentioned anywhere that jhove is a batch file.
Assigning a value/string to an environment variable
I suggest to read first the answer on
Why is no string output with 'echo %var%' after using 'set var = text' on command line?
and next look on these two lines:
set "input=C:\Users\NekhayenkoO\test\"**
set "output=C:\Users\NekhayenkoO\outputxml\"**
I don't know why two asterisks are at end of those 2 command lines. But that does not really matter as both asterisk are ignored on assigning the two paths to the two environment variables.
This can be seen on posted output of the batch file as there is no asterisk output on the lines:
for /F %a in ('dir /b /a-d /s "C:\Users\NekhayenkoO\test\"') do (
CALL jhove -m PDF-hul -h xml -o "C:\Users\NekhayenkoO\outputxml\\757419577.xml" "C:\Users\NekhayenkoO\test\757419577.pdf"
There is no asterisk anywhere. So the environment variables input and output are obviously defined without the asterisks at end which is even good here.
Enclosing directory and file names in double quotes
The help output on running cmd /? in a command prompt window explains in last paragraph on last help page on which characters in a directory or file name double quotes must be used around complete directory/file name.
The space character is the string delimiting character on command line and therefore a directory or file name with a space must be always enclosed in double quotes.
Predefined environment variables on Windows
Opening a command prompt window and running set results in output of all environment variables defined for the the current user account including PATH and PATHEXT as also USERNAME and USERPROFILE.
The Wikipedia article about Windows Environment Variables explains the environment variables predefined by Windows. It is advisable to make use of them in batch files.
Execution of applications and scripts on Windows
If in a command prompt window or in a batch file just the file name of an application or script without file extension and without path is specified, the Windows command interpreter is searching first in current directory and next in all directories of environment variable PATH for a file with specified name having a file extension listed in environment variable PATHEXT. In this case Windows command interpreter is searching for jhove.*.
The values of the environment variables PATH and PATHEXT can be seen on opening a command prompt window and running in this window set path which results in output of all environment variables starting with the case-insensitive interpreted string PATH with their current values.
Next to know is that when Windows command interpreter searches for jhove.*, the NTFS file system returns the file names matching this search pattern sorted alphabetically. So if current directory or any of the directories listed in PATH have for example jhove.bat and jhove.exe, the NTFS file system returns first jhove.bat. This batch file is used by Windows command interpreter as file extension BAT is listed by default in PATHEXT.
But if the file system of the drive with jhove.* files is FAT, FAT32 or ExFat, the file system returns the file names matching the search pattern in order as stored in the file allocation table and therefore unsorted. So in case of a directory contains jhove.bat and jhove.exe on a drive with any FAT file system, it is unpredictable which file is executed by Windows command interpreter on specifying just jhove in a batch file.
For that reason it is always advisable to specify the application or script with file name and at least also with the file extension. And if possible the entire path to the application to run or the script to call should be also specified.
The Windows command interpreter does not need to search around by specifying the name of an application or script file with file extension and with complete path.
See also answer on Where is "START" searching for executables?
Calling a batch file versus running an application
A batch file is a script (text file) interpreted by Windows command interpreter line by line whereby a command block starting with ( and ending with matching ) is interpreted like a subroutine defined on one line.
An application is an executable (binary file) compiled with a compiler for a specific processor or processor family and therefore does not need to be interpreted anymore on execution. It contains already processor instructions (machine code).
Why the command call must be used to run another batch file from within a batch file is explained in detail by the answers on
How to call a batch file that is one level up from the current directory?
In a Windows batch file, can you chain-execute something that is not another batch file?
For that reason it is very important to know what jhove is. It is a batch file and must be therefore called with command call which answers the question How to process 2 for loops after each other in batch?
For help on command call open a command prompt window and run call /?. The output help explains also which placeholders exist to reference arguments of the batch file whereby argument 0 is the name of the batch file.
Which command lines contains jhove.bat?
On unexpected behavior on calling a batch file from another batch file it is important to know the code of the called batch file as well because the error could be in code of called batch file.
Code of jhove.bat as stored in jhove-1_11.zip without instruction comments:
#ECHO OFF
SET JHOVE_HOME=%~dp0
SET EXTRA_JARS=
REM NOTE: Nothing below this line should be edited
REM #########################################################################
SET CP=%JHOVE_HOME%\bin\JhoveApp.jar
IF "%EXTRA_JARS%"=="" GOTO FI
SET CP=%CP%:%EXTRA_JARS
:FI
REM Retrieve a copy of all command line arguments to pass to the application
SET ARGS=
:WHILE
IF %1x==x GOTO LOOP
SET ARGS=%ARGS% %1
SHIFT
GOTO WHILE
:LOOP
REM Set the CLASSPATH and invoke the Java loader
java -classpath %CP% Jhove %ARGS%
Well, this is a not good written batch code for following reasons:
The commands setlocal and endlocal are not used in batch file to control the life time of variables used by this batch file. See answer on change directory command cd ..not working in batch file after npm install for more details. npm.bat is also a not good coded batch file like jhove.bat as it turned out.
The command line SET JHOVE_HOME=%~dp0 defines the environment variable JHOVE_HOME with drive and path of storage location of jhove.bat. The path returned by %~dp0 ends always with a backslash. If jhove*.zip was extracted into a directory with 1 or more space in complete path, care must be taken wherever JHOVE_HOME is finally used to enclose the final string in double quotes.
The command line SET CP=%JHOVE_HOME%\bin\JhoveApp.jar defines the environment variable CP by concatenating path to batch file jhove.bat with a fixed path and name of the Java package. Here is already a small mistake as %~dp0 is a path always ending with a backlash concatenated with a string starting with a backslash. So there are two backslashes finally in path to the Java package file. But Windows kernel handles this error in path and therefore it does not really matter.
The environment variable CP is referenced unmodified with no EXTRA_JARS defined by the user finally on command line java -classpath %CP% Jhove %ARGS%. The error here is %CP% is specified without being enclosed in double quotes which results in unexpected behavior if jhove*.zip was extracted indeed by the user into a directory with 1 or more spaces in complete path.
A percent sign is missing at end of command line SET CP=%CP%:%EXTRA_JARS.
The writer of jhove.bat did not know obviously anything about %* which on usage of last command line instead of %ARGS% makes the WHILE loop above completely useless.
Much better for jhove.bat would be:
#echo off
setlocal EnableExtensions
set "JHOVE_HOME=%~dp0"
set "EXTRA_JARS="
REM NOTE: Nothing below this line should be edited
REM #########################################################################
set "CP=%JHOVE_HOME%bin\JhoveApp.jar"
if not "%EXTRA_JARS%"=="" set "CP=%CP%:%EXTRA_JARS%"
rem Set the CLASSPATH and invoke the Java loader
java.exe -classpath "%CP%" Jhove %*
endlocal
The executable java.exe must be found via environment variable PATH by Windows command interpreter.
Final batch code for usage
I suggest to use the following code for this task in case of jhove.bat should not be modified to above working code:
#echo off
setlocal EnableExtensions
set "InputFolder=%USERPROFILE%\test"
set "OutputFolder=%USERPROFILE%\outputxml"
echo Searching for bin\JhoveApp.jar in:
echo.
set "SearchPath=%CD%;%PATH%"
set "SearchPath=%SearchPath:)=^)%"
for /F "delims=" %%I in ('echo %SearchPath:;=^&ECHO %') do (
echo %%I
if exist "%%~I\bin\JhoveApp.jar" (
set "JHOVE_HOME=%%~I"
goto RunJHOVE
)
)
echo.
echo Error reported by %~f0:
echo.
echo Could not find bin\JhoveApp.jar in current directory and folders of PATH.
echo.
endlocal
pause
goto :EOF
:RunJHOVE
if "%JHOVE_HOME:~-1%" == "\" (
set "CP=%JHOVE_HOME%bin\JhoveApp.jar"
) else (
set "CP=%JHOVE_HOME%\bin\JhoveApp.jar"
)
echo.
echo Using %CP%
md "%OutputFolder%" 2>nul
rem for /F %%I in ('dir /A-D /B /S "%InputFolder%\*" 2^>nul') do (
rem java.exe -classpath "%CP%" Jhove -m PDF-hul -h xml -o "%OutputFolder%\%%~nI.xml" "%%I"
rem )
for /R "%InputFolder%" %%I in (*) do (
java.exe -classpath "%CP%" Jhove -m PDF-hul -h xml -o "%OutputFolder%\%%~nI.xml" "%%I"
)
endlocal
The input and output folder paths are defined without backslash at end and without asterisk using predefined environment variable USERPROFILE.
A slightly modified code written by Magoo in his answer on Find the path used by the command line when calling an executable is used to find Java package of JHOVE. The batch file prints the folders it is searching for in case of the file could not be found which results in an error message and halting batch execution until the user presses any key.
The class path variable CP is created with taking into account if folder path ends with a backslash or not. Folder paths in PATH should be defined without backslash at end, but there are always installers which add folder paths not 100% correct to PATH. However, it does not really matter if the result would be \\ anywhere within a path as Windows kernel handles this. That's the reason why if exist "%%~I\bin\JhoveApp.jar" also always works although this file existence test could be also done with two backslashes in path depending on folder path in PATH.
Next the output folder is created without checking first if the folder is already existing and without checking if folder creation was successful at all.
The batch code contains two solutions for running jhove on each file found recursively in input folder path. The first one is commented out. It would have the advantage to work also for hidden and system files. The second solution does not work for hidden and system files, but this is most likely not necessary here. The second solution is therefore the preferred one.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
echo /?
endlocal /?
for /?
goto /?
if /?
md /?
pause /?
set /?
setlocal /?
And read also the Microsoft articles:
Microsoft's command-line reference
Using command redirection operators
Testing for a Specific Error Level in Batch Files

Create Folder on desktop using user input in Batch File

I am trying to make a batch file that will make a folder on the desktop from user input. Here is my code:
echo What do you want the folder to be called?
SET /p folderName=
md C:\Users\%username%\desktop\%folderName%
However, whenever I try this, It gives me an error saying:
A subdirectory or file C:\Users\Razi\desktop\ already exists.
It doesn't seem to be noticing the %folderName% at the end.
Can somebody tell me what's wrong with my code and give an alternative? Thank you!
Oviously, %folderName% appears to be empty, as you can see in the error message which includes the path argument the md command receives. So md tries to create the already existing directory Desktop.
If the error appears even when you enter a valid directory name, I am pretty sure that the code fragment is part of a block in between parentheses, in which case you need to enable and apply delayed expansion. Otherwise you read the folderName value present before the entire block is executed.
For instance, the following block is seen as a single command line by the command interpreter; %folderName% is expanded (replaced by its value) as soon as the whole line/block is parsed:
(
echo What do you want the folder to be called?
set /P folderName=
md "%USERPROFILE%\desktop\%folderName%"
)
In the following, delayed expansion is enabled (by setlocal); to actually use it, the % expansion has been changed to !; so !folderName! is expanded (read) later, as soon as it is executed:
setlocal EnableDelayedExpansion
rem ...
(
echo What do you want the folder to be called?
set /P folderName=
md "%USERPROFILE%\desktop\!folderName!"
)
rem ...
endlocal
Note that the changed value of folderName is no longer available as soon as endlocal has been executed, or the batch file terminates (where an implicit endlocal happens).
In addition to the above, I put quotation marks around the path at the md command to avoid trouble with white-spaces or special characters, and I changed C:\Users\%USERNAME% to %USERPROFILE% as recommended in Stephan's comment.

Resources