Detect Windows Printer Status Using Visual Basic

Posted on 2005-05-09
Last Modified: 2013-11-25
I have an Access 2k / VB application that loops through a list of customers and prints to WinFax Fax Driver (basically another printer). I am looking for some VB code that can basically check the status of this printer and if Spooling or Printing then suspend the VB application until finished.  There should only be one print job in the print que.  Once finished, the VB application will send the next print job until it cycles through the entire recordset based on customer number.

Kind of like ...  

While WinFax Printer Status = "Spooling" OR WinFax Printer Status = "Printing"
  Do Somtheing

Any help will be appreciated.


Question by:Eric Sherman
    LVL 20

    Accepted Solution

    I believe you will find it necessary to use the Windows API to obtain what you need... the FSO printer object doesn't break down the printer status codes in a very useful manner.  See this link for a pretty complete article and code on obtaining Printer status codes that you can use...

    LVL 19

    Author Comment

    by:Eric Sherman
    Thanks Jester for the responses.  Looks like the GetPrinter API should be able to accomplish what I am trying to do.  I reviewed the link you provided and I'm not that familiar with the GetPrinter API so I need a little help to get started.

    I have a printer named "WinFax (Photo Quality)".   All I need to find out is if the JobsCount for this printer is greater than 1 then I will supspend the application running in VB.  In other words ...

    While "WinFax (Photo Quality)" JobsCount > 1 Then
      Do Something

    I need help with the structure of the code to reference the GetPrinter API in order to read the JobsCount for the printer.
    I will probably have the declare the following fuction but where/how do you reference the printer you are trying to get the JobsCount for???

    Private Declare Function GetPrinterApi Lib "winspool.drv" Alias _
           "GetPrinterA" (ByVal hPrinter As Long, _
             ByVal Level As Long, _
             buffer As Long, _
             ByVal pbSize As Long, _
             pbSizeNeeded As Long) As Long

    Private Type PRINTER_INFO_2
       JobsCount As Long



    LVL 19

    Author Comment

    by:Eric Sherman
    Ok, I searched around and put this together from a couple of other posts.  This seems to work and it find out how many print jobs are in the printer que.  I have a question if anyone can answer, please.  In the Function below HowMany() the following code is included and I'm not sure how to understand what it's doing.

        If pcbNeed > 0 Then
            ReDim pJob(pcbNeed - 1)
            retval = EnumJobs(hPrinter, 0, 99, 1, pJob(0), pcbNeed, pcbNeed, pcRet)
        End If

    When I tested the contents of the variables it would look something like this ... I'm not sure how the ReDim pJob got to 66.

        If 176 > 0 Then
            ReDim pJob(176 - 1)
            retval = EnumJobs(155667028, 0, 99, 1, 66, 176, 176, 1)
        End If

    Public Declare Function OpenPrinter Lib "winspool.drv" Alias "OpenPrinterA" _
        (ByVal pPrinterName As String, phPrinter As Long, pDefault As Any) As Long

    Public Declare Function EnumJobs Lib "winspool.drv" Alias "EnumJobsA" _
        (ByVal hPrinter As Long, ByVal FirstJob As Long, ByVal NoJobs As Long, _
        ByVal Level As Long, pJob As Any, ByVal cdBuf As Long, _
        pcbNeed As Long, pcReturned As Long) As Long

    Public Declare Function ClosePrinter Lib "winspool.drv" (ByVal hPrinter As Long) As Long

    Function HowMany()
    Dim hPrinter As Long
    Dim pcbNeed As Long, pcRet As Long
    Dim pJob() As Byte
    Dim lngJobsCount As Long
    Dim retval As Long
    Dim strPrinter As String

        'Set your printer name here
        strPrinter = "WinFax (photo quality)"
        retval = OpenPrinter(strPrinter, hPrinter, ByVal vbNullString)
        retval = EnumJobs(hPrinter, 0, 99, 1, ByVal vbNullString, 0, pcbNeed, pcRet)
        If pcbNeed > 0 Then
            ReDim pJob(pcbNeed - 1)
            retval = EnumJobs(hPrinter, 0, 99, 1, pJob(0), pcbNeed, pcbNeed, pcRet)
        End If
        retval = ClosePrinter(hPrinter)
        HowMany = pcRet
        MsgBox pcbNeed - 1
    End Function

    Featured Post

    Find Ransomware Secrets With All-Source Analysis

    Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

    Join & Write a Comment

    Article by: Martin
    Here are a few simple, working, games that you can use as-is or as the basis for your own games. Tic-Tac-Toe This is one of the simplest of all games.   The game allows for a choice of who goes first and keeps track of the number of wins for…
    A theme is a collection of property settings that allow you to define the look of pages and controls, and then apply the look consistently across pages in an application. Themes can be made up of a set of elements: skins, style sheets, images, and o…
    Get people started with the process of using Access VBA to control Outlook using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Microsoft Outlook. Using automation, an Access applic…
    Show developers how to use a criteria form to limit the data that appears on an Access report. It is a common requirement that users can specify the criteria for a report at runtime. The easiest way to accomplish this is using a criteria form that a…

    745 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    16 Experts available now in Live!

    Get 1:1 Help Now