No announcement yet.

Obtain ERRORLEVEL value? Possible?

  • Filter
  • Time
  • Show
Clear All
new posts

  • Obtain ERRORLEVEL value? Possible?

    I would to run an BATch file from Powerbasic, but for it to
    do me any good, I somehow need to transfer the ERRORLEVEL
    value back to the program.

    That is not possible, or is it? If possible, what gets/traps
    the ERRORLEVEL value so it can get transferred/read by the

    Thank you.



  • #2
    A simple work-around would be to make your batch file write a filename to the current directory using either echo or touch based on the errorlevel, then check which file exists when you re-enter your PB program.

    In your batch file:

    if errorlevel 2 echo.> level2.tmp

    Then, in your PB program:

    if len(dir$("level2.tmp"))>0 then
    kill "level2.tmp" ' so we don't find it again on the next run by mistake
    print "We found errorlevel 2 and now we can sing."
    end if



    • #3
      ' Execute an exteernal program as a child proccess, interrogate
      ' it's return code.
      ' For PB/DOS 3.2
      ' Author: Michael Mattias Racine WI 
      ' from original version for Microsoft QuickBASIC by Ethan Winer.
      '     SUB TO Execute a program as a child process           
      ' Function value = return code of process; if < 0, error is 
      ' -1 * (dos error)
      ' REG equates as expected in REGS.INC
      DEFINT A-Z
      FUNCTION DosExecute% (Program$, Parameter$) LOCAL
        '---- Prepare the program name and parameter strings for processing.  DOS
        '     requires that the parameter string hold the length of the parameter
        '     text, followed by the parameter text, and then followed by a CHR$(13)
        '     Enter byte.  The parameter block holds two CHR$(0) bytes followed by
        '     the address and segment of the parameter string.
        DIM Block   AS LOCAL STRING * 14    'this is the DOS parameter block
        DIM Parm    AS LOCAL STRING * 80    'and this is the actual parameter text
        DIM ZBuffer AS LOCAL STRING * 80    'this holds a copy of the program name
        SaveDefSeg = pbvDefSeg
        DEF SEG
        DefaultDS = pbvDefSeg
        Zero$ = CHR$(0)                  'invoke CHR$() only once for efficiency
        DOS = &H21                       'saves a few bytes
        ZBuffer$ = Program$ + Zero$      'make an ASCIIZ string for DOS
        LSET Parm$ = CHR$(LEN(Parameter$)) + Parameter$ + CHR$(13)
        LSET Block$ = Zero$ + Zero$ + MKI$(VARPTR(Parm$)) + MKI$(VARSEG(Parm$))
        Dummy& = SETMEM(-500000)         'free up memory for the program being run
        REG %RegAX, &h4B00
        REG %RegDX, VARPTR (ZBuffer$)
        REG %RegES, VARSEG(Block$)
        REG %RegBX, VARPTR(Block$) 
        REG %RegDS, DefaultDS
        Flags = REG(0)
        ReturnAX = REG(%RegAX)
        IF (Flags AND 1) THEN          'DOS error trying to run the program?
          DosExecute% = -(ReturnAX)    'yes, set function value to -1 * error code
          GOTO Execute.Done            'and jump to reclaim memory
        END IF
        REG %RegAX, &H4D00               'retrieve subordinate process code
        CALL Interrupt DOS
        DosExecute% = REG (%RegAX)          'set function value to exit code
        Dummy& = SETMEM(500000)          'reclaim the memory relinquished eariler
        DEF SEG = SaveDefSeg             ' restore DS to what it was at entry.
      Don't know if this works when Program$ is a batch file, but it's worth a shot.

      If that doesn't work, you could run this from within your program once for each external program in the batch file, interrogating the return code each time.


      [This message has been edited by Michael Mattias (edited February 10, 2005).]
      Michael Mattias
      Tal Systems (retired)
      Port Washington WI USA
      [email protected]


      • #4
        > Don't know if this works when Program$ is a batch file,
        > but it's worth a shot.

        Not having actually tried it, I suspect that it wouldn't work because the return value you would get would be from, and not from the program that had run. One too many layers between you and the external program, as it were.



        • #5

          On 10 Feb 05, Michael Mattias wrote:

          Hello Michael,

          > Don't know if this works when Program$ is a batch file, but it's
          > worth a shot.

          Not really Michael. ;-)

          That's my own and very old source to this problem:


          / h o m a s
          email : [email protected] / mailto:[email protected][email protected]</A> (PGP-Key available)
          www : / (PowerBASIC)
          fax/bbs: +49-30-47300910 (VFC, V34+, X75, ISDN, CCB, 9600-128000bps)
          ## CrossPoint/Agent R/C2478, via PBNEWS v0.56g (
 - -


          • #6
            But in a larger sense, why SHELL/Execute a batch file from an MS-DOS program at all?

            Nothing you can do in a batch file you can't do with 'native' PB/DOS code anyway.

            Michael Mattias
            Tal Systems (retired)
            Port Washington WI USA
            [email protected]


            • #7
              > But in a larger sense, why SHELL/Execute a batch file from
              > an MS-DOS program at all?

              You can actually run a bash script (Unix commandline) from PB/DOS using the UNIX command under DOSEMU.

              It's a pretty slick trick for accomplishing stuff that you absolutely can't do directly from PB on Linux otherwise.



              • #8
                Most child processes have their own environments, which are copies
                of their parents. A Batch file is different in that it shares its
                parents environment. So one thing you can do with a shell is to
                set or modify an environmental variable using the SET command and
                have it retained in the parent's environment.

                Trouble is, a SHELL is also a child process, and I suspect that the
                plain vanilla version also has its own environment copy, so the
                parent's environment may go unmodified. Others have come up with
                methods of doing a SHELL where the parent's environment is changed,
                so you might need to look into that.

                But really, you have other options. For instance, in the BAT file
                you may perform IF ERRORLEVEL 1 ECHO OOPS! Got an Error #1. Since
                you probably performed an @ECHO OFF at the top of the BAT file,
                if the words "OOPS! Got an Error #1" pops up on the screen, you
                just heard from your BAT file.

                Of course you could also do it this way: IF ERRORLEVEL 1 ECHO
                OOPS! Got an Error #1 > errflag.txt, then when the BAT file is
                done. you can check for the existence of errflag.txt or even
                open it and read the error that occurred. If you want your BAT
                file to tell you more, just replace the > with two .'s (>> ),
                which tells the system to just add more text to the contents of

                I've noted with Windows 2000 Pro, that I can't seem to use the
                single > and get anything written to the file, so I always have
                to use the >>.

                The statement that you can do anything in you program that a BAT
                file can do is true, but not always easily. A one-liner like any
                of these is a bit harder to do in your main program:

                FOR %a IN (*.BAS) DO TYPE %a >> \project\bigfile.bas

                FOR %a IN (*.BAS) DO ECHO $INCLUDE "%a" >> \project\

                FOR %a IN (*.lst) DO TYPE %a | SORT >>

                Or this simple BAT file:

                @ECHO OFF
                IF NOT EXIST %1.bat GOTO exit
                IF EXIST %1.bk9 DEL %1.bk9
                IF EXIST %1.bk8 REN %1.bk9
                IF EXIST %1.bk7 REN %1.bk8
                IF EXIST %1.bk6 REN %1.bk7
                IF EXIST %1.bk5 REN %1.bk6
                IF EXIST %1.bk4 REN %1.bk5
                IF EXIST %1.bk3 REN %1.bk4
                IF EXIST %1.bk2 REN %1.bk3
                IF EXIST %1.bk1 REN %1.bk2
                IF EXIST %1.bak REN %1.bk1
                COPY %1.bas %1.bak

                Old Navy Chief, Systems Engineer, Systems Analyst, now semi-retired