Windows/Batch Programming

From Omnia
Jump to navigation Jump to search

Shell Scripts on the PC

This began as a project to write a set of essays for use by my co-workers as an aid to understanding the DOS batch programs I wrote for user account and machine management, and for numerous one-off programs to solve problems and provide unusual services. It got out of hand. Win95, with its brain-dead batch language, came along - then NT and its very different batch language - then DOS started going away and Linux appeared on the scene.

It appeared to me that the best way to continue the work was to make the original essays into one volume of a multi-volume work covering all of the environments I use in separate sets of essays. This is the master wrapper page and introduction for that grand scheme. I don't expect it ever to be complete - the operating environments come and go faster than I can master their shell script languages. If the links are not active, I haven't actually written anything on that topic yet.

echo

Turn off echo command:

@echo off

print blank line:

echo.

print text and variables:

echo Hello %name%, how are you?

sleep

Implementing the WAIT Command in a Batch File - DOS and Batch Files:

wait.bat:

@ping 127.0.0.1 -n 2 -w 1000 > nul
@ping 127.0.0.1 -n %1% -w 1000> nul

beep

@echo off

:repeat

rem - character created with [ctrl]+[g]
echo �

ping 127.0.0.1 -n 1 -w 1000 > nul

goto repeat

Current Folder

%~dp0

showfolder.bat:

%systemroot%/explorer.exe %~dp0

error levels

WARNING: Error levels match equal OR HIGHER

some_program.exe
IF ERRORLEVEL 1 GOTO ERROR
GOTO DONE

:ERROR
echo "There was an error"
exit 1

:DONE
echo "done"


print exit code from last run command: (case insensitive)

echo %errorlevel%
echo %ERRORLEVEL%

using errorlevel within batch:

if errorlevel 1 (
  rem this includes all 1 and above
  ...
)

To determine the exact return code the previous command returned, we could use a construction like this:

@ECHO OFF
IF ERRORLEVEL 1 SET ERRORLEV=1
IF ERRORLEVEL 2 SET ERRORLEV=2
IF ERRORLEVEL 3 SET ERRORLEV=3
IF ERRORLEVEL 4 SET ERRORLEV=4
   •
   •
   •
IF ERRORLEVEL 254 SET ERRORLEV=254
IF ERRORLEVEL 255 SET ERRORLEV=255
ECHO ERRORLEVEL = %ERRORLEV%


Negative Error Levels:

In Windows NT 4/2000/XP this may sometimes fail, since some executables return negative numbers for errorlevels!
However, this can be fixed by using the following code to check for non-zero return codes:
IF %ERRORLEVEL% NEQ 0 ...
Use the code above wherever you would have used IF ERRORLEVEL 1 ... in the "past".

Source: Batch files - Errorlevels

exit

Quits the CMD.EXE program (command interpreter) or the current batch
script.

EXIT [/B] [exitCode]

  /B          specifies to exit the current batch script instead of
              CMD.EXE.  If executed from outside a batch script, it
              will quit CMD.EXE

  exitCode    specifies a numeric number.  if /B is specified, sets
              ERRORLEVEL that number.  If quitting CMD.EXE, sets the proces
              exit code with that number.

To exit with return code of 1:

exit 1

To exit from one batch file to another with return code of 1:

exit /b 1

if

Performs conditional processing in batch programs.

IF [NOT] ERRORLEVEL number command
IF [NOT] string1==string2 command
IF [NOT] EXIST filename command
NOT Specifies that Windows 2000 / XP should carry out the command only if the condition is false.
ERRORLEVEL number Specifies a true condition if the last program run returned an exit code equal to or greater than the number specified.
string1==string2 Specifies a true condition if the specified text strings match.
EXIST filename Specifies a true condition if the specified filename exists.
command Specifies the command to carry out if the condition is met. Command can be followed by ELSE command that will execute the command after the ELSE keyword if the specified condition is FALSE

The ELSE clause must occur on the same line as the command after the IF. For example:

IF EXIST filename. (
del filename.
) ELSE (
echo filename. missing.
)
if %1==yes echo yes
if "%1"=="" echo empty
if not %1==no echo no

if %1=="doit" ( echo doing it )
if %1=="domore" (
echo doing more
echo doing more
)

if "%1"=="" (
echo Error: missing parameter
exit 1
)

Note: Careful, spaces in variables will break if statements

Resources:

comments

rem this is a comment
rem and so is this

variables

rem  notice no space between equal sign
set variablename=johnson
set variablename=mike johnson
echo My name is %variablename%
set rc=%errorlevel%

Command line parameters (notice no second %)

%1 %2 %3 %4 %5 %6 %7 %8 %9
shift

for loop

for %%a in (1 2 3 4 5 6 7 8 9 10 11 12 13 14 15) do echo CHEESE && echo IS GOOD
# same affect if you don't care about value
for %%a in (1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1) do  echo CHEESE && echo IS GOOD
for /f %%x in ('dir %BACKUPDIR% /b ^| find /v /c "::"') do set countfiles=%%x
for %%a in (1 2 3 4 5 6 7 8 9 10 11 12 13 14 15) do (
...
echo "loop: %%a"
)

References:

goto loop

set a=1

set limit=1111111111111111111111111
:loop
...
set a=%a%1
if not %a%==%limit% goto loop

References:

function

set ARG1=test1
call:FUNC1

set ARG1=test2
call:FUNC1

:FUNC1
echo.
echo "ARG1 = %ARG1%"
echo.
goto:eof

Resources:

pause

pause
pause > nul

wait or sleep

Window XP does not have a wait command. Here is a work around:

wait.bat:

@ping 127.0.0.1 -n 2 -w 1000 > nul
@ping 127.0.0.1 -n %1% -w 1000> nul

to use:

wait.bat 10  # 10 seconds

To make the "ping" timing more accurate, just be shure to ping something that does not exist.

@ping 1.1.1.1 -n 1 -w 10000

Source: http://malektips.com/dos0017.html

Since Windows XP and 2003 users do not have the CHOICE command, if you find the PING alternative not to your liking, the Windows 2003 Resource Kit has a batch file SLEEP command.

Multiple commands in one

The double ampersand (&&) command separator may not run the commands to the right of && command.

For example, when you run the following command, the pause command does not run when a floppy disk is not in drive A, and you receive a "The device is not ready" message:

dir a: && pause

Source: http://support.microsoft.com/kb/279253


exec copy *.* c:\Dir + cls + del a:\*.txt

Source: http://www.computing.net/answers/dos/cascading-multiple-dos-commands/15543.html


http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/ntcmds_shelloverview.mspx?mfr=true

Call Batch

C:\>call /?
Calls one batch program from another.

CALL [drive:][path]filename [batch-parameters]

  batch-parameters   Specifies any command-line information required by the
                     batch program.

If Command Extensions are enabled CALL changes as follows:

CALL command now accepts labels as the target of the CALL.  The syntax
is:

    CALL :label arguments

A new batch file context is created with the specified arguments and
control is passed to the statement after the label specified.  You must
"exit" twice by reaching the end of the batch script file twice.  The
first time you read the end, control will return to just after the CALL
statement.  The second time will exit the batch script.  Type GOTO /?
for a description of the GOTO :EOF extension that will allow you to
"return" from a batch script.

In addition, expansion of batch script argument references (%0, %1,
etc.) have been changed as follows:


    %* in a batch script refers to all the arguments (e.g. %1 %2 %3
        %4 %5 ...)

    Substitution of batch parameters (%n) has been enhanced.  You can
    now use the following optional syntax:

        %~1         - expands %1 removing any surrounding quotes (")
        %~f1        - expands %1 to a fully qualified path name
        %~d1        - expands %1 to a drive letter only
        %~p1        - expands %1 to a path only
        %~n1        - expands %1 to a file name only
        %~x1        - expands %1 to a file extension only
        %~s1        - expanded path contains short names only
        %~a1        - expands %1 to file attributes
        %~t1        - expands %1 to date/time of file
        %~z1        - expands %1 to size of file
        %~$PATH:1   - searches the directories listed in the PATH
                       environment variable and expands %1 to the fully
                       qualified name of the first one found.  If the
                       environment variable name is not defined or the
                       file is not found by the search, then this
                       modifier expands to the empty string

    The modifiers can be combined to get compound results:

        %~dp1       - expands %1 to a drive letter and path only
        %~nx1       - expands %1 to a file name and extension only
        %~dp$PATH:1 - searches the directories listed in the PATH
                       environment variable for %1 and expands to the
                       drive letter and path of the first one found.
        %~ftza1     - expands %1 to a DIR like output line

    In the above examples %1 and PATH can be replaced by other
    valid values.  The %~ syntax is terminated by a valid argument
    number.  The %~ modifiers may not be used with %*

Check if Programming Running

tasklist /FI "IMAGENAME eq myapp.exe" 2>NUL | find /I /N "myapp.exe">NUL
if "%ERRORLEVEL%"=="0" echo Programm is running

Ref: http://stackoverflow.com/questions/162291/how-to-check-if-a-process-is-running-via-a-batch-script

Kill Program

taskkill /IM cmd.exe
# force
taskkill /F /IM process.exe

Ref: http://superuser.com/questions/57941/exit-program-in-windows-command-prompt

Start Window

C:\>start /?
Starts a separate window to run a specified program or command.

START ["title"] [/Dpath] [/I] [/MIN] [/MAX] [/SEPARATE | /SHARED]
      [/LOW | /NORMAL | /HIGH | /REALTIME | /ABOVENORMAL | /BELOWNORMAL]
      [/WAIT] [/B] [command/program]
      [parameters]

    "title"     Title to display in  window title bar.
    path        Starting directory
    B           Start application without creating a new window. The
                application has ^C handling ignored. Unless the application
                enables ^C processing, ^Break is the only way to interrupt
                the application
    I           The new environment will be the original environment passed
                to the cmd.exe and not the current environment.
    MIN         Start window minimized
    MAX         Start window maximized
    SEPARATE    Start 16-bit Windows program in separate memory space
    SHARED      Start 16-bit Windows program in shared memory space
    LOW         Start application in the IDLE priority class
    NORMAL      Start application in the NORMAL priority class
    HIGH        Start application in the HIGH priority class
    REALTIME    Start application in the REALTIME priority class
    ABOVENORMAL Start application in the ABOVENORMAL priority class
    BELOWNORMAL Start application in the BELOWNORMAL priority class
    WAIT        Start application and wait for it to terminate
    command/program
                If it is an internal cmd command or a batch file then
                the command processor is run with the /K switch to cmd.exe.
                This means that the window will remain after the command
                has been run.

                If it is not an internal cmd command or batch file then
                it is a program and will run as either a windowed application
                or a console application.

    parameters  These are the parameters passed to the command/program


If Command Extensions are enabled, external command invocation
through the command line or the START command changes as follows:

non-executable files may be invoked through their file association just
    by typing the name of the file as a command.  (e.g.  WORD.DOC would
    launch the application associated with the .DOC file extension).
    See the ASSOC and FTYPE commands for how to create these
    associations from within a command script.

When executing an application that is a 32-bit GUI application, CMD.EXE
    does not wait for the application to terminate before returning to
    the command prompt.  This new behavior does NOT occur if executing
    within a command script.

When executing a command line whose first token is the string "CMD "
    without an extension or path qualifier, then "CMD" is replaced with
    the value of the COMSPEC variable.  This prevents picking up CMD.EXE
    from the current directory.

When executing a command line whose first token does NOT contain an
    extension, then CMD.EXE uses the value of the PATHEXT
    environment variable to determine which extensions to look for
    and in what order.  The default value for the PATHEXT variable
    is:

        .COM;.EXE;.BAT;.CMD

    Notice the syntax is the same as the PATH variable, with
    semicolons separating the different elements.

When searching for an executable, if there is no match on any extension,
then looks to see if the name matches a directory name.  If it does, the
START command launches the Explorer on that path.  If done from the
command line, it is the equivalent to doing a CD /D to that path.

Wait for window program to complete

A windows program normally returns immediately upon startup. To wait until the process completes.

start /wait [program]

Advanced Windows Commands

wmic

windows management 

List Disk and Network Drives

Loop volume verify: [1]

@echo off
rem listdrives.bat by Kenneth Burgener <kenneth@oeey.com> © Nov 2012

echo Available Drives:
for %%a in (A B C D E F G H I J K L M N O P Q R S T U V W X Y Z) do (
  rem echo %%a::
  vol %%a: 1>NUL 2>NUL && echo %%a:
)

Windows Vista and Windows 7: [2]

wmic logicaldisk get name

List physical drives like \\.\PHYSICALDRIVE1 [3]

wmic diskdrive list
wmic diskdrive list brief

Examples

Perl PPM Module Installer

@echo off

set PPM_MODULE=Spreadsheet-BasicRead
call:PPM

set PPM_MODULE=Spreadsheet-WriteExcel
call:PPM

set PPM_MODULE=Frontier-RPC
call:PPM

set PPM_MODULE=File-Copy-Recursive
call:PPM

set PPM_MODULE=Error
call:PPM

set PPM_MODULE=Statistics-Basic
call:PPM


goto END



:PPM
echo.
echo Installing %PPM_MODULE%...
call c:\perl\bin\ppm.bat install %PPM_MODULE%
if errorlevel 1 (
  echo.
  echo !!!
  echo !!!  ERROR: Failure to install %PPM_MODULE%
  echo !!!
  goto END
)
echo.
goto:eof


:END

run10jobs.bat

REM c:\RSD_TEST_TOOLS\seqtp18_32.exe -B k:\test1 64K 1000M 0 k_log 

set window_title="E:\test1 64K 1000M:"
set command_line=C:\RSD\seqtp18_32.exe -S E:\test1 64K 1000M 0 E_log
start %window_title% %command_line%

%SystemRoot%\system32\taskkill /IM seqtp18_32.exe /F


keywords