Announcement

Collapse
No announcement yet.

Obtain ERRORLEVEL value? Possible?

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Donald Darden
    replied
    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
    errflag.txt.

    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\include.inc

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

    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
    :exit

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

    Leave a comment:


  • Frank Cox
    replied
    > 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.

    ------------------

    Leave a comment:


  • Michael Mattias
    replied
    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.

    Leave a comment:


  • Thomas Gohel
    replied

    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:
    http://www.pbhq.de/cgi-bin/pbsearch....on=pbshell.bas

    Regards,

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

    Leave a comment:


  • Frank Cox
    replied
    > 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 command.com, and not from the program that command.com had run. One too many layers between you and the external program, as it were.



    ------------------

    Leave a comment:


  • Michael Mattias
    replied
    Code:
    ' EXECDOS.BAS
    ' 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
      CALL INTERRUPT DOS
      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
    
    Execute.Done:
      Dummy& = SETMEM(500000)          'reclaim the memory relinquished eariler
      DEF SEG = SaveDefSeg             ' restore DS to what it was at entry.
    
    END FUNCTION
    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.

    MCM


    [This message has been edited by Michael Mattias (edited February 10, 2005).]

    Leave a comment:


  • Frank Cox
    replied
    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

    ------------------

    Leave a comment:


  • Robert E. Carneal
    started a topic Obtain ERRORLEVEL value? Possible?

    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
    program?

    Thank you.

    Robert

    ------------------
Working...
X