Knowledge Base |

# PRB: Problem Redirecting Output to Printer When Offline

Article ID: 108904

Article Last Modified on 8/16/2005

APPLIES TO

- Microsoft BASIC Professional Development System 7.0
- Microsoft BASIC Professional Development System 7.1
- Microsoft QuickBasic 4.0
- Microsoft QuickBASIC 4.0b
- Microsoft QuickBasic 4.5 for MS-DOS
- Microsoft Visual Basic for MS-DOS

This article was previously published under Q108904

## SYMPTOMS

If a user uses the redirection operator (>) to redirect the output of an EXE to a printer, an error could occur if the printer isn't ready. If the program contains an error handler it may try to print a message, and this action also causes the error. Thus the program terminates as though there was no error handler.

## CAUSE

The problem is that any diagnostic generated by the error handler is also redirected to the printer, thus causing another error.

## WORKAROUND

An error handler should always print to the device which is least likely to fail. The scrn: device is usually the best choice. If you open this device directly, you can be assured it won't be redirected.
Here are two possible workarounds:

1. Set up an error handler and detect errors 25 and 71 (Device Fault and Disk not ready).
   When these errors occur in conjunction with the printer device, open the screen (SCRN:) for output, display an appropriate error message, and wait for the user to respond.
   Example:

          ON ERROR GOTO bug
          OPEN "scrn:" FOR OUTPUT AS #1
          PRINT #1, "Printing to screen"
          PRINT "Printing to printer"
          END
          bug:
              PRINT #1, "Error number ";ERR
          END

2. Check printer status with a ROM BIOS interrupt

You can also check the status of the printer periodically throughout a program by using the ROM BIOS Interrupt 17h with function 2. This interrupt returns the printer status in the AH register. Each bit returned in AH represents the following printer conditions:

       Bit     Condition
       ----------------------------------
       Bit 7   Printer Not Busy (0 = Busy)
       Bit 6   Acknowledge
       Bit 5   Out of Paper
       Bit 4   Printer Selected
       Bit 3   I/O Error
       Bit 2   Unused
       Bit 1   Unused
       Bit 0   Timed-Out

For example, to determine if the printer is out of paper, the interrupt could be called and bit 5 could be examined. To call MS-DOS interrupts from Visual Basic for MS-DOS, use the CALL INTERRUPT routine.
The following is a sample Basic program that uses the CALL INTERRUPT routine to check the printer status whenever the F1 key is pressed, or after a Basic error:

### Example Code

       ' To try this example in VBDOS.EXE:
       ' 1. From the File menu, choose New Project.
       ' 2. Copy the code example to the Code window.
       ' 3. Press F5 to run the program.
       '
       ' To run this program in the environment, you must invoke the
       ' environment with the /L switch to load the default Quick library:
       ' VBDOS.EXE /L for Visual Basic 1.0 for MS-DOS
       DECLARE SUB PrinterStatus ()
       DEFINT A-Z
       ' Use the following include file for Visual Basic 1.0 for MS-DOS:
       REM $INCLUDE: 'VBDOS.BI'
       ' Use the following include file for QuickBasic for MS-DOS:
       REM $INCLUDE: 'qb.bi'
       ' Use the following include file for Basic PDS for MS-DOS:
       REM $INCLUDE: 'qbx.bi'

       CLS
       ON ERROR GOTO Trap
       ON KEY(1) GOSUB CheckPrinter
       KEY(1) ON
       OPEN "lpt1:" FOR OUTPUT AS #1
       FOR i = 1 TO 1000
          PRINT #1, "dflkgjsaklfajds;lfk"
       NEXT i
       END

       Trap:
       CALL PrinterStatus
       INPUT "Hit Any Key to Continue"; a$
       RESUME

       CheckPrinter:
       PRINT "err = "; ERR
       CALL PrinterStatus
       INPUT "Hit Any Key to Continue"; a$
       RESUME

       SUB PrinterStatus STATIC
       DIM ina AS RegType, outa AS RegType
       DIM INFO$(7)
       ina.ax = &H200
       ina.dx = &H0
       CALL INTERRUPT(&H17, ina, outa)
       outah = outa.ax \ 256
       FOR i = 7 TO 0 STEP -1
          result = (outah) AND (2 ^ i)
          IF result = 0 THEN
             INFO$(i) = "OFF"
          ELSE
             INFO$(i) = "ON"
          END IF
       NEXT i
       PRINT "Bit 7 - Printer Not Busy : "; INFO$(7)
       PRINT "Bit 6 - Acknowledge : "; INFO$(6)
       PRINT "Bit 5 - Out of Paper : "; INFO$(5)
       PRINT "Bit 4 - Printer Selected : "; INFO$(4)
       PRINT "Bit 3 - I/O Error : "; INFO$(3)
       PRINT "Bit 2 - Unused : "; INFO$(2)
       PRINT "Bit 1 - Unused : "; INFO$(1)
       PRINT "Bit 0 - Timed-Out : "; INFO$(0)
       END SUB

## STATUS

This behavior is under review and will be considered for correction in a future release.

## MORE INFORMATION

### Steps to Reproduce Behavior

Compile the Following program and run it without a printer connected as shown below:

    PRINT "Printing to printer"
    END

    PROGRAM >LPT1:

Additional query words: VBmsdos QuickBas BasicCom b_vbmsdos b_quickbas

Keywords: kbprb KB108904