Limit CMD processing to internal commands, safer and faster?
Posted: 21 Nov 2011 17:11
In the thread CALL me, or better avoid call at
http://www.dostips.com/forum/viewtopic.php?f=3&t=1947&hilit=precedence
Jeb demonstrated the slowness and unsafety of 'call set' and 'call echo'
The code below is an attempt to tackle both problems.
This is done by skipping the superfluous directory and extension searches.
This effectively limits default processing to internal commands only.
External commands can still be used but will require path and extension.
I have used the commandlist of Vista and done limited tests on Vista.
iCMDdemo.bat
http://www.dostips.com/forum/viewtopic.php?f=3&t=1947&hilit=precedence
Jeb demonstrated the slowness and unsafety of 'call set' and 'call echo'
The code below is an attempt to tackle both problems.
This is done by skipping the superfluous directory and extension searches.
This effectively limits default processing to internal commands only.
External commands can still be used but will require path and extension.
I have used the commandlist of Vista and done limited tests on Vista.
iCMDdemo.bat
Code: Select all
@echo off
cls
echo examples for "call set" and "call echo"
echo(
echo call :iCmd Set var=hello by set
echo call :iCmd Echo hello by echo
set "var="
call :iCmd Set var=hello by set
call :iCmd Echo hello by echo
set var&rem show new value
echo(
echo The same but now without iCMD
echo(
echo call :LimitCMDToInternalCommands
echo call Set var=hello by set
echo call Echo hello by echo
echo call :RestoreCMDExternalCommands
call :LimitCMDToInternalCommands
set "var="
call Set var=hello by set
call Echo hello by echo
set var&rem show new value
call :RestoreCMDExternalCommands
echo(
echo Done
call :iCmd
exit/b
goto:eof
:LimitCMDToInternalCommands
rem store current (d)path(ext)
if defined path set pushPath=%path%
if defined dpath set pushDpath=%dpath%
set pushPathExt=%pathext%
rem limit (d)path(ext) NOTE: pathext must be defined or call will fallback to cmd internal default)
path;&dpath;&set pathext=;
goto :eof
:RestoreCMDExternalCommands
rem restore original (d)path(ext)
if defined pushPath path %pushPath%
if defined pushdpath dpath %pushDpath%
set pathext=%pushPathExt%
rem cleanup
set pushPath=&set pushDPath=&set pushPathExt=
goto :eof
:iCmd internalCommand parameters
REM echo params [%*]
if not @%1 == @ (
call :LimitCMDToInternalCommands
rem call internal command
for %%a in (ASSOC BREAK CALL CD CHDIR CLS COLOR COPY DATE DEL DIR DPATH ECHO ENDLOCAL ERASE ^
FTYPE KEYS MD MKDIR MKLINK MOVE PATH PAUSE POPD PROMPT PUSHD RD REM ^
REN RENAME RMDIR SET SETLOCAL SHIFT TIME TITLE TYPE VER VERIFY VOL ^
) do if /I @%%a == @%1 call %*
call :RestoreCMDExternalCommands
) else (
echo(
echo Syntax:
echo(
echo call :iCmd NameForInternalCommand ParametersForInternalCommand
echo(
echo Some remarks:
echo Internal commands IF and FOR can not be used with call
echo Internal commands GOTO and EXIT can be used with iCmd and will be safe but cause a problem,
echo These commands transfer control so restoring the orinal [d]path[ext] is not possible!
echo This can not be solved inside iCmd but can be solved in the calling batchfile.
echo Use the subs LimitCMD... and RestoreCMD... in the calling batchfile.
echo Use Setlocal and Endlocal as further safeguard against losing your paths [in case of error or EXIT]
echo In limited mode external commands can still be used but you have to use full path and file extension.
echo(
pause
exit/b
)
goto :eof
)
goto :eof