I hope you can help me.
I am using youtube-dl on windows (youtube-dl.exe)
Downloading the video works great and also just the audio. But what i want is for it to save the audio file in a different place eg. C:\Users*******\Desktop
I made a batch file with this code:
:audio
cls
echo.
echo.
echo Your audio vill be downloaded and saved as a .mp3 format
echo.
echo.
set /p audio=Enter Video URL here:
cls
youtube-dl.exe --extract-audio --audio-format mp3 --output C:\Users\*******\Desktop\(ext)s.%(ext)s %audio%
pause
cls
echo.
echo.
echo.
echo.
echo Your audio has now been downloaded.
ping localhost -n 3 >nul
exit
and then it gives me this
Usage: youtube-dl.exe [OPTIONS] URL [URL...]
youtube-dl.exe: error: You must provide at least one URL.
Type youtube-dl --help to see a list of all options.
Press any key to continue . . .
It works fine if i use this but it saves it in the same folder.
:audio
cls
echo.
echo.
echo Your audio vill be downloaded and saved as a .mp3 format
echo.
echo.
set /p audio=Enter Video URL here:
cls
youtube-dl.exe --extract-audio --audio-format mp3 %audio%
pause
cls
echo.
echo.
echo.
echo.
echo Your audio has now been downloaded.
ping localhost -n 3 >nul
exit
Also please keep in mind that it also uses ffprobe.exe and ffmpeg.exe (They are both in the same folder as youtube-dl.exe
Open a command prompt window and run there cmd /?. This command outputs the help for the Windows command processor. On last help page in last paragraph there is written which characters in a directory or file name or arguments of executables and scripts require the usage of double quotes: space and &()[]{}^=;!'+,`~
The character % has a special meaning in batch files as it marks the beginning and end of an immediately expanded environment variable reference or a batch file argument reference or a loop variable reference. The percent sign must be escaped with one more % to specify a literally interpreted % character.
In command prompt window run set and there are displayed the standard environment variables for the user account on the machine. One of those standard environment variables is USERPROFILE which holds the path to the current user's profile folder containing by default, for example, the subfolder Desktop.
Now let us look on the following line from your batch file:
youtube-dl.exe --extract-audio --audio-format mp3 --output C:\Users\*******\Desktop\(ext)s.%(ext)s %audio%
It would be good to use here a reference to the environment variable USERPROFILE for the Desktop directory. The user account name could contain a space character and therefore it is advisable to enclose the path in double quotes. Next there are parentheses and a single percent sign which definitely require double quotes and escaping the percent sign.
The URL stored in environment variable audio can't contain a space character as in URLs a space character must be encoded with %20. But this single percent sign causes again troubles on interpreting the line by Windows command processor. The solution is using delayed expansion.
Let us look on this batch code:
#echo off
setlocal EnableExtensions EnableDelayedExpansion
set "ToolPath=%~dp0"
cd /D "%USERPROFILE%\Desktop"
rem The directory may not exist. It would be a good idea to check that.
:audio
cls
echo/
echo/
echo Your audio will be downloaded and saved as a .mp3 format
echo/
echo/
set "audio="
:PromptUser
set /P "audio=Enter audio URL here: "
if not defined audio goto PromptUser
set "audio=!audio:"=!"
if not defined audio goto PromptUser
"%ToolPath%youtube-dl.exe" --extract-audio --audio-format mp3 --output "%USERPROFILE%\Desktop\(ext)s.%%(ext)s" "!audio!"
pause
cls
echo/
echo/
echo/
echo/
echo Your audio has now been downloaded.
%SystemRoot%\System32\ping.exe 127.0.0.1 -n 4 >nul
endlocal
The batch file first creates a local copy of all environment variables, enables command extensions and delayed variable expansion, and pushes also current working directory path on stack.
Next the path of the directory containing the batch file and the other executables used by this batch file is assigned to variable ToolPath. Run in command prompt window call /? for details on %~dp0 (drive and path of argument 0 – the batch file – always ending with a backslash).
Then the current directory is changed to the Desktop directory of the currently used user account independent from which drive the batch file was started. Run in command prompt window cd /? for details about this command and its options.
The line with youtube-dl.exe is changed as now the executable is called with full path (as current working directory is now the user's Desktop directory). Also the output directory is enclosed now in double quotes, uses also environment variable USERPROFILE, has escaped the single percent sign with one more % and the URL is referenced now in double quotes using delayed expansion (exclamation marks instead of percent signs). Run in a command prompt window set /? for help and details about delayed expansion.
For a timeout of 3 seconds the value used on command PING must be 4 as the first ping is always immediately successful.
The command ENDLOCAL results in discarding the local copy of the table with the environment variables (ToolPath is not defined anymore after this line and all changes on other variables are lost), restores previous values for delayed expansion (most likely turning it off as not enabled by default) and command extensions (most likely being still enabled as by default) and also restoring previous working directory (most likely the path of the batch file if started with a double click).
See also:
How does the Windows Command Interpreter (CMD.EXE) parse scripts?
DosTips forum topic: ECHO. FAILS to give text or blank line - Instead use ECHO/
How to stop Windows command interpreter from quitting batch file execution on an incorrect user input?
Path of user desktop in batch files
Related
Problem
I am writing some .cmd / .bat files on a windows machine that need to work on an sd card with variable parent directories. The sd card will likely change drive names (Drive A, Drive E, etc.) as it moves from device to device and I want to write cmd files that will anticipate that. I would like this to work with my linux steam deck if possible, but if not I understand.
Rom Location
E:\Games\Nintendo\3DS\Games\Animal Crossing New Leaf.3ds
Core Location
E:\Games\RetroArch\cores\citra_libretro.dll
3DS.cmd , currently works at this address
#echo off
echo Keeping Window Active for GOG Time Tracking
cd "E:\Games\RetroArch\"
"retroarch.exe" -L "cores\citra_libretro.dll" %1 -f
Animal Crossing New Leaf.cmd , currently works at this address
#echo off
call "3DS.cmd" "E:\Games\Nintendo\3DS\Games\Animal Crossing New Leaf.3ds"
Question
How would I write the code above as a windows file on any non-specific drive directory where the current Directory is on the Drive named E:\ ?
(Ex: A:\ , or B:, and so on)
There can be used the following lines in the batch file 3DS.cmd if this batch file is stored in root of the SD card and is executed from the SD card mounted as drive with a drive letter:
#echo off
echo Keeping window active for GOG time tracking
cd /D "%~d0\Games\RetroArch"
retroarch.exe -L cores\citra_libretro.dll %1 -f
The usage help of command CALL output on running call /? in a command prompt window explains how to reference the arguments of a batch file. There is always the argument 0 even on batch file is executed without any argument string passed to the batch file by a user or another process.
%0 references the string used to start the execution of the batch file. On double clicking on a batch file stored on an SD card mounted with a drive letter by Windows, %0 expands to the fully qualified file name of the batch file on the SD card enclosed in " because of the Windows File Explorer starts in background:
C:\WINDOWS\system32\cmd.exe /c ""Animal Crossing New Leaf.cmd" "
The usage help of the Windows Command Processor cmd.exe output on running cmd /? explains how the arguments are interpreted by cmd.exe in this case. The first and the last " are removed from the command line. The started cmd.exe executes therefore:
"E:\Animal Crossing New Leaf.cmd"
That string with the double quotes is argument 0 of the executed batch file.
%~d0 can be used in the batch file to reference just the drive letter and the colon of the currently running batch file respectively \\ if the batch file is stored on a network resource executed using its UNC path.
The code above works only for batch file being stored in root of a storage media mounted with a drive letter.
A code for 3DS.cmd working always independent on which storage media the batch file is stored and in which directory and how the batch file is started as long as the directory Games is a subdirectory of the directory containing the batch file is:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
cls
if "%~1" == "" echo ERROR: %~nx0 called without game file name!& pause & exit /B
pushd "%~dp0Games\RetroArch"
echo Keeping window active for GOG time tracking
retroarch.exe -L cores\citra_libretro.dll %1 -f
popd
endlocal
%~dp0 expands to full path of the batch file always ending with a backslash.
See also: What is the reason for batch file path referenced with %~dp0 sometimes changes on changing directory? The bug of cmd.exe does not matter here because of %~dp0 is used before changing the current directory the first time with the command PUSHD.
The batch file Animal Crossing New Leaf.cmd stored in same directory as 3DS.cmd should contain only the single command line:
#call "%~dp03DS.cmd" "%~dp0Games\Nintendo\3DS\Games\Animal Crossing New Leaf.3ds"
The two batch files can be used with these improvements also on copying all directories and files on the SD card to a directory of user´s choice like %UserProfile%\RetroGames.
It is also possible to use only one batch file with name Animal Crossing New Leaf.cmd stored in the directory with the subdirectory Games and all the other directories and files with the following lines:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
pushd "%~dp0Games\RetroArch" || (echo ERROR: Missing subdirectory "Games\RetroArch"& pause & exit /B)
echo Keeping window active for GOG time tracking
retroarch.exe -L cores\citra_libretro.dll "%~dp0Games\Nintendo\3DS\Games\Animal Crossing New Leaf.3ds" -f
popd
endlocal
To understand the commands used and how they work, open a command prompt window, execute there the following commands, and read the displayed help pages for each command, entirely and carefully.
call /?
cd /?
echo /?
endlocal /?
exit /?
if /?
pause /?
popd /?
pushd /?
setlocal /?
I used Chat GPT, it gave me this result that is now working.
3ds.cmd
#echo off
echo Keeping Window Active for GOG Time Tracking
set sd_dir=%cd:~0,1%
cd "%sd_dir%:\Games\RetroArch\"
"retroarch.exe" -L "cores\citra_libretro.dll" %1 -f
Animal Crossing New Leaf.cmd
#echo off
set sd_dir=%cd:~0,1%
call "3DS.cmd" "%sd_dir%:\Games\Nintendo\3DS\Games\Animal Crossing New Leaf.3ds"
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 /?
cd %cd%
ffmpeg -i %cd%/%04d.png out.mp4
A script with just this in it works completely fine and outputs exactly what I need it to, but:
:: A simple script to convert a png or jpg image sequence to an
mp4 file with ffmpeg
cls
#echo off
title PNG2MP4
color C
echo Ensure you have ffmpeg installed and setup in your environment variables or this script won't work.
:QUERY
echo This will convert all image files in the following directory to a single mp4,
echo %cd%
echo are the files PNGs or JPEGs(PNG/P/JPG/J/CANCEL)?
set/p "ch=>"
if /I %ch%==PNG goto CONVERTPNG
if /I %ch%==P goto CONVERTPNG
if /I %ch%==JPG goto CONVERTJPG
if /I %ch%==J goto CONVERTJPG
if /I %ch%==CANCEL goto :eof
echo Invalid choice & goto QUERY
:CONVERTPNG
cd %cd%
ffmpeg -i %cd%/%04d.png out.mp4
:CONVERTJPG
cd %cd%
ffmpeg -i %cd%/%04d.jpg out.mp4
This more complex version of the script fails, outputting:
C:\tmp/img2mp4.bat4d.jpg: No such file or directory
Why is it no longer calling the files that it did before and is there an easy fix for this?
Here is my suggestion for the batch file:
#echo off
rem A simple script to convert a png or jpg image sequence to an mp4 file with ffmpeg
cls
title PNG2MP4
color C
echo Ensure you have ffmpeg installed and setup in your environment variables
echo or this script won't work.
echo/
echo This will convert all image files in the following directory to a single mp4:
echo/
echo %cd%
echo/
%SystemRoot%\System32\choice.exe /C PJC /N /M "Are the files PNGs or JPEGs or Cancel (P/J/C)? "
if errorlevel 3 color & goto :EOF
echo/
if errorlevel 2 (
ffmpeg.exe -i %%04d.jpg out.mp4
) else (
ffmpeg.exe -i %%04d.png out.mp4
)
color
The character % must be escaped in a batch file with one more % to be interpreted as literal character which was the main problem causing the batch file not working as expected. %0 references the string used to start the batch file which was img2mp4.bat. So %04d.jpg concatenated img2mp4.bat with 4d.jpg and the result was running ffmpeg.exe with img2mp4.bat4d.jpg as file name instead of the argument string %04d.jpg.
To reference one or more files/folders in current directory the file/folders can be simply specified in arguments list of a script or application with no path. This is explained in Microsoft documentation about Naming Files, Paths, and Namespaces. This page describes further that on Windows the directory separator is the backslash character \ and not the forward slash / as on Linux and Mac. / is used on Windows mainly for options as it can be seen on line with command CHOICE because of this character is not possible in file/folder names. - is used on Linux/Mac for options which is possible also in file/folder names even as first character of a file/folder name. So on Windows \ should be always used as directory separator although the Windows kernel functions for file system accesses automatically correct / in file/folder names to \.
CHOICE is much better for prompting a user to take a choice from several offered options than the command SET with option /P. set/p is syntactically not correct at all because of command set should be separated with a space from option /P which should be separated with a space from next argument variable=prompt text. set/p forces cmd.exe to automatically correct the command line to set /p. Batch files should be syntactically correct coded and not depend on automatic error corrections of Windows command processor.
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 how to reference batch file arguments.
echo /?
rem /?
cls /?
title /?
color /?
set /?
choice /?
if /?
goto /?
Further I suggest to read:
How does the Windows Command Interpreter (CMD.EXE) parse scripts?
Why is no string output with 'echo %var%' after using 'set var = text' on command line?
How to stop Windows command interpreter from quitting batch file execution on an incorrect user input?
Single line with multiple commands using Windows batch file
ECHO. FAILS to give text or blank line - Instead use ECHO/
Where does GOTO :EOF return to?
I'm creating a batch script to a get a file based on what option the user chooses. The only problem is, the file in the ftp server has a colon and from what i've researched, windows does not accept ":" colon.
Is it possible to replace that character before downloading?
Below is a sample of my code.
Echo open sample.net>first.dat
Echo user>>first.dat
Echo password>>first.dat
Echo ascii>>first.dat
Echo cd directory>>first.dat
Echo lcd folder>>first.dat
Echo get sample-text-10-16-2017_16:36:00:340033.txt>>first.dat
Echo bye>>first.dat
ftp -v -i -s:first.dat
del first.dat
As you can see also, I get a list first of the file names inside the folder for the user to input the file name. I just wrote a specific file name for the example
I'm still not familiar with the for loops in batch but I think that it is one way of replacing the characters in a file name before downloading
[Untried]
get remotefilename localfilename
is apparently valid, so placing a valid windows filename as a second argument should d/l to the file specified.
[Addendum - also untried]
(after Echo lcd folder>>first.dat)
echo mls remotefilesrequired awindowlistfilename>>first.dat
rem this should log in and create awindowslistfilename
rem containing the remote filelist
ftp -v -i -s:first.dat
del second.dat 2>nul
setlocal enabledelayedexpansion
for /f "delims=" %%a in (awindowslistfilename) do (
set "remote=%%a"
echo get !remote! !remote::=.!>>second.dat
)
endlocal
Echo bye>>second.dat
ftp -v -i -s:second.dat
del first.dat
del second.dat
Since I'm not aware of the return format for mls, I'm assuming that it's a simple file-list, one to a line.
This code first executes the ftp log-on palaver and an mls command, creating awindowslistfile locally.
It then deletes second.dat (the 2>nul suppresses error messages like file not found appearing on stderr)
setlocal enabledelayedexpansion and endlocal bracket a mode where the syntax changes such that !var! may be used to access the run-time value of a variable, whereas %var% always refers to the parse-time value.
The for/f command reads the filename (parenthesised) and assigns each line in turn to the metavariable %%a. The delims= option ensures that the entire line is assigned, ignoring the normal tokenising procedure.
A series of individual get commands is then written to second.dat, with the substitution of : by . in the name.
Finally, add the bye and FTP again.
(I'm not sure whether first.dat will also require a bye and second.bat will need to prelimnary commands, but could be...)
Note that it's batch convention to enclose filenames that may contain separators like Space,; in "quotes". How FTP will feel about that, if necessary, I can only guess.
Naturally, extra lines within the loop
set "remote=!remote:x=y!"
could be used to serially replace character sequences x by y if there are any other problematic characters encountered.
I am writing a batch script that installs some applications from MSI files from the same folder.
When I write those commands in command prompt window, all is fine and all the commands work properly.
But when I write them into the batch script, suddenly most of the commands such as XCOPY, msiexec, DISM result in an error message like:
'XCOPY' is not recognized as an internal or external command, operable program or batch file.
After googling it for a while, I saw a lot of comments related to the environment variable PATH which should contain C:\Windows\system32 and I made sure its included in the PATH. Also found a lot of answers about writing the full path which I already tried and it didn't work.
I'm working on Windows server 2012.
This is the code of my batch file:
#echo off
set path=C:\ rem default path
rem get the path as parameter to the script:
set argC=0
for %%x in (%*) do Set /A argC+=1
if %argC% gtr 0 (set path=%1%)
IF %ERRORLEVEL% NEQ 0 (
echo %me%: something went wrong with input directory
)
echo Destenation: %path%
SETLOCAL ENABLEEXTENSIONS
SET me=%~n0
SET parent=%~dp0
echo %me%: starting installation of Python 2.7 64bit and Apache 64 bit
REM install .net 3.5
DISM /Online /Enable-Feature /FeatureName:NetFx3 /All /LimitAccess /Source:installationMediaDrive:\sources\sxs
msiexec /i ".\py\python-2.7.amd64.msi" TARGETDIR=%path%/Python27 /passive /norestart ADDLOCAL=ALL
mkdir %path%\Apache24
XCOPY /e /Q ".\Apache24" %path%\Apache24
It looks like the batch file should support an optionally specified path to installation directory as first parameter. The code used to check for existence of this optional folder path is very confusing. There are definitely easier methods to check for an optional parameter as it can be seen below.
The main problem is redefining environment variable PATH which results in standard console applications of Windows stored in directory %SystemRoot\System32 and other standard Windows directories are not found anymore by command interpreter cmd.exe on execution of the batch file.
In general it is required to specify an application to execute with full path, file name and file extension enclosed in double quotes in case of this complete file specification string contains a space character or one of these characters &()[]{}^=;!'+,`~ as explained in last paragraph on last output help page on running in a command prompt window cmd /?.
But mainly for making it easier for human users to execute manually applications and scripts from within a command prompt window, the Windows command interpreter can also find the application or script to run by itself if specified without path and without file extension.
So if a user enters just xcopy or a batch file contains just xcopy, the Windows command interpreter searches for a file matching the pattern xcopy.* which has a file extension as defined in semicolon separated list of environment variable PATHEXT first in current directory and if no suitable file found next in all directories in semicolon separated list of environment variable PATH.
There are 3 environment variables PATH:
The system PATH as stored in Windows registry under:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment
The folder paths in system PATH are used by default for all processes independent on used account.
The user PATH as stored in Windows registry under:
HKEY_LOCAL_MACHINE\Environment
The folder paths in user PATH are used by default only for all processes running using the account on which the user PATH was set.
The local PATH just hold in memory in currently active environment of running process.
The system and the user PATH are concatenated by Windows to a single local PATH for processes.
Every time a process starts a new process like Windows Explorer starting Windows command interpreter for execution of a batch file, a copy of the environment table of currently running process is created by Windows for the new process. So whatever a process changes on its own local copy of environment variables has no effect on all other already running processes. The local changes on the environment variables are effective only on own process and all processes started by the process modifying its variables.
On starting the batch file the variables PATH and PATHEXT have the values as displayed on running in a command prompt window opened under same user account as used on starting the batch file the command set PATH listing all variables starting with PATH case-insensitive in name.
Now let us look on the second line of the batch file:
set path=C:\ rem default path
This line redefines the local PATH environment variable. Therefore the environment variable PATH being effective for the command process executing the batch file and all applications started by this batch file does not contain anymore C:\Windows\System32;C:\Windows;..., but contains now just this very strange single folder path.
C:\ rem default path
rem is an internal command of cmd.exe and must be written on a separate line. There is no line comment possible in batch code like // in C++ or JavaScript. For help on this command run in a command prompt window rem /?.
On running the batch file without an installation folder path as first argument, the result is that Windows command interpreter searches for dism.*, msiexec.* and xcopy.* just in current directory as there is surely no directory with name rem default path with lots of spaces/tabs at beginning in root of drive C:.
Conclusion: It is no good idea to use path as variable name for the installation folder path.
Another mistake in batch code is using %1% to specify the first argument of the batch file. This is wrong as the arguments of the batch file are referenced with %1, %2, ... Run in a command prompt window call /? for help on referencing arguments of a batch file and which possibilities exist like %~dp0 used below to get drive and path of argument 0 which is the batch file name, i.e. the path of the folder containing the currently running batch file.
I suggest using this batch code:
#echo off
setlocal EnableExtensions
set "SourcePath=%~dp0"
set "BatchName=%~n0"
if "%~1" == "" (
echo %BatchName% started without an installation folder path.
set "InstallPath=C:\"
goto StartInstalls
)
rem Get installation folder path from first argument
rem of batch file without surrounding double quotes.
set "InstallPath=%~1"
rem Replace all forward slashes by backslashes in case of installation
rem path was passed to the batch file with wrong directory separator.
set "InstallPath=%InstallPath:/=\%"
rem Append a backslash on installation path
rem if not already ending with a backslash.
if not "%InstallPath:~-1%" == "\" set "InstallPath=%InstallPath%\"
:StartInstalls
echo %BatchName%: Installation folder: %InstallPath%
echo/
echo %BatchName%: Installing .NET 3.5 ...
DISM.exe /Online /Enable-Feature /FeatureName:NetFx3 /All /LimitAccess /Source:installationMediaDrive:\sources\sxs
echo/
echo %BatchName%: Installing Python 2.7 64-bit ...
%SystemRoot%\System32\msiexec.exe /i "%SourcePath%py\python-2.7.amd64.msi" TARGETDIR="%InstallPath%Python27" /passive /norestart ADDLOCAL=ALL
echo/
echo %BatchName%: Installing Apache 2.4 64-bit ...
mkdir "%InstallPath%Apache24"
%SystemRoot%\System32\xcopy.exe "%SourcePath%\Apache24" "%InstallPath%Apache24\" /C /E /H /I /K /Q /R /Y >nul
endlocal
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 /? ... for explanation of %~dp0, %~n0 and %~1.
dism /?
echo /?
endlocal /?
goto /?
if /?
msiexec /?
rem /?
set /?
setlocal /?
xcopy /?
And read also
the Microsoft TechNet article Using command redirection operators,
the Microsoft support article Testing for a Specific Error Level in Batch Files,
the answer on change directory command cd ..not working in batch file after npm install and the answers referenced there for understanding how setlocal and endlocal really work and
the answer on Why is no string output with 'echo %var%' after using 'set var = text' on command line? for understanding why using set "variable=value".
And last take a look on:
SS64.com - A-Z index of the Windows CMD command line
Microsoft's command-line reference
Windows Environment Variables (Wikipedia article)
The administrator of a Windows server should twist everything written here and on the referenced pages round one's little finger.