Batch files are native to DOS and Windows. They are interpreted by the default shell programs COMMAND.COM (W98) or CMD.COM (NT). These shell programs are frustratingly limited, and inconsistent between versions. In many cases, you may want to abandon batch files and use a Unix type shell instead, but if you know a few tricks you can do most scripting chores with batch files.
You should also be aware of the win32 scripting languages available on typical PCs. These include Visual Basic Script, Java Script, WSH, Cscript, and in many cases Perl and Python. See the Microsoft Script Center
One key point is what happens when you drag and drop things in Windows. Once you have written your batch file utility, you will probably never use it by typing it's name. More likely, you will drag and drop files or directories onto the batch file icon. When you drop something onto an executable file icon, Windows executes the program as if you had typed
"program_name item1 item2 ..."
Within the batch file, the program name is %0, the first item is %1, the next %2 etc. However Win98 has limitations:
Under Win98, batch file console windows do not close when finished unless
you either:
1. right click on bat file icon=>properties=>Program=>Close
on exit
This creates a PIF file which is what you put on your desktop. Since
you don't want the bat file cluttering up your desktop, start with the
bat file in some other directory, create the PIF and move the PIF to the
desktop.
or
2. include "echo off" somewhere, probably
"@echo off" at first line, and "cls" at the last line.
or
2.a "cls" is the last line with no end of line, ie there is no
trailing blank line(s).
Also under Win98:
only THREE items
can be dragged to a batch file. Batch files under Win98 can not use %4 to %9
unless you call them from a DOS command line. Why? I'm not sure but it looks
like explorer calls "COMMAND.COM %1 %2 %3 %4" where %1 is your batch
file and %2 %3 %4 are the arguments it will accept.
DIR /S does not work below the root
directory of some CD volumes.
Win2K, ie NT-5.0 fixed these two problems. Many such problems are caused by the fact that under DOS/Windows, the arguments are processed by the called program only, so every program has to do it's own variable substitution. Alas, each DOS command does it a bit differently. The shell, ie command.com does nothing with them.
Waits for the user to choose one of a set of choices.
CHOICE [/C[:]choices] [/N] [/S] [/T[:]c,nn] [text]
/C[:]choices Specifies allowable keys. Default is YN
/N
Do not display choices and ? at end of prompt string.
/S
Treat choice keys as case sensitive.
/T[:]c,nn Default choice to c after nn seconds
text Prompt
string to display
ERRORLEVEL is set to offset of key user presses in choices.
Choice.com is handy for menu choices, but not useful for other input. Something that is much more useful is putenv.com (alternate). Besides setting environment variables to an input string, you can use it to set variable from the output of other commands, because this sets variables from standard input. Unfortunately, neither choice.com nor putenv work under NT4/5 (NT5=W2K,XP). So if you want a batch file that works on all versions of MSWindows, you will have to include separate code for 16 and 32 bit windows. The SET /P function is available for NT5 (W2K,XP), but not NT4.
You can use a helper file "set.txt" containing the text:
SET temp=
where there is no EOL after the equal sign; ie no trailing blank line. (Notepad
will do this.)
Then use
TYPE set.txt > set.bat
to a second batch file; add the output from another command; call the
second batch file; then
SET variable=%temp%
so you can use set.txt again.
A nasty option that does work on all systems is creating temporary batch files who's names are the choices. Then you prompt for the options and call %COMSPEC% to take the input and run the selection.bat file that matches the choice made, something like this:
@echo off
::
echo @echo off > y.bat
echo echo answer is Yes ^>CON >> y.bat
echo exit >> y.bat
copy y.bat yes.bat > nulecho @echo off > n.bat
echo echo answer is No ^>CON >> n.bat
echo exit >> n.bat
copy n.bat no.bat > nulecho enter yes or no (y/n)
call %COMSPEC% >nuldel n.bat no.bat y.bat yes.bat
echo donepause
goto:eof
In NT-4/W2K, bat files can use the argument manipulation used in
the "for" command for other purposes.
See "for /?"
For example:
if not "%~x1" == ".ROM" goto message
copy /B 7556.vid + %~nx1 %~n1.dat
PAUSE
exit
:message
echo drop .rom file on this bat file to create .dat file
pause
exit
You can only drag/drop two files to a bat file if they are in the same directory. But this NT5 bat script will wait for a second drag and drop argument if necessary. (set /p option is not available in NT4 or W9x) fc (file compare) is the WIN32 equivalent of the Unix diff command.
setlocal
::
set name2=%2
rem drag file here and click, enter
if ""%2=="" set /P name2=2nd file?
fc /a /n %1 %name2%
pause
If you do not have %path% set for the commands used in the bat file,
the bat file will have a problem finding the command, so place the bat
file in the directory with the (eg. diff.exe) command and add
cd %0\..to the beginning of the bat file. Then create a link to the bat file and put the link on your desktop, etc.
A win98 file compare batch file:
@echo offWhen one file is dropped at a time, a temporary batch file is created, where you drop the second file. You may want to change the options on the "fc" command for ASCII files.
if not "%2"=="" goto 2files
if not "%1"=="" goto 1file
echo drag and drop files for compare
pause
goto eof
:1file
cd %0\..
echo @echo off > "compare2.bat"
echo fc /b "%1" "%%1" >> "compare2.bat"
echo pause >> "compare2.bat"
echo cls >> "compare2.bat"
goto eof
:2files
fc /b "%1" "%2"
pause
:eof
cls
Notice the line 'echo fc /b "%1" "%%1" >> "compare2.bat"'. The result is a line in compare2.bat that reads "fc /b filename.ext %1". This uses an extra "%" for the same reason the keyword "for" needs double %'s on it's index variable. See "for /?". Leading %'s are lost in the first pass when interpreting the script, when %1, %2, etc are replaced by literals.
"Send to" is just a directory under Windows where you put things
like your batch files. One of the things available when you right click
something is to send it to one of the utilities in "Send to".
One handy utility is to open a command shell in a certain directory (Win98):
@echo off %1\ cd %1 command.com cls
I use this to ftp files to my ISP. I just "send to" the
directory containing my web pages to this batch file. Then I can ftp
files without having to (local) CD to that directory. I use it most any time I
need a DOS shell.
Save this as "command.bat" in your "Windows\SendTo"
directory (W98).
"%1\" is the drive that %1 is in. This is needed because cd path
does not change the current working disk volume.
"@echo off" can be omitted if there is no EOL after "cls",
ie no trailing blank line.
Other things you want to put
in "send to" are shortcuts to notepad and vim text
editors.
see http://www.vim.org/
The for command allows you to write scripts that process a group of files. The following line should combine a group of "page" files into a single file.
for %%i in (page*.htm) do copy allpages.htm + %%i allpages.htm
But it doesn't work. The problems are:
The sequence of files is random.
Copy will error if "allpages.htm" does not exist before the first
page.
Copy will add end off file bytes between pages.
The following W2K batch script works around these problems and uses the directory name to name the resulting file..
%~d1 cd %~p1 call :dirnam "%CD%.HTM" for /F "usebackq delims=" %%i in (`dir page*.htm /OD/B`) do call :addfile "%%i" pause goto eof :addfile if exist %dest% ( copy /B %dest% + %1 %dest% ) else ( copy %1 %dest% ) goto :EOF :dirnam set dest=All-%~nx1
Drop one of the page*.htm files in a common directory onto this batch file. Then:
Note the use of "delims=". This, and quotes around "%%i"
are required to handle file names that include spaces.
This more generic version concatenates any type of selected files. Drag and drop
only the files you want combined.
@echo off if ""%1 == "" goto message %~d1 cd "%~p1" call :dirnam "%CD%%~x1" set fcnt=0 if exist %dest% echo File %dest% already exists. Adding files. for /F "usebackq delims=" %%i in (`dir %* /OD/B`) do call :addfile "%%i" echo %fcnt% files concatinated to %dest% pause goto :EOF :addfile if exist %dest% ( copy /B %dest% + %1 %dest% > nul set /A fcnt=%fcnt%+1 ) else ( copy %1 %dest% > nul set fcnt=1 ) goto :EOF :message echo This batch files concatenates files dropped to it, into echo a file named after the directory and extension of the first file. echo ie "all-dir1.ext1" **Files are sorted by date/time.** pause :dirnam set dest="all-%~nx1"
Batfiles:
The DOS batch file programming handbook & tutorial
©
Rob VanDerWoude's
stuff
Printing Orphan
documents
A simple
playlist generator