Command to run a .bat file - windows

I'm trying to make my Visual Studio build script execute a .bat file that does something important.
Here is what I'm want to do right now:
cd "F:\- Big Packets -\kitterengine\Common\" Template.bat
But it doesn't work.
I have to do this to make it work:
cd "F:\- Big Packets -\kitterengine\Common\"
F:
Template.bat
But this is pretty difficult to add to the Visual Studio script.
How can I do this in one single line?

"F:\- Big Packets -\kitterengine\Common\Template.bat" maybe prefaced with call (see call /?). Or Cd /d "F:\- Big Packets -\kitterengine\Common\" & Template.bat.
CMD Cheat Sheet
Cmd.exe
Getting Help
Punctuation
Naming Files
Starting Programs
Keys
CMD.exe
First thing to remember its a way of operating a computer. It's the way we did it before WIMP (Windows, Icons, Mouse, Popup menus) became common. It owes it roots to CPM, VMS, and Unix. It was used to start programs and copy and delete files. Also you could change the time and date.
For help on starting CMD type cmd /?. You must start it with either the /k or /c switch unless you just want to type in it.
Getting Help
For general help. Type Help in the command prompt. For each command listed type help <command> (eg help dir) or <command> /? (eg dir /?).
Some commands have sub commands. For example schtasks /create /?.
The NET command's help is unusual. Typing net use /? is brief help. Type net help use for full help. The same applies at the root - net /? is also brief help, use net help.
References in Help to new behaviour are describing changes from CMD in OS/2 and Windows NT4 to the current CMD which is in Windows 2000 and later.
WMIC is a multipurpose command. Type wmic /?.
Punctuation
& seperates commands on a line.
&& executes this command only if previous command's errorlevel is 0.
|| (not used above) executes this command only if previous command's
errorlevel is NOT 0
> output to a file
>> append output to a file
< input from a file
2> Redirects command error output to the file specified. (0 is StdInput, 1 is StdOutput, and 2 is StdError)
2>&1 Redirects command error output to the same location as command output.
| output of one command into the input of another command
^ escapes any of the above, including itself, if needed to be passed
to a program
" parameters with spaces must be enclosed in quotes
+ used with copy to concatenate files. E.G. copy file1+file2 newfile
, used with copy to indicate missing parameters. This updates the files
modified date. E.G. copy /b file1,,
%variablename% a inbuilt or user set environmental variable
!variablename! a user set environmental variable expanded at execution
time, turned with SelLocal EnableDelayedExpansion command
%<number> (%1) the nth command line parameter passed to a batch file. %0
is the batchfile's name.
%* (%*) the entire command line.
%CMDCMDLINE% - expands to the original command line that invoked the
Command Processor (from set /?).
%<a letter> or %%<a letter> (%A or %%A) the variable in a for loop.
Single % sign at command prompt and double % sign in a batch file.
\\ (\\servername\sharename\folder\file.ext) access files and folders via UNC naming.
: (win.ini:streamname) accesses an alternative steam. Also separates drive from rest of path.
. (win.ini) the LAST dot in a file path separates the name from extension
. (dir .\*.txt) the current directory
.. (cd ..) the parent directory
\\?\ (\\?\c:\windows\win.ini) When a file path is prefixed with \\?\ filename checks are turned off.
Naming Files
< > : " / \ | Reserved characters. May not be used in filenames.
Reserved names. These refer to devices eg,
copy filename con
which copies a file to the console window.
CON, PRN, AUX, NUL, COM1, COM2, COM3, COM4,
COM5, COM6, COM7, COM8, COM9, LPT1, LPT2,
LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, and LPT9
CONIN$, CONOUT$, CONERR$
--------------------------------
Maximum path length 260 characters
Maximum path length (\\?\) 32,767 characters (approx - some rare characters use 2 characters of storage)
Maximum filename length 255 characters
Starting a Program
See start /? and call /? for help on all three ways.
There are two types of Windows programs - console or non console (these are called GUI even if they don't have one). Console programs attach to the current console or Windows creates a new console. GUI programs have to explicitly create their own windows.
If a full path isn't given then Windows looks in
The directory from which the application loaded.
The current directory for the parent process.
Windows NT/2000/XP: The 32-bit Windows system directory. Use the
GetSystemDirectory function to get the path of this directory. The
name of this directory is System32.
Windows NT/2000/XP: The 16-bit Windows system directory. There is no
function that obtains the path of this directory, but it is
searched. The name of this directory is System.
The Windows directory. Use the GetWindowsDirectory function to get
the path of this directory.
The directories that are listed in the PATH environment variable.
Specify a program name
This is the standard way to start a program.
c:\windows\notepad.exe
In a batch file the batch will wait for the program to exit. When
typed the command prompt does not wait for graphical
programs to exit.
If the program is a batch file control is transferred and the rest of the calling batch file is not executed.
Use Start command
Start starts programs in non standard ways.
start "" c:\windows\notepad.exe
Start starts a program and does not wait. Console programs start in a new window. Using the /b switch forces console programs into the same window, which negates the main purpose of Start.
Start uses the Windows graphical shell - same as typing in WinKey + R (Run dialog). Try
start shell:cache
Also program names registered under HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths can also be typed without specifying a full path.
Also note the first set of quotes, if any, MUST be the window title.
Use Call command
Call is used to start batch files and wait for them to exit and continue the current batch file.
Other Filenames
Typing a non program filename is the same as double clicking the file.
Keys
Ctrl + C exits a program without exiting the console window.
For other editing keys type Doskey /?.
↑ and ↓ recall commands
ESC clears command line
F7 displays command history
ALT+F7 clears command history
F8 searches command history
F9 selects a command by number
ALT+F10 clears macro definitions
Also not listed
Ctrl + ←or→ Moves a word at a time
Ctrl + Backspace Deletes the previous word
Home Beginning of line
End End of line
Ctrl + End Deletes to end of line

Can refer to here: https://ss64.com/nt/start.html
start "" /D F:\- Big Packets -\kitterengine\Common\ /W Template.bat

There are many possibilities to solve this task.
1. RUN the batch file with full path
The easiest solution is running the batch file with full path.
"F:\- Big Packets -\kitterengine\Common\Template.bat"
Once end of batch file Template.bat is reached, there is no return to previous script in case of the command line above is within a *.bat or *.cmd file.
The current directory for the batch file Template.bat is the current directory of the current process. In case of Template.bat requires that the directory of this batch file is the current directory, the batch file Template.bat should contain after #echo off as second line the following command line:
cd /D "%~dp0"
Run in a command prompt window cd /? for getting displayed the help of this command explaining parameter /D ... change to specified directory also on a different drive.
Run in a command prompt window call /? for getting displayed the help of this command used also in 2., 4. and 5. solution and explaining also %~dp0 ... drive and path of argument 0 which is the name of the batch file.
2. CALL the batch file with full path
Another solution is calling the batch file with full path.
call "F:\- Big Packets -\kitterengine\Common\Template.bat"
The difference to first solution is that after end of batch file Template.bat is reached the batch processing continues in batch script containing this command line.
For the current directory read above.
3. Change directory and RUN batch file with one command line
There are 3 operators for running multiple commands on one command line: &, && and ||.
For details see answer on Single line with multiple commands using Windows batch file
I suggest for this task the && operator.
cd /D "F:\- Big Packets -\kitterengine\Common" && Template.bat
As on first solution there is no return to current script if this is a *.bat or *.cmd file and changing the directory and continuation of batch processing on Template.bat is successful.
4. Change directory and CALL batch file with one command line
This command line changes the directory and on success calls the batch file.
cd /D "F:\- Big Packets -\kitterengine\Common" && call Template.bat
The difference to third solution is the return to current batch script on exiting processing of Template.bat.
5. Change directory and CALL batch file with keeping current environment with one command line
The four solutions above change the current directory and it is unknown what Template.bat does regarding
current directory
environment variables
command extensions state
delayed expansion state
In case of it is important to keep the environment of current *.bat or *.cmd script unmodified by whatever Template.bat changes on environment for itself, it is advisable to use setlocal and endlocal.
Run in a command prompt window setlocal /? and endlocal /? for getting displayed the help of these two commands. And read answer on change directory command cd ..not working in batch file after npm install explaining more detailed what these two commands do.
setlocal & cd /D "F:\- Big Packets -\kitterengine\Common" & call Template.bat & endlocal
Now there is only & instead of && used as it is important here that after setlocal is executed the command endlocal is finally also executed.
ONE MORE NOTE
If batch file Template.bat contains the command exit without parameter /B and this command is really executed, the command process is always exited independent on calling hierarchy. So make sure Template.bat contains exit /B or goto :EOF instead of just exit if there is exit used at all in this batch file.

You can use Cmd command to run Batch file.
Here is my way =>
cmd /c ""Full_Path_Of_Batch_Here.cmd" "
More information => cmd /?

Like Linux, to run the myapp.exe, you can use only one of these three methods.
use system path
add project directory to your systeme path, then:
myapp.exe
or
myapp
use full long path
\path\to\project\myapp.exe
go to working directory
cd \path\to\project
.\myapp.exe

Related

Iterate folder and get filename for commandline input

I am trying to iterate files in a folder and process them with another batch file inside the do loop. It works with echo but as soon as I use the variable as input to the program, it echoes the () part and everything inside.
Here's what I'm trying to do.
#echo off
SETLOCAL ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION
for /r %%f in (/folder/*) do (
set name="%%~nf"
echo !name! <--- ok
process.bat !name! <--- echoes () and commands inside this do loop
)
ENDLOCAL
The process.bat just capitalizes the first letter of the filename and echoes it for debug or confirmation.
A batch file must be called from within a batch file using command call as otherwise Windows command processor continues processing on other batch file with never returning back to initial batch file.
See also: How to call a batch file that is one level up from the current directory?
Please read excellent answer on batch file echo on/off not working properly written by dbenham for the reason on getting suddenly the commands executed by FOR output after first execution of process.bat without using command CALL. I cannot explain better what happens in this case.
The directory separator on Windows is the backslash character \ and not the forward slash / as on Linux or Mac. Windows supports also / in file/folder paths for compatibility reasons by automatically replacing all / by \ before accessing the Windows file systems, but a good written script uses 100% correct syntax and does not depend on automatic corrections done by other programs. / is used on Windows mainly for command line switches.
The usage of / instead of \ can result in an unexpected behavior. For example run a batch file with following content:
#echo off
echo Files in directory %SystemRoot:\=/%/:
for %%I in (%SystemRoot:\=/%/*) echo %%I
echo/
pause
echo/
echo Files in directory %SystemRoot%\:
for %%I in (%SystemRoot%\*) echo %%I
echo/
pause
The first FOR using C:/Windows/* as wildcard pattern outputs the file names with just drive letter + colon + file name + file extension. The file path \Windows\ is missing in output file names. The second FOR loop using C:\Windows\* as wildcard pattern outputs the full qualified file names, i.e. drive letter + colon + file path + file name + file extension.
A file/folder path starting with \ references a directory or file relative to root directory of current DRIVE.
This is explained by the Microsoft documentation Naming Files, Paths, and Namespaces.
It looks like folder is a subdirectory in directory of the executed batch file. In this case / or \ at beginning of folder path is definitely not correct. The backslash at beginning can be omitted or .\ is used to reference the directory folder in current directory on execution of the batch file. But the current directory on batch file execution can be also different to directory containing the executed batch file, for example on running the batch file as administrator, or on running the batch file as scheduled task, or on running the batch file from a network resource accessed using a UNC path. For that reason it is advisable to reference explicitly subdirectory folder in directory of the batch file.
Delayed environment variable expansion is not needed as long as the file name assigned currently to the loop variable does not need to be modified other than the modifiers of for support it. A command line like set name="%%~nf" does not work correct with enabled delayed expansion and file name contains one or more ! because of cmd.exe interprets the exclamation mark(s) in file name as beginning/end of a delayed expanded environment variable reference.
See also: How does the Windows Command Interpreter (CMD.EXE) parse scripts?
It looks like a recursive search for non-hidden files is not really needed as otherwise passing just file name without path and file extension would be not enough to get the right file processed by other batch file process.bat.
So the entire task can be done most likely also with:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
for %%I in ("%~dp0folder\*") do call "%~dp0process.bat" "%%~nI"
endlocal
But if the other batch file process.bat expects that the passed file name without file extension and path is in current directory on execution of process.bat, it is necessary to make the subdirectory folder in directory of this batch file first the current directory.
#echo off
setlocal EnableExtensions DisableDelayedExpansion
pushd "%~dp0folder"
for %%I in (*) do call "%~dp0process.bat" "%%~nI"
popd
endlocal
Note: The batch file folder path referenced with %~dp0 always ends with a backslash. Therefore no additional backslash should be used on concatenating this path string with a file/folder name to avoid having finally on execution of the batch file \\ in full qualified file/folder name, although Windows kernel corrects such paths also automatically by removing second backslash in this case.
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 /?
echo /?
endlocal /?
popd /?
pushd /?
set /?
setlocal /?

How to maintain a file association when calling a program from a batch file?

Is there a way to maintain the original file association when running a program from a batch file?
I created a batch file that calls a Windows program and performs some file maintenance. I changed the file association to the batch file. When I click on a file that's associated with that program, the batch file executes and opens the program but the file I click on isn't loaded. The original file association is lost.
This sorta makes sense because the CALL command within the batch file is once removed from the initial mouse-click that initiated the batch file.
Is there a syntax I can add that would pass the target file name to the batch file as a variable and append it to the CALL command line?
BTW, this is for an XP machine. Any assistance would be appreciated!
EDIT: here's the code I'm trying to write:
call "C:\Program Files\CorelDRAW X4\Programs\CorelDRW.exe"
:loop
if exist "C:\Documents and Settings\<user>\My Documents\corel user files\*.cdr" copy "C:\Documents and Settings\<user>\My Documents\corel user files\*.cdr" "C:\Documents and Settings\<user>\My Documents\corel user files\*.sav"
ping localhost -n 300 > nul
goto loop
I'm trying to protect CorelDraw's auto-save file. There's a bug whereby CorelDraw sometimes deletes the auto-save file during abnormal shut-down. I changed the .cdr file association so that clicking on a cdr file calls the batch file, which in turn calls Coreldraw and copies the auto-save file to a different filename. That part works, but I have to manually open the file I clicked on.
Ideally, I'd like to figure out a way to terminate the loop when I close CorelDraw, but I'll cross that bridge once I solve the file association problem.
EDIT2: Here is the result of echo %CMDCMDLINE%:
C:\WINDOWS\system32\cmd.exe /c ""C:\Documents and Settings\<user>\My Documents\corel user files\protect_autosave.bat" "C:\Documents and Settings\<user>\My Documents\filename.cdr""
As far as I have understood the requirements for the task the code to use in batch file %ProgramFiles%\CorelDRAW X4\Programs\CorelFile.bat is:
#echo off
if "%~1" == "" goto :EOF
"%ProgramFiles%\CorelDRAW X4\Programs\CorelDRW.exe" %*
for %%I in (%*) do if exist %%I copy /Y "%%~I" "%%~dpnI.sav" >nul
This batch file must be associated with file extension .cdr for example by importing following registry file on Windows XP and later Windows versions with administrator privileges:
REGEDIT4
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\.cdr]
#="CorelDrawFile"
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CorelDrawFile]
#="Corel Draw Image"
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CorelDrawFile\DefaultIcon]
#=hex(2):22,25,50,72,6f,67,72,61,6d,46,69,6c,65,73,25,5c,43,6f,72,65,6c,44,52,\
41,57,20,58,34,5c,50,72,6f,67,72,61,6d,73,5c,43,6f,72,65,6c,44,52,57,2e,65,\
78,65,22,2c,30,00
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CorelDrawFile\shell\open\command]
#=hex(2):22,25,50,72,6f,67,72,61,6d,46,69,6c,65,73,25,5c,43,6f,72,65,6c,44,52,\
41,57,20,58,34,5c,50,72,6f,67,72,61,6d,73,5c,43,6f,72,65,6c,46,69,6c,65,2e,\
62,61,74,22,20,22,25,31,22,00
It is also possible to register file extension .cdr with absolute paths with REG_SZ instead of using REG_EXPAND_SZ and %ProgramFiles% in paths.
REGEDIT4
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\.cdr]
#="CorelDrawFile"
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CorelDrawFile]
#="Corel Draw Image"
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CorelDrawFile\DefaultIcon]
#="\"C:\\Program Files\\CorelDRAW X4\\Programs\\CorelDRW.exe\",0"
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CorelDrawFile\shell\open\command]
#="\"C:\\Program Files\\CorelDRAW X4\\Programs\\CorelFile.bat\" \"%1\""
Windows Explorer calls for each selected *.cdr file the batch file on using context menu Open respectively on double clicking a single *.cdr file.
The batch file starts Corel Draw with all the arguments passed to the batch file passing to Corel Draw. This is usually just the file name of the *.cdr file with full path and file extension enclosed in double quotes.
After Corel Draw terminated, the batch file checks for existence of each file specified as command line argument and copies the file with same name in same directory with different file extension .sav.
The batch file is designed for being started with multiple *.cdr file names specified as arguments on command line. I don't know if Corel Draw supports multiple *.cdr files being specified on command line.
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 %* (batch file) and %1 (Windows registry).
copy /?
echo /?
for /?
if /?

Force batch file to load to RAM before running

I have a batch file in an administrative partition of my portable drive, with a shortcut symlinked to it on the root of the drive. The purpose of the file is to unmount the drive and remount it as the specified letter (mostly for convenience).
When the file is opened, it is opened relative to the current letter rather than to the volume ID, so naturally, when the unmount happens, the command processor has no idea what to do next as it reads the file as needed rather than caching it.
There are two foreseeable solutions that I can think of but can't figure out:
Make the file get cached into RAM before executing
Make the file run relative to the volume ID instead of the mountpoint (tried using {VOLID}\file where {VOLID} is the volume ID, but it couldn't find the file although it was there (navigating to {VOLID}\ correctly opened the directory, but trying to open the file didn't correctly open the file.
Despite of the other answers, it's trivial to cache a whole batch script to RAM.
You only need to build a single block, as blocks are parsed and cached before they can be executed.
But blocks have some drawbacks, percent expansion doesn't work, therefore you need to use delayed expansion.
call and goto can't be used, as they would try to read from the file again.
(goto) 2>nul & (
echo The script is started
REM Need to change the directory, else the unmount doesn't work
c:
mountvol e: /p
mountvol g: \\?\Volume{VOLID}\
dir G:\
echo The script will end now
REM Here you need the goto 2>nul hack to avoid an error message
)
The (goto) 2>nul & seems strange here, but it's explained at SO:How to make a batch file delete itself?.
It works also without the goto, but then the scripts ends with an error message
Have the batch file determine where it is running from see this. If it's running from the portable drive have it make a copy of itself to a permanent drive location (c:\temp for instance) then run that copy of the batch file.
When running a bath file there is no concept of running it from RAM. Windows command processor will always go back to the .bat file for the 'next' command to run. If you edit a batch file while it's running the command processor will pick up your changes.
JJF wrote already the correct answer. It is not possible to copy a batch file to RAM and inform Windows command interpreter to interpret the command lines in memory. It would be possible to create a RAM disk, copy the batch file to the RAM disk and run it from there. But this just makes the task more complicated than necessary.
This commented batch code demonstrates how to copy a batch file to directory for temporary files and start it there for complete processing in a separate Windows command process.
#echo off
rem Is the batch file path not the path of directory for temporary files?
if /I not "%~dp0" == "%TEMP%\" (
rem Copy the batch file to directory for temporary files.
copy "%~f0" "%TEMP%" >nul
rem Run the copy in a separate command process with name of the batch
rem file with extension as window title and exit this batch process.
start "%~nx0" "%TEMP%\%~nx0"
goto :EOF
)
echo The batch file is now running from directory for temporary files.
echo.
pause
rem Delete the batch file in directory for temporary files
rem and exit the command process started for this batch file.
del "%TEMP%\%~nx0" & exit
Replace the two echo commands and the pause command by your batch code.
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 (drive and path of argument 0 which is the batch file itself) and %~nx0 (name and extension of batch file)
copy /?
del /?
echo /?
exit /?
goto /?
if /?
pause /?
rem /?
start /?
See also answer on Single line with multiple commands using Windows batch file for an explanation of operator & used here two run the two commands del and exit read from one line to avoid an opened console window with an error message as batch file deleted unexpected for the Windows command interpreter while processing it.

Trouble with renaming folders and sub folders using Batch

So I'm trying to set up a template file structure for projects that can be modified in name to suit each project. I have created the example directory containing example folders i.e. "Template project" contains "template hardware" , "template software" etc. , and have a simple batch program that copies the "template project" folder and all contained subfolders, however I would like to change the word 'template' with what ever I choose to call the project. I was wondering if this is possible to do? Ideally I could just edit the batch file with the name of the project and then run it to copy the template and rename it.
Any help is greatly appreciated!
To start learning type help at the command prompt. Then anything on that list add /? for more help.
Set /p NewName=Enter project name
md "c:\somewhere\%newname%project\%newname% software
md "c:\somewhere\%newname%project\%newname% hardware
or use xcopy (and use/l to have it do a test without copying)
xcopy "c:\tempate" "d:\%newname%" /e /h /q /i /c
See set /?, md /?, and xcopy /?. Type just set to see a list of variables.
& seperates commands on a line.
&& executes this command only if previous command's errorlevel is 0.
|| (not used above) executes this command only if previous command's errorlevel is NOT 0
> output to a file
>> append output to a file
< input from a file
| output of one command into the input of another command
^ escapes any of the above, including itself, if needed to be passed to a program
" parameters with spaces must be enclosed in quotes
+ used with copy to concatinate files. E.G. copy file1+file2 newfile
, used with copy to indicate missing parameters. This updates the files modified date. E.G. copy /b file1,,
%variablename% a inbuilt or user set environmental variable
!variablename! a user set environmental variable expanded at execution time, turned with SelLocal EnableDelayedExpansion command
%<number> (%1) the nth command line parameter passed to a batch file. %0 is the batchfile's name.
%* (%*) the entire command line.
%<a letter> or %%<a letter> (%A or %%A) the variable in a for loop. Single % sign at command prompt and double % sign in a batch file.
\\ (\\servername\sharename\folder\file.ext) access files and folders via UNC naming.
: (win.ini:streamname) accesses an alternative steam. Also separates drive from rest of path.
. (win.ini) the LAST dot in a file path seperates the name from extension
. (dir .\*.txt) the current directory
.. (cd ..) the parent directory
\\?\ (\\?\c:\windows\win.ini) When a file path is prefixed with \\?\ filename checks are turned off.
< > : " / \ | Reserved characters. May not be used in filenames.
Reserved names. These refer to devices eg,
copy filename con
which copies a file to the console window.
CON, PRN, AUX, NUL, COM1, COM2, COM3, COM4,
COM5, COM6, COM7, COM8, COM9, LPT1, LPT2,
LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, and LPT9
CONIN$, CONOUT$, CONERR$
Maximum path length 260 characters
Maximum path length (\\?\) 32,767 characters (approx - some rare characters use 2 characters of storage)
Maximum filename length 255 characters
Starting a Program
===============
See start /? and call /? for help on all three ways.
Specify a program name
--------------------------------
c:\windows\notepad.exe
In a batch file the batch will wait for the program to exit. When
typed the command prompt does not wait for graphical
programs to exit.
If the program is a batch file control is transferred and the rest of the calling batch file is not executed.
Use Start command
--------------------------
start "" c:\windows\notepad.exe
Start starts a program and does not wait. Console programs start in a new window. Using the /b switch forces console programs into the same window, which negates the main purpose of Start.
Start uses the Windows graphical shell - same as typing in WinKey + R (Run dialog). Try
start shell:cache
Use Call command
-------------------------
Call is used to start batch files and wait for them to exit and continue the current batch file.
.
--

Using a Windows Batch file to back up files in user-specified location and user-specified file extension

I'm creating a Windows Batch file which will allow me to backup files in a specific location with a specific file extension by creating a copy of the file with a .bak extension. For example, if I were to give the working Batch file the parameters "C:\Test & Folder" (which, in this example, only contains a file called MyWork.laz) and ".laz", it would switch to the correct drive, look through the specified folder, create a copy of MyWork.laz in the same folder called MyWork.laz.bak, then switch back to the drive where the batch was started from.
Currently the code looks like this:
set EXTEN = *%~2%
%~d1
cd "%~f1"
FOR %%I IN %%EXTEN DO COPY %%I %%I.bak
%~d0
However, when the batch file gets to Line 4, the following error is outputted:
%EXTEN was unexpected at this time.
How Line 4 is interpreted by Windows is also shown (I was using ".bak" as my second argument):
FOR %I IN %EXTEN DO COPY %I %I.bak
As I'm new to Windows Batch programming, and my research into this hasn't yielded anything, I'd appreciate any advice or assistance.
The simple batch solution:
#ECHO OFF
FOR /F "usebackq delims=" %%I IN ( `DIR /B "%~1*.%~2"` ) DO COPY "%~1%%I" "%~1%%I.bak" >nul
This simple solution runs command DIR searching for files with the extension passed as second parameter in directory specified as first parameter.
Output format of command DIR is set with option /B to simple format which means only name of found files without path are output by DIR.
This output is read next line by line in the FOR loop which executes the copy command on each file to create the backup file in same directory.
But this simple solution has some disadvantages for usage:
There is no check if the batch file was called with the 2 parameters required.
There is no check if the directory path passed as first parameter really ends with a backslash as required.
There is no check if the extension passed as second parameter does not contain a dot as expected.
Therefore the better solution is following batch file:
#ECHO ON
SET "Folder=%~1"
SET "Extension=%~2"
IF "%Folder%"=="" GOTO Usage
IF "%Extension%"=="" GOTO Usage
IF "%Folder:~-1%"=="\" SET "Folder=%Folder:~0,-1%"
IF "%Extension:~0,1%"=="." SET "Extension=%Extension:~1%"
FOR /F "usebackq delims=" %%I IN ( `dir /b "%Folder%\*.%Extension%"` ) DO COPY "%Folder%\%%I" "%Folder%\%%I.bak" >NUL
GOTO EndBatch
:Usage
CLS
ECHO Usage: %~n0 ["][Drive:]Path["] Extension
ECHO.
ECHO Examples:
ECHO.
ECHO %~n0 "C:\My Files\" txt
ECHO.
ECHO %~n0 C:\Temp\ doc
ECHO.
PAUSE
:EndBatch
SET Folder=
SET Extension=
The second line assigns first parameter to an environment variable Folder with removing surrounding double quotes if present at all. The entire parameter for command SET must be in double quotes in case of directory path contains a special character like & or %.
The third line assigns second parameter to an environment variable Extension with removing surrounding double quotes if present at all (unlikely but not impossible).
The fourth and fifth line check if batch file was called with at least 2 parameters.
The check for first parameter missing can be done safely only after removing the double quotes as otherwise the execution of the batch file is breaked with a syntax error message if the directory path contains a special character like &.
IF ""C:\Test & Folder""==""
results in a syntax eror while
IF "C:\Test & Folder"==""
is correct parsed by the command line interpreter.
The sixth line checks if last character of directory path is a backslash. The backslash at end is removed if this is the case. The opposite is also possible by appending a backslash if missing at end. But using 3 times a backslash in the FOR loop below makes this line easier to read.
The seventh line removes a dot from beginning of file extension if the file extension was specified on calling the batch file with a dot.
The other lines should be self-explaining.
Addition to answer the questions by Expack3 in first comment:
Whenever a new process is started, Windows allocates memory for the environment variables and their values, and copies the environment data from the parent process to the environment memory of the called process. Therefore each process has its own environment buffer and can modify, add or delete environment variables with no impact on other running processes including the parent process.
The process cmd.exe is called on running a batch file which interprets and executes the commands in the batch file. By default cmd.exe terminates itself on end of a batch file reached. With termination of cmd.exe the environment variables buffer is also deallocated and therefore it does not really matter which variables have been added, modified or deleted by the batch file. So in general it is not necessary to delete environment variables used temporarily in a batch file.
But instead of double clicking on a batch file, or running a batch file via a shortcut (*.lnk file), or by Windows task scheduler, it is also possible to run a batch file directly from within a command prompt window which means from an already running cmd.exe process.
In this case the environment variables added by the executed batch file remain in environment buffer after processing the batch file finished. This can lead to problems if next from within same command prompt window one more batch file is executed which by chance use also one of the environment variables of first batch file, but has not initialized the environment variable before first usage. The mistake of a missing variable initialization in second batch file in combination of not removing variables in first batch file could result now in a different execution of second batch file in comparison to running only second batch file respectively running the second batch file first in command prompt window.
Another reason for deleting temporarily used environment variables is the limited memory for environment variables. The memory allocated by Windows for the environment variables before starting the process does not grow during process execution. So if one batch file is called from other batch files and none of the batch files deletes the temporarily used environment variables, it could happen that there is suddenly no more free memory for a new variable or a larger string for an existing variable during the execution of the batch hierarchy. The logon batch file in large companies is often a collection of batch files which needs more and more memory from environment buffer if each batch file itself called directly or indirectly via other batch file(s) does not remove the temporarily used environment variables.
So it is simply more safe to delete the environment variables used temporary before exiting a batch file although for most batch files it is not necessary and just increases the total batch processing time by a few microseconds.
Using a line like:
set "Folder=%~f1"
is not enough for this batch file. It removes the double quotes from passed directory path and additionally changes a relative directory path to an absolute directory path if the directory can be found.
But it does not remove the backslash from end of a directory path if this path is already an absolute path.
For this batch file it is not really necessary that the directory path is an absolute path as the commands DIR and COPY work both also with relative paths.
The expansion of a relative directory path to an absolute directory path would just require a few microseconds more on batch execution without any benefit, except the batch files is extended by inserting a line with ECHO printing name of copied file with complete path within the FOR loop for visual inspection.

Resources