Discussion:
Reset/set and Display/get errorlevel
(too old to reply)
Will Sort from China
2005-05-16 08:09:51 UTC
Permalink
:: ErrLvl.bat - Reset/set and Display/get errorlevel
:: Will Sort - 2005/04/16 - MSDOS6.22/***@Win98/***@Wi­nXP
:: Test:
:: if %1>255 ==> %el%=(%1 mod 256)
:: if %1=e11 ==> %el%=0
:: if %1=11e ==> %el%=11
::
@echo off
if "%1"=="" goto Get
if "%1"=="@" goto Get
if not "%1"=="/?" goto Set


:help
echo.
echo ErrLvl.bat - Reset/set and Display/get errorlevel
echo Usage:
echo set errorlevel: errlvl decnum [@]
echo get errorlevel: errlvl [@]
echo @ is optional quiet switch.
echo.
goto end

:Set
if exist ~ErrLvl.com goto SetRun
:SetMake
echo.>~ErrLvl.asd
echo>>~ErrLvl.asd E 100 BE 82 00 31 C0 31 DB B9 0A 00 8A 1C 80 FB 30 7C

echo>>~ErrLvl.asd E 110 0F 80 FB 39 7F 0A 80 EB 30 F7 E1 01 D8 46 EB EA

echo>>~ErrLvl.asd E 120 B4 4C CD 21
for %%s in (N~ErrLvl.com RCX 24 W Q) do echo %%s>>~ErrLvl.asd
debug < ~ErrLvl.asd > nul
:SetRun
~ErrLvl %1
if "%2"=="@" goto end

:Get
set el=0
if errorlevel 1 set el=1
if not errorlevel 2 goto GetDisplay
:GetByBit
set el=
if errorlevel 100 for %%n in (1 2) do if errorlevel %%n00 set el=%%n
set #el=0 1 2 3 4 5 6 7 8 9
if "%el%"=="2" set #el=0 1 2 3 4 5
if errorlevel 10 for %%n in (%#el%) do if errorlevel %el%%%n0 set
el=%el%%%n
set #el=0 1 2 3 4 5 6 7 8 9
if "%el%"=="25" set #el=0 1 2 3 4 5
for %%n in (%#el%) do if errorlevel %el%%%n set el=%el%%%n
set #el=
:GetDisplay
if not "%1"=="@" echo Current errorlevel is:
%el%
goto end

:end
William Allen
2005-05-16 22:43:18 UTC
Permalink
"Will Sort from China" wrote in message
...snip
Post by Will Sort from China
echo.>~ErrLvl.asd
echo>>~ErrLvl.asd E 100 BE 82 00 31 C0 31 DB B9 0A 00 8A 1C 80 FB 30 7C
echo>>~ErrLvl.asd E 110 0F 80 FB 39 7F 0A 80 EB 30 F7 E1 01 D8 46 EB EA
echo>>~ErrLvl.asd E 120 B4 4C CD 21
for %%s in (N~ErrLvl.com RCX 24 W Q) do echo %%s>>~ErrLvl.asd
debug < ~ErrLvl.asd > nul
:SetRun
~ErrLvl %1
...snip

Nice work.

It's conventional to have a Batch file delete its workfiles when it
finishes (unless you want to retain them for diagnostic or future use).

For Windows 95/98/ME only:
As a point of interest, it's not always necessary to have DEBUG create
an executable file (unless you intend to retain it for future use).

With your code:
100 mov si,82
103 xor ax,ax
105 xor bx,bx
107 mov cx,a
10a mov bl,[si]
10c cmp bl,30
10f jl 120
111 cmp bl,39
114 jg 120
116 sub bl,30
119 mul cx
11b add ax,bx
11d inc si
11e jmp 10a
120 mov ah,4c
122 int 21

you can issue a g(=go or execute from 100, the default) to execute the
script directly. The Return code you set will remain in the ERRORLEVEL
byte when the DEBUG script ends (as far as I'm aware, this won't work
in Windows 2000 and similar operating systems, and also note that in
those systems the ERRORLEVEL can be negative or greater than 255
and is displayable by expanding the system variable %ERRORLEVEL%).

Note that in some cases (not the code above) you may need to terminate
the code in the script with INT 3 (breakpoint =hex CC) in order to leave
registers and other values available.

This demo shows syntax (it only uses the SET ERRORLEVEL part of your
code), and assumes that the ERRORLEVEL to be set is in the %1 parameter:

Lines that don't begin with two spaces have wrapped accidentally
====Begin cut-and-paste (omit this line)
@ECHO OFF
IF [%1]==[] GOTO :EOF
ECHO.e100 be 82 0 31 c0 31 db b9 0a 0 8a 1c 80 fb 30 7c>_ERR.SCR
ECHO.e110 f 80 fb 39 7f a 80 eb 30 f7 e1 1 d8 46 eb ea>>_ERR.SCR
ECHO.e120 b4 4c cd 21>>_ERR.SCR
FOR %%C IN (g q) DO ECHO.%%C>>_ERR.SCR
debug _ERR.SCR %1<_ERR.SCR>NUL
DEL _ERR.SCR
:EOF

====End cut-and-paste (omit this line)
For Win95/98/ME study/demo use. Cut-and-paste as plain-text Batch file.
Batch file troubleshooting: http://www.allenware.com/find?UsualSuspects

This screen capture shows operation in a Return-code shell (to display
the ERRORLEVEL), with the above pasted as DEMO.BAT

============Screen capture Windows 95
C:\WORK>rem Work in a Return-code shell to display ERRORLEVEL

C:\WORK>command /z /k prompt Rcode $p$g
Return code (ERRORLEVEL): 0
WARNING: Reloaded COMMAND.COM transient

Rcode C:\WORK>demo.bat 154
Return code (ERRORLEVEL): 154
Rcode C:\WORK>demo.bat 255
Return code (ERRORLEVEL): 255
Rcode C:\WORK>demo.bat 0
Return code (ERRORLEVEL): 0
Rcode C:\WORK>exit

C:\WORK>
============End screen capture

Note 1:
In the code line:

debug _ERR.SCR %1<_ERR.SCR>NUL

the first use of _ERR.SCR is merely a place-filler to allow the %1
to be passed to DEBUG as a command tail from offset hex 82 so that
your script can pick up the value. If there isn't a handy file around,
you can equally well use NUL as place-filler in Windows 95/98/ME, thus:

debug NUL %1<_ERR.SCR>NUL

Note 2:
The use of the Windows 95/98/ME Return-code shell is explained and
demonstrated in Lesson 2 (Using Child Shells) of our Batch Course:
http://www.allenware.com/icsw/icswidx.htm

--
William Allen
Free interactive Batch Course http://www.allenware.com/icsw/icswidx.htm
Batch Reference with examples http://www.allenware.com/icsw/icswref.htm
Header email is rarely checked. Contact us at http://www.allenware.com/
Will Sort from China
2005-05-19 02:00:09 UTC
Permalink
Thank you for taking the time to reply and share your knowledge.
I am a Chinese and my English is poor.
I hope that you understand much phase problem of this text.
Post by William Allen
It's conventional to have a Batch file delete its workfiles when it
finishes (unless you want to retain them for diagnostic or future use).
I know that deleting of workfiles is necessary in most of batch
program.
But many internal commands of ***@WinXP can reset errorlevel, e.g. del.
If delete workfiles in batch, errorlevel will set to 0 by 'del'
command.
Post by William Allen
As a point of interest, it's not always necessary to have DEBUG create
an executable file (unless you intend to retain it for future use).
you can issue a g(=go or execute from 100, the default) to execute the
script directly. The Return code you set will remain in the
ERRORLEVEL
Post by William Allen
byte when the DEBUG script ends (as far as I'm aware, this won't work
in Windows 2000 and similar operating systems, and also note that in
those systems the ERRORLEVEL can be negative or greater than 255
and is displayable by expanding the system variable %ERRORLEVEL%).
Because I want to get&set errorlevel in a batch program.
I tried to execute script directly. But just such as your said,
it don't work in Windows 2000 and similar operating systems.
Similarly, COMMAND /Z and %ERRORLEVEL% won't work in ALL command line.

For compatibility of program, I was obliged to selected current ways.
Post by William Allen
Note that in some cases (not the code above) you may need to
terminate
Post by William Allen
the code in the script with INT 3 (breakpoint =hex CC) in order to leave
registers and other values available.
I have seen most program used it, but never really know use of INT3.
Post by William Allen
This demo shows syntax (it only uses the SET ERRORLEVEL part of your
code), and assumes that the ERRORLEVEL to be set is in the %1
parameter:

In Win9x command, I wrote a program on set errorlevel too.

====Begin cut-and-paste (omit this line)
:: SetErr.bat - Second version
:: Will Sort - 2004/02/07 - ***@Win98
:: Usage:
:: SetErr HexNum [@]
:: @ is optional quiet switch
@echo off
if [%1]==[] goto end

:main
echo a>_SetErr.scr
echo mov ax,4c%1>>_SetErr.scr
echo int21>>_SetErr.scr
echo.>>_SetErr.scr
echo g>>_SetErr.scr
echo q>>_SetErr.scr

debug <_SetErr.scr> nul
if not errorlevel 1 echo Invalid argument '%1'
:: can't check errorlevel of hexnum form
if not [%2]==[@] echo Current errorlevel: %1

:end
====End cut-and-paste (omit this line)
William Allen
2005-05-19 21:21:06 UTC
Permalink
"Will Sort from China" wrote in message
Post by Will Sort from China
Thank you for taking the time to reply and share your knowledge.
This newsgroup is for sharing knowledge :-)
Post by Will Sort from China
I am a Chinese and my English is poor.
Your English is better than my Chinese (=I speak no Chinese at all).
Post by Will Sort from China
I hope that you understand much phase problem of this text.
Post by William Allen
It's conventional to have a Batch file delete its workfiles when it
finishes (unless you want to retain them for diagnostic or future use).
I know that deleting of workfiles is necessary in most of batch
program.
If delete workfiles in batch, errorlevel will set to 0 by 'del'
command.
Yes. That's a good point. I tried to find a solution to that problem.
As far as I can tell, the START command can be used to avoid any
change to the current ERRORLEVEL in CMD.EXE, and this can be
used to prevent DEL changing the ERRORLEVEL you have set.

This example shows how to delete a workfile without affecting the
current ERRORLEVEL by running DEL in a START /min CMD /c shell.
You can read details of START command with /? help switch:
start /?

Lines that don't begin with two spaces have wrapped accidentally
====Begin cut-and-paste (omit this line)
@ECHO OFF

:: Create a pretend workfile
ECHO. Create a pretend workfile>MyWorkFile.TXT

:: Set ERRORLEVEL 1 with a bad DIR command and redirect
:: the error message to NUL with: >NUL 2>&1
DIR Bad:FileName >NUL 2>&1
ECHO. Bad DIR command set Errorlevel=%ERRORLEVEL%

:: Use START /min to run an instance of CMD.EXE to execute a DEL
:: In my simulated Windows 2000, this doesn't affect ERRORLEVEL
start /min cmd /c DEL MyWorkFile.TXT

:: Check ERRORLEVEL again
ECHO. Errorlevel after START DEL is still=%ERRORLEVEL%

====End cut-and-paste (omit this line)
Simulated Win2000 for study/demo use. Cut-and-paste as Batch text file.
Batch file troubleshooting: http://www.allenware.com/find?UsualSuspects

This screen capture shows how it works for me:

============Screen capture Windows 2000 simulated in Win95
C:\WORK>demo.cmd
Bad DIR command set Errorlevel=1
Errorlevel after START DEL is still=1

C:\WORK>
============End screen capture

This example above also shows a way many people use to post Batch files
to NewsGroups. Each line begins with two [Space]s so that if a line is
wrapped by accident, you can easily see that it has happened. When you
posted your Batch file, some lines wrapped (broke into two parts).

So for example, one of your lines appeared to me as:

===From Will Sort
if errorlevel 10 for %%n in (%#el%) do if errorlevel %el%%%n0 set
el=%el%%%n
===

Of course, I knew that it was meant to be on one line, but someone
who did not know much Batch language may not see this and
would not be able to get the Batch file to work properly.

If you indent all lines by two [Space]s, then if these two lines
wrapped, it would show as:

===
if errorlevel 10 for %%n in (%#el%) do if errorlevel %el%%%n0 set
el=%el%%%n
===

and it would be more obvious that the second line was an overflow
and not really a separate line at all.

...snip
Post by Will Sort from China
In Win9x command, I wrote a program on set errorlevel too.
====Begin cut-and-paste (omit this line)
:: SetErr.bat - Second version
@echo off
if [%1]==[] goto end
:main
echo a>_SetErr.scr
echo mov ax,4c%1>>_SetErr.scr
echo int21>>_SetErr.scr
echo.>>_SetErr.scr
echo g>>_SetErr.scr
echo q>>_SetErr.scr
debug <_SetErr.scr> nul
if not errorlevel 1 echo Invalid argument '%1'
:: can't check errorlevel of hexnum form
:end
====End cut-and-paste (omit this line)
That's good.

As I said, if you indent each line of the posted Batch file by two [Space]s
between the === lines and it will be obvious to anyone using the
Batch file if a line has accidentally wrapped (=broken in two parts).

You can make your example a little better by using two separate
assembly commands:
mov ah,4c
mov al,%1

Then, if someone forgets to put a leading 0 in front of a small
errorlevel such as 05, maybe they type:
demo.bat 5
by mistake instead of
demo.bat 05
then the Batch file won't go wrong.

And if you are a little more subtle, you can also handle the case
where they do not type any parameter. If you make those two mov
lines become:
mov ax,0%1
mov ah,4c
then when the Batch file is used with no parameter, it sets an
ERRORLEVEL of zero. So if they type:
demo.bat
it will set ERRORLEVEL 0 without needing to test whether there
is a %1 parameter or not.


===Using the PROMPT to write small DEBUG scripts

In Windows 95/98/ME, you can also use the PROMPT command to write
small DEBUG scripts in a very compact way. If you type:
prompt /?
you'll see the special characters that the PROMPT can include. One
of them is $_ (which means Carriage Return Linefeed = a new line).

This means that if you want to use a DEBUG script such as:
===Script starts
a
mov ax,0%1
mov ah,4c
int 21

g
q
===Script ends

you can generate it all as a PROMPT in one line, with:
PROMPT a$_mov ax,0%1$_mov ah,4c$_int 21$_$_g$_q
where $_ means start a new line.

If you run this PROMPT through COMMAND.COM (usually as %COMSPEC% in
batch files) you can ECHO it through DEBUG. You have to ECHO the
special PROMPT command into a temporary Batch file, then run the
Batch file in a %COMSPEC%/c child shell and pipe it to DEBUG.

This shows the syntax to set the ERRORLEVEL to the hex value in
the %1 parameter (the same as your example Batch file):

Lines that don't begin with two spaces have wrapped accidentally
====Begin cut-and-paste (omit this line)
@ECHO OFF
:: Sets ERRORLEVEL to hex value in %1
***@PROMPT a$_mov ax,0%1$_mov ah,4c$_int 21$_$_g$_q>%TEMP%.\_ERRL.BAT
%COMSPEC%/e:1024/c %TEMP%.\_ERRL.BAT | debug>NUL
DEL %TEMP%.\_ERRL.BAT

====End cut-and-paste (omit this line)
For Win95/98/ME study/demo use. Cut-and-paste as plain-text Batch file.
Batch file troubleshooting: http://www.allenware.com/find?UsualSuspects

The temporary Batch file is created in the TEMP folder, which is variable
usually set to C:\WINDOWS\TEMP in Windows 95/98/ME. Strictly speaking,
you don't need the [Space]s in mov[Space]ax and int[Space]21 and so on,
but I put them in for clarity.

--
William Allen
Free interactive Batch Course http://www.allenware.com/icsw/icswidx.htm
Batch Reference with examples http://www.allenware.com/icsw/icswref.htm
Header email is rarely checked. Contact us at http://www.allenware.com/
Will Sort from China
2005-05-23 14:22:53 UTC
Permalink
Post by William Allen
Lines that don't begin with two spaces have wrapped accidentally
if you indent each line of the posted Batch file by two [Space]s
between the === lines and it will be obvious to anyone using the
Batch file if a line has accidentally wrapped (=broken in two parts).
Thank you very much for your helpful hints. I will correct next posts.
Can I modify the older posts?
Post by William Allen
That's a good point. I tried to find a solution to that problem.
As far as I can tell, the START command can be used to avoid any
change to the current ERRORLEVEL in CMD.EXE, and this can be
used to prevent DEL changing the ERRORLEVEL you have set.
'START' is good idea. But is won't work in old MSDOS, e.g. MSDOS 622.
I tried to use 'CMD /C DEL', but it's failed. Therefore I have only
choice yet.
On the other hand, those files may be used to work files for
prefetching too. Of course, they shoule created in temporary folder.
Post by William Allen
mov ah,4c
mov al,%1
mov ax,0%1
mov ah,4c
PROMPT a$_mov ax,0%1$_mov ah,4c$_int 21$_$_g$_q
The temporary Batch file is created in the TEMP folder
you don't need the [Space]s in mov[Space]ax and int[Space]21
Nice ideas. Thank you again.
Post by William Allen
====Begin cut-and-paste (omit this line)
@ECHO OFF
:: Sets ERRORLEVEL to hex value in %1
21$_$_g$_q>%TEMP%.\_ERRL.BAT
Post by William Allen
%COMSPEC%/e:1024/c %TEMP%.\_ERRL.BAT | debug>NUL
DEL %TEMP%.\_ERRL.BAT
====
Perfect and laconic!
William Allen
2005-05-23 16:52:45 UTC
Permalink
"Will Sort from China" wrote in message
Post by Will Sort from China
Post by William Allen
Lines that don't begin with two spaces have wrapped accidentally
if you indent each line of the posted Batch file by two [Space]s
between the === lines and it will be obvious to anyone using the
Batch file if a line has accidentally wrapped (=broken in two parts).
Thank you very much for your helpful hints. I will correct next posts.
Can I modify the older posts?
No, and it's not really necessary. Our experience is that if someone
has problems they post back to the News Group and ask for help.

...snip
Post by Will Sort from China
'START' is good idea. But it won't work in old MSDOS, e.g. MSDOS 622.
I tried to use 'CMD /C DEL', but it's failed. Therefore I have only
choice yet.
In old MS-DOS 6.22 and Windows 95/98/ME you won't have a problem
with ERRORLEVELs being changed by internal commands like DEL
so DEL can be used directly for them.

When you are trying to write Batch files that work in many different
systems, you can take advantage of the differences to make some
commands work only in certain systems. The & command separator
in Windows NT/2000/XP is a very useful device for making a command
do nothing in MS-DOS 6.22/Windows 95/98/ME, but do several
things in Windows NT/2000/XP. This fragment shows how to
DELete with start in Windows NT/2000/XP but use DEL directly
in MS-DOS 6.22/Windows 95/98/ME.

Lines that don't begin with two spaces have wrapped accidentally
====Begin cut-and-paste (omit this line)
@ECHO OFF

ECHO. Make a workfile>WorkFile.tmp

:: The line below behaves as one ECHO to NUL command in Win95/98/ME
:: and old MS-DOS, but behaves as three commands in Windows NT/2000/XP
:: because & is a command separator in those systems. You must
:: leave a [Space] after the NUL.
ECHO/>NUL &start /min cmd.exe /c DEL WorkFile.tmp&GOTO SkipOldDos

:: This DEL command is used only in Windows 95/98/ME and old MS-DOS
DEL WorkFile.tmp

:SkipOldDos
:: Rest of batch file

====End cut-and-paste (omit this line)
Cross-platform study/demo use. Cut-and-paste as plain-text Batch file.
Batch file troubleshooting: http://www.allenware.com/find?UsualSuspects

Note that redirection in MS-DOS 6.22 and Windows 95/98/ME can
come more or less anywhere in the line. So, for those systems:

ECHO/>NUL &start /min cmd.exe /c DEL WorkFile.tmp&GOTO SkipOldDos
is the same as
ECHO/ &start /min cmd.exe /c DEL WorkFile.tmp&GOTO SkipOldDos>NUL
and simply ECHOes a message to NUL (message output is discarded and not
displayed).

Note also that, with the command
start /min cmd.exe /c DEL WorkFile.tmp
the [Space] between cmd.exe and /c is essential, or START
won't find the CMD.EXE program.
Post by Will Sort from China
On the other hand, those files may be used to work files for
prefetching too. Of course, they shoule created in temporary folder.
...snip

Yes, that's usually best, though it's handy to create workfiles in
the current folder while you are developing a new Batch file.

--
William Allen
Free interactive Batch Course http://www.allenware.com/icsw/icswidx.htm
Batch Reference with examples http://www.allenware.com/icsw/icswref.htm
Header email is rarely checked. Contact us at http://www.allenware.com/
Loading...