Batch Programming Snippets

Breakpoints and Debugging

If you write huge scripts and testing them for the first time, sometimes it would be nice to be able to debug them. There are some 3rd party applications arround, that can enable debugging of batch files but we want to use the “power of cmd.exe” to do that. When I write scripts, I define a custom command as a variable and place the variable all over my script. So changing that variable will enable/disable debugging.

Here is an example:

@ECHO OFF
CLS
SET MYPAUSE=@ECHO.^&@ECHO °°°°°°°°°°°BREAKPOINT°°°°°°°°°°° Press a key^&PAUSE^>NUL
::SET MYPAUSE=ECHO.
ECHO.
ECHO The script should stop between
ECHO Here
%MYPAUSE%
ECHO and here.

With the above example the script will execute as follows

The script should stop between
Here

░░░░░░░░░░░BREAKPOINT░░░░░░░░░░░ Press a key
and here.

If you change to the following

::SET MYPAUSE=@ECHO.^&@ECHO °°°°°°°°°°°BREAKPOINT°°°°°°°°°°° Press a key^&PAUSE^>NUL
SET MYPAUSE=ECHO.

the script will execute without a PAUSE

The script should stop between
Here

and here.

Voila - you can now debug your scripts a little bit better

Command extensions (check if enabled)

The cmd.exe supports the so called “Command Extensions”. They are enabled by default but can be enabled/disabled by setting a registry key or by command line. When cmd.exe starts it looks for the following registry keys to check if Command Extensions should be enabled or not.

HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor\EnableExtensions
HKEY_CURRENT_USER\Software\Microsoft\Command Processor\EnableExtensions

It checks if a REG_DWORD exists there. If set to “0x1” it means Extensions are enabled and “0x0” means extensions are disabled.

If you rely on some features of cmd.exe in your batch files that only work if “Command Extensions” are enabled, you should check if they are enabled at the beginning of your script. But how? The answer is very simple and easy. You have to do 3 Steps.

  1. Execute an invalid command to set the errorlevel to 1
  2. Use SETLOCAL ENABLEEXTENSIONS to reset back the errorlevel to 0
  3. Check if the errorlevel is 0 (not the same as if %ERRORLEVEL%=0). If it is still 1 “Command Extensions” are not enabled.

So here is a small script to do the above job.

@ECHO OFF
CLS
::Check if command extensions are enabled
::
:: 1. Execute an invalid command to set the errorlevel to 1
::    A command that I think works good is the VERIFY command.
::    It usually has only 1 Parameter so passing 2 it creates
::    errorlevel 1 but does not complain.
VERIFY FIRST SECOND>NUL
:: 2. The variable %ERRORLEVEL% is now 1 if Command
::    Extensions" are enabled. If we now try
::    SETLOCAL ENABLEEXTENSIONS and Command extensions are on
::    the variable %ERRORLEVEL% will be reset to 0
SETLOCAL ENABLEEXTENSIONS
:: 3. If Command Extensions are not enabled, the SETLOCAL
::    command will be executed and the ERRORLEVEL will be 1
::    (not the variable %ERRORLEVEL%). Keep in mind, that
::    %ERRORLEVEL% is not the same as the ERRORLEVEL.
IF NOT ERRORLEVEL 0 (
 ECHO Command Extensions are off
) ELSE (
 ECHO Command Extensions are on
)

MYSLEEP (sleeping for some seconds)

Sometimes you need the opportunity to let your script sleep for some seconds. Most batch professionals know, that you can achieve this with a ping command to localhost. Here is an impressive way to implement a custom sleep command (MYSLEEP) into your scripts

We just join 3 commands together:

@echo [Sleeping 5 seconds - with the magic MYSLEEP]...
ping -n 6 127.0.0.1 > NUL
@echo done

into one line using the “^” character which means “Do a carriage return”. The “> NUL” means “Print the result to nowhere.

@echo [Sleeping 5 seconds - with the magic MYSLEEP]...^&ping -n 6 127.0.0.1^>NUL^&@echo done

and store it into the variable MYSLEEP

SET MYSLEEP=@echo [Sleeping 5 seconds - with the magic MYSLEEP]...^&ping -n 6 127.0.0.1^>NUL^&@echo done

Now we can use “%MYSLEEP%” at anytime in our batch script to execute a sleep of ~5 seconds. Here is a sample script to demonstrate the usage:

@ECHO OFF
CLS
SET MYSLEEP=@echo [Sleeping 5 seconds - with the magic MYSLEEP]...^&ping -n 5 127.0.0.1^>NUL^&@echo done
ECHO Hello World
%MYSLEEP%
ECHO Now it is 5 seconds later

format your date

This script will bring the computer date read from %DATE% into the correct format an also makes sure that single numbers get a leading 0. The script takes care about that there are only 4 possibilites than can be returned by %DATE%

   xxx x/xx/xxxx delimiter on position 6 and 9  eg. Dec 1/12/2009  or Dez 12.1.2009
  xxx xx/xx/xxxx delimiter on position 7 and 10 eg. Dec 12/12/2009 or Dez 12.12.2009
   xxx xx/x/xxxx delimiter on position 7 and 9  eg. Dec 12/1/2009  or Dez 1.12.2009
    xxx x/x/xxxx delimiter on position 6 and 8  eg. Dec 1/1/2009   or Dez 1.1.2009

The script stores the number(s) left of the first delimiter in the variable %DBB% and the number(s) left of the second delimiter in the variable %DAA%. Try it out!

@ECHO OFF
CLS
SETLOCAL
rem set Delimiter eg. / or .
SET TR=/
rem SET DATUM=Thu 1/1/2009
SET DATUM=%DATE%

SET TRENNER=/
rem check format "xxx x/xx/xxxx" / on position 6 and 9
 IF "%DATUM:~5,1%%DATUM:~8,1%"=="%TR%%TR%" (^SET DBB=0%DATUM:~4,1%&^SET DAA=%DATUM:~6,2%&^SET YEAR=%DATUM:~-4%&^GOTO CHECKEND)
rem check format "xxx xx/xx/xxxx" / on position 7 and 10
 IF "%DATUM:~6,1%%DATUM:~9,1%"=="%TR%%TR%" (^SET DBB=%DATUM:~4,2%&^SET DAA=%DATUM:~7,2%&^SET YEAR=%DATUM:~-4%&^GOTO CHECKEND)
rem check format "xxx xx/x/xxxx" / on position 7 and 9
 IF "%DATUM:~6,1%%DATUM:~8,1%"=="%TR%%TR%" (^SET DBB=%DATUM:~4,2%&^SET DAA=0%DATUM:~7,1%&^SET YEAR=%DATUM:~-4%&^GOTO CHECKEND)
rem check format "xxx x/x/xxxx" / on position 6 and 8
 IF "%DATUM:~5,1%%DATUM:~7,1%"=="%TR%%TR%" (^SET DBB=0%DATUM:~4,1%&^SET DAA=0%DATUM:~6,1%&^SET YEAR=%DATUM:~-4%&^GOTO CHECKEND)
GOTO :CHECKEND

:CHECKEND

rem maybe you have to change the delimiter and the position of
rem DBB and DAA when using german or other format
echo %DBB%---%DAA%---YEAR%

format your date v2 (from internet)

See this page for more information. This version is much better than mine. It took me a while to understand but now I got it! :)

@echo off&SETLOCAL

   :: This will return date into environment vars
   :: Works on any NT/2K/XP machine independent of regional date settings
   :: 20 March 2002

   FOR /f "tokens=1-4 delims=/-. " %%G IN ('date /t') DO (call :s_fixdate %%G %%H %%I %%J)
   goto :s_print_the_date
   
   :s_fixdate
   if "%1:~0,1%" GTR "9" shift
   FOR /f "skip=1 tokens=2-4 delims=(-)" %%G IN ('echo.^|date') DO (
       set %%G=%1&set %%H=%2&set %%I=%3)
   goto :eof

   :s_print_the_date
   echo Month:[%mm%]  Day:[%dd%]  Year:[%yy%]
   SET FileDate=%yy%_%mm%_%dd%
   ENDLOCAL&SET mm=%mm%&SET dd=%dd%&SET yy=%yy%

SET FileDate=%yy%_%mm%_%dd%


The above works by taking advantage of a quirk in the date command first noticed by Michael Jerkovic - the DATE command will display something like:

  The current date is: Fri 14/04/2000
  Enter the new date: (**dd-mm-yy**)

The useful bit there is the (dd-mm-yy), on a machine with different regional settings it may appear as (mm-dd-yy)

The first FOR command returns the 3 numeric parts of the date e.g. 14 04 2000 The second FOR command returns the 3 text descriptions e.g. dd mm yy Then the line set G=%1&set H=%2&set %%I=%3 creates the 3 variables and sets them = numeric values

Effectively: set dd=14&set mm=04&set yy=2000 On a machine with different regional settings this might become: set mm=04&set dd=14&set yy=2000

Note the reason this works with any regional setting is that the DATE string (dd-mm-yy) always displays with `-` as it's date separator.

public/windows/batch/snippets.txt · Last modified: 2015/08/11 08:20 (external edit)
CC Attribution-Share Alike 3.0 Unported
Driven by DokuWiki Recent changes RSS feed Valid CSS Valid XHTML 1.0