DosTips.com ... for VISTA,XP,NT,Server 2000,Server 2003,Server 2008
Search:
Last update:
Dec 18, 2008

DOS - Function Collection

The functions listed in this section serve as copy source to enhance your batch program.  Simply copy paste the function into your batch program and start calling them.  The provided test codes serve as examples on how to call the functions.

 

1      Variable Persistency - :setPersist, :getPersistentVars, :savePersistentVars, :restorePersistentVars  1

2      String Trimming Left and Right - :trim, :trimLeft, :trimRight. 2

3      String Length - :strLen. 3

4      Time Of Day and runtime measurements - :getTod, :getHHMMSSDD, :Tod2Str, :TodDiffNow  4

5      Circulate thru a List - :getNextInList. 5

6      Choose from List of last entered Values - :choiceListInput. 6

7      Opening the Registry Editor at a defined Location - :regedit. 9

8      Float <-> Integer Conversion - :F2I, :I2F. 9

9      Extracting text blocks from a File - :extractFromFile. 11

10         Get THIS computers IP address - :getIP. 13

11         Wait, Sleep, Hold - :sleep. 13

12         Progress Indicator - :initProgress, :doProgress. 13

 

  

1        Variable Persistency - :setPersist, :getPersistentVars, :savePersistentVars, :restorePersistentVars

 

Variable persistency can be archived by storing the variable of interest into a file when the DOS batch terminates and read them back in when the DOS batch starts up.  The setPersist function marks a variable to be persistent.  The savePersistentVars function stores the persistent variables into a file.  The restorePersistentVars function reads the variables back in from a file.

What it’s good for

·        Remembering the state of the batch program for the next run

·        Allow user profiles

·        Store information to be used in the next run

·        Implement execution counters

 Code

:setPersist -- to be called to initialize persistent variables

::          -- %*: set command arguments

set %*

GOTO:EOF

 

 

:getPersistentVars -- returns a comma separated list of persistent variables

::                 -- %~1: reference to return variable

SETLOCAL

set retlist=

set parse=findstr /i /c:"call:setPersist" "%~f0%"^|find /v "ButNotThisLine"

for /f "tokens=2 delims== " %%a in ('"%parse%"') do (set retlist=!retlist!%%a,)

( ENDLOCAL & REM RETURN VALUES

    IF "%~1" NEQ "" SET %~1=%retlist%

)

GOTO:EOF

 

 

:savePersistentVars -- Save values of persistent variables into a file

::                  -- %~1: file name

SETLOCAL

echo.>"%~1"

call :getPersistentVars persvars

for %%a in (%persvars%) do (echo.SET %%a=!%%a!>>"%~1")

GOTO:EOF

 

 

:restorePersistentVars –- Restore the values of the persistent variables

::                     -- %~1: batch file name to restore from

if exist "%FilePersist%" call "%FilePersist%"

GOTO:EOF

 

 

Test Code

rem.--define the filename where persistent variables get stored

rem.  just add a + to the name of THIS file, i.e. "DosTips.bat" - "DosTips+.bat"

set FilePersist=%~dpn0+%~x0

 

rem.--initialize the persistent variables

call:setPersist var=Hello

 

rem.--read the persistent variables from the storage

call:restorePersistentVars "%FilePersist%"

 

rem.--modify the persistent variable

echo.var = '%var%'

echo.

echo.Enter new string for var then run the batch again.

set /p var=var =

 

rem.--save the persistent variables to the storage

call:savePersistentVars "%FilePersist%"

 

 

Test Code Output

var = 'Hello'

 

Enter new string for var then run the batch again.

var =

2        String Trimming Left and Right - :trim, :trimLeft, :trimRight

 

Three functions to trim spaces around a value, i.e. left, right, left and right.

 Code

:trimLeft -- trim leading spaces

:         -- %~1: variable reference, string to be trimmed

for /f "tokens=* delims= " %%a in ("!%~1!") do set %~1=%%a

GOTO:EOF

 

 

:trimRight -- trim trailing spaces

:          -- %~1: variable reference, string to be trimmed

SETLOCAL

:trimLeft_LOOP

set s=!%~1!

if "%s:~-1%"==" " set s=%s:~0,-1%&goto:trimLeft_LOOP

(ENDLOCAL & REM.-- RETURN VALUES

    IF "%~1" NEQ "" SET %~1=%s%

)

GOTO:EOF

 

 

:trim -- trim leading and trailing spaces

:     -- %~1: variable reference, string to be trimmed

call:trimLeft %~1

call:trimRight %~1

GOTO:EOF

 

 

Test Code

set s=left trim nothing&                  call:trimLeft s&echo."!s!"

set s= left trim one&                     call:trimLeft s&echo."!s!"

set s=                   left trim plenty&call:trimLeft s&echo."!s!"

set s=right trim nothing&                 call:trimRight s&echo."!s!"

set s=right trim one &                    call:trimRight s&echo."!s!"

set s=right trim plenty                  &call:trimRight s&echo."!s!"

set s=trim nothing&                       call:trim s&echo."!s!"

set s= trim one left and one right &      call:trim s&echo."!s!"

set s=    trim plenty left and right     &call:trim s&echo."!s!"

 

 

Test Code Output

"left trim nothing"

"left trim one"

"left trim plenty"

"right trim nothing"

"right trim one"

"right trim plenty"

"trim nothing"

"trim one left and one right"

"trim plenty left and right"

3        String Length - :strLen

 

The :strLen function uses a binary search approach to determine the length of a string.

 Code

:strLen -- returns the length of a string via binary search, maximum length 1023

::      -- %~1: in - varible name of a string variable

::      -- %~2: out- string length

SETLOCAL

set str=A!%~1!&  rem keep the A up front to ensures we get the length and not the upper bond

                 rem it also avoids trouble in case of empty string

set len=0

set /a n=1024

set /a n^>^>=1, len+=n

 if !str:~%len%!. == . set /a len-=n

set /a n^>^>=1, len+=n

 if !str:~%len%!. == . set /a len-=n

set /a n^>^>=1, len+=n

 if !str:~%len%!. == . set /a len-=n

set /a n^>^>=1, len+=n

 if !str:~%len%!. == . set /a len-=n

set /a n^>^>=1, len+=n

 if !str:~%len%!. == . set /a len-=n

set /a n^>^>=1, len+=n

 if !str:~%len%!. == . set /a len-=n

set /a n^>^>=1, len+=n

 if !str:~%len%!. == . set /a len-=n

set /a n^>^>=1, len+=n

 if !str:~%len%!. == . set /a len-=n

set /a n^>^>=1, len+=n

 if !str:~%len%!. == . set /a len-=n

set /a n^>^>=1, len+=n

 if !str:~%len%!. == . set /a len-=n

( ENDLOCAL & REM RETURN VALUES

    IF "%~2" NEQ "" SET %~2=%len%

)

GOTO:EOF

 

 

Test Code

for /l %%a in (0,1,10) do (

    set s=

    for /l %%b in (0,1,%%a) do if /i %%b NEQ 0 set s=!s!x

    call:strLen s len

    echo."!s!" - length !len!

)

 

 

Test Code Output

"" - length 0

"x" - length 1

"xx" - length 2

"xxx" - length 3

"xxxx" - length 4

"xxxxx" - length 5

"xxxxxx" - length 6

"xxxxxxx" - length 7

"xxxxxxxx" - length 8

"xxxxxxxxx" - length 9

"xxxxxxxxxx" - length 10

4        Time Of Day and runtime measurements - :getTod, :getHHMMSSDD, :Tod2Str, :TodDiffNow

 

The getTod function returns a Time Of Day (Tod) integer value with a precision of 1/100th of a second.  Together with the other functions this can be used for time capture calculations like runtime measurements.

The getHHMMSSDD function allows extracting the hours, minutes, seconds, and 1/100th of seconds from a Tod integer.

The Tod2Str function allows to freely format a Tod integer into a string, i.e. put the seconds, hours, minutes where you want them.

What it’s good for

·        Runtime measurement

Limits

·        No corrector for days where daylight saving time is being turned on or off

Code

:getTod -- get a Time of Day value in 1/100th seconds

::   -- %~1: out - timo of day

SETLOCAL

set /a t=0

for /f "tokens=1-4 delims=:." %%a in ("%time: =0%") do set /a t=(((1%%a*60)+1%%b)*60+1%%c)*100+1%%d-36610100

( ENDLOCAL & REM RETURN VALUES

    IF "%~1" NEQ "" SET %~1=%t%

)

GOTO:EOF

 

 

:getHHMMSSDD -- split a Time Of Day integer into hours, minutes, seconds, 1/100th

::           -- %~1: in  - time of day as integer

::           -- %~2: out - hours

::           -- %~3: out - minutes

::           -- %~4: out - seconds

::           -- %~5: out - 1/100th

SETLOCAL

set /a t=%~1

set /a hh=t/360000

set /a t-=hh*360000

set /a mm=t/6000

set /a t-=mm*6000

set /a ss=t/100

set /a t-=ss*100

( ENDLOCAL & REM RETURN VALUES

    IF "%~2" NEQ "" SET %~2=%hh%

    IF "%~3" NEQ "" SET %~3=%mm%

    IF "%~4" NEQ "" SET %~4=%ss%

    IF "%~5" NEQ "" SET %~5=%t%

)

GOTO:EOF

 

 

:Tod2Str -- format a Time Of Day integer into a time string

::             -- %~1: out - output string

::             -- %~2: in  - time of day

::             -- %~3: in  - formatter string, default is HH:MM:SS.DD

SETLOCAL

set tod=%~2

set f=%~3

if "%f%"=="" set f=[TTTT]&            rem --if no format given assume [TTTT] format

set f=%f:[TTTT]=[H]:[MM]:[SS].[DD]%&  rem --replace [TTTT] with the default format

call:getHHMMSSDD tod h m s d&         rem --extract the numbers from the Time Of Day value

rem -- ensure two digits, add leading 0 where necessarily

set HH=0!h!&set HH=!HH:~-2!

set MM=0!m!&set MM=!MM:~-2!

set SS=0!s!&set SS=!SS:~-2!

set DD=0!d!&set DD=!DD:~-2!

rem -- replace the format specifyiers with real values

set f=!f:[HH]=%HH%!

set f=!f:[MM]=%MM%!

set f=!f:[SS]=%SS%!

set f=!f:[DD]=%DD%!

set f=!f:[H]=%h%!

set f=!f:[M]=%m%!

set f=!f:[S]=%s%!

set f=!f:[D]=%d%!

( ENDLOCAL & REM RETURN VALUES

    IF "%~1" NEQ "" (SET %~1=%f%) ELSE (ECHO.%f%)

)

GOTO:EOF

 

 

:TodDiffNow -- echos the time of day difference of Now-Base

::          -- %~1: in - Base time as variable

::          -- %~2: in - formatter string, default is HH:MM:SS.DD

::          -- %~3: out- diff time or empty for screen output

SETLOCAL

set base=!%~1!

call:getTod curr&                    rem --get the current Time Of Day

set /a diff=curr-base&               rem --subtract the base to get the difference

if /i diff LSS 0 diff+=24*60*60*100& rem --when measuring over midnight add a full day

call:Tod2Str s %diff% "%~2"&         rem --format the difference as string

( ENDLOCAL & REM RETURN VALUES

    IF "%~3" NEQ "" (SET %~3=%s%) ELSE (ECHO.%s%)

)

GOTO:EOF

 

 

Test Code

set delay=5

call:getTod t

echo.Starting a %delay%s delay via ping...

FOR /l %%a in (%delay%,-1,1) do ping -n 2 -w 1 127.0.0.1>NUL

echo....finished.

call:TodDiffNow t "The %delay%s delay via ping really took [TTTT]"

 

 

Test Code Output

Starting a 5s delay via ping...

...finished.

The 5s delay via ping really took 0:00:06.39

 

 

5        Circulate thru a List - :getNextInList

 

The getNextInList function allows a variable to circulate thru a set of values.  Each time calling this function the next entry in the choice list will be returned.  After passing the last entry the function will start again with the first entry.

What it’s good for

·        Creating a state automat in DOS

·        Let the user circulate through option rather than force typing.

 Code

:getNextInList -- return next value in list

::             -- %~1 - in/out ref to current value, returns new value

::             -- %~2 - in     choice list, must start with delimiter which must not be '@'

SETLOCAL

set lst=%~2&             rem.-- get the choice list

if "%lst:~0,1%" NEQ "%lst:~-1%" echo.ERROR Choice list must start and end with the delimiter&GOTO:EOF

set dlm=%lst:~-1%&       rem.-- extract the delimiter used

set old=!%~1!&           rem.-- get the current value

set fst=&for /f "delims=%dlm%" %%a in ("%lst%") do set fst=%%a&rem.--get the first entry

                         rem.-- replace the current value with a @, append the first value

set lll=!lst:%dlm%%old%%dlm%=%dlm%@%dlm%!%fst%%dlm%

                         rem.-- get the string after the @

for /f "tokens=2 delims=@" %%a in ("%lll%") do set lll=%%a

                         rem.-- extract the next value

for /f "delims=%dlm%" %%a in ("%lll%") do set new=%%a

( ENDLOCAL & REM RETURN VALUES

    IF "%~1" NEQ "" (SET %~1=%new%) ELSE (echo.%new%)

)

GOTO:EOF

 

 

Test Code

rem.--modify the persistent variable

set choiceList=,MO,TU,WE,TH,FR,SA,SU,

echo.choice list = "%choiceList%"

set var=

echo.var = '%var%'&call:getNextInList var "%choiceList%"

echo.var = '%var%'&call:getNextInList var "%choiceList%"

echo.var = '%var%'&call:getNextInList var "%choiceList%"

echo.var = '%var%'&call:getNextInList var "%choiceList%"

echo.var = '%var%'&call:getNextInList var "%choiceList%"

echo.var = '%var%'&call:getNextInList var "%choiceList%"

echo.var = '%var%'&call:getNextInList var "%choiceList%"

echo.var = '%var%'&call:getNextInList var "%choiceList%"

echo.var = '%var%'&call:getNextInList var "%choiceList%"

echo.var = '%var%'&call:getNextInList var "%choiceList%"

 

 

Test Code Output

choice list = ",MO,TU,WE,TH,FR,SA,SU,"

var = ''

var = 'MO'

var = 'TU'

var = 'WE'

var = 'TH'

var = 'FR'

var = 'SA'

var = 'SU'

var = 'MO'

var = 'TU'

Note

If var starts out empty or with a bogus value then the getNextInChoiceList function will assign the first value in the choice list, which is nice default behavior.

6        Choose from List of last entered Values - :choiceListInput

 

The choiceListInput function lets the user enter a value.  The value entered is returned by the function and added to the end of a choice list.  The choice list is shown next time this function is being called, and thus allows the user to pick from the list of last entered value.  The last chosen or newly entered value is added to the end of the choice list and acts as default input next time this function is being called.

The choice list is being stored into a variable.  The name of this variable is to be passed into the function, which allows this function to be called using different choice lists. 

What it’s good for

·        Increases user efficiency

·        Allows picking number from list instead of having to enter a long strings

·        Only need to pick a value when different from last run, otherwise just hit enter

Tip

Make the choice list variable persistent in order to have it available over multiple batch file executions.

 Code

:choiceListInput – lets the user choose from list of last entered values

:                -- %~1 - out, returns input value

:                -- %~2 - in/out, ref to choice list, returns trimmed reordered choice list

:                -- %~3 - in, list title

:                -- %~4 - in, list entry count limit

SETLOCAL ENABLEDELAYEDEXPANSION

set l=,!%~2!,&          rem.-- get the choice list

set t=%~3&              rem.-- get the list title

set c=%~4&              rem.-- get the list entry count limit

set m=&                 rem.-- a message

set l2=,

set v=

:choiceListInput_LOOP1

echo.%t%

set i=0&for %%a in (%l%) do (

    set /a i+=1

    set l2=!l2!!i!;%%~a,

    set v=%%~a

    echo.  !i! - %%~a

)

if "%m%" NEQ "" echo.  ^>^> %m%

echo.  Make a choice or enter a new value [%v%]

set v1=%v%

set /p v1=  :

echo.

set v2=!v1!&set v2=!v2:,=!&set v2=!v2:@=!&set v2=!v2:;=!&set v2=!v2:"=!

rem.--reject entry with illegal character

if "!v1!" NEQ "!v2!" (

    set m=Note: ,;@" and empty string not allowed.  Try again.

    goto:choiceListInput_LOOP1

)

rem.--if first character is minus then remove the entry

set remove=&if "%v1:~0,1%"=="-" set remove=y&set v1=%v1:~1%

set v=%v1%

rem.--if number chosen then find corresponding value

set l3=!l2:,%v%;=,@!

if "%l3%" NEQ "%l2%" (

    for /f "delims=@ tokens=2" %%a in ("!l3!") do set l3=%%a

    for /f "delims=,"          %%a in ("!l3!") do set v=%%a

)

rem.--remove value from list if exist

set l3=%l%

set l=!l:,%v%,=,!

if "%remove%"=="y" (

    if "%l%"=="%l3%" (set m='%v%' cannot be removed from list

    ) ELSE (set m='%v%' has been removed from list)

    goto:choiceListInput_LOOP1

)

if "%l%"=="%l3%" echo.  ^>^>'%v%' has been added to the list

rem.--add to the value to the end

set l=!l:~1!%v%

rem.--enforce the list entry count limit if requested

if "%c%" NEQ "" (

    set i=0&for %%a in (%l%) do set /a i+=1

    if /i !i! GTR !c! (

        for /f "delims=, tokens=1,*" %%a in ("!l!") do (

            set l=%%b

            echo.  ^>^>'%%a' dropped out of the list

        )

    )

)

( ENDLOCAL & REM RETURN VALUES

    IF "%~1" NEQ "" (SET %~1=%v%) ELSE (echo.%v%)

    IF "%~2" NEQ "" (SET %~2=%l%) ELSE (echo.%l%)

)

goto :eof

 

 

Test Code

if "%~1"=="" (

    set z=%~dpn0.tmp

    if exist "!z!" del "!z!"

    echo.a>>"!z!"

    echo.b>>"!z!"

    echo.c>>"!z!"

    echo.d>>"!z!"

    echo.>>"!z!"

    echo.2>>"!z!"

    echo.-d>>"!z!"

    echo.-1>>"!z!"

    echo.-1>>"!z!"

    echo.z>>"!z!"

    "%~f0" auto<"!z!"

)

 

rem.--modify the persistent variable

 

set choiceList=

set var=

call:choiceListInput var choiceList "Selection List:" 3&echo.  --'!var!' has been selected

call:choiceListInput var choiceList "Selection List:" 3&echo.  --'!var!' has been selected

call:choiceListInput var choiceList "Selection List:" 3&echo.  --'!var!' has been selected

call:choiceListInput var choiceList "Selection List:" 3&echo.  --'!var!' has been selected

call:choiceListInput var choiceList "Selection List:" 3&echo.  --'!var!' has been selected

call:choiceListInput var choiceList "Selection List:" 3&echo.  --'!var!' has been selected

call:choiceListInput var choiceList "Selection List:" 3&echo.  --'!var!' has been selected

Test Code Output

Selection List:

  Make a choice or enter a new value []

  :

  >>'a' has been added to the list

  --'a' has been selected

Selection List:

  1 - a

  Make a choice or enter a new value [a]

  :

  >>'b' has been added to the list

  --'b' has been selected

Selection List:

  1 - a

  2 - b

  Make a choice or enter a new value [b]

  :

  >>'c' has been added to the list

  --'c' has been selected

Selection List:

  1 - a

  2 - b

  3 - c

  Make a choice or enter a new value [c]

  :

  >>'d' has been added to the list

  >>'a' dropped out of the list

  --'d' has been selected

Selection List:

  1 - b

  2 - c

  3 - d

  Make a choice or enter a new value [d]

  :

  --'d' has been selected

Selection List:

  1 - b

  2 - c

  3 - d

  Make a choice or enter a new value [d]

  :

  --'c' has been selected

Selection List:

  1 - b

  2 - d

  3 - c

  Make a choice or enter a new value [c]

  :

Selection List:

  1 - b

  2 - c

  >> 'd' has been removed from list

  Make a choice or enter a new value [c]

  :

Selection List:

  1 - c

  >> 'b' has been removed from list

  Make a choice or enter a new value [c]

  :

Selection List:

  1 - c

  >> 'b' cannot be removed from list

  Make a choice or enter a new value [c]

  :

  >>'z' has been added to the list

  --'z' has been selected