Is the printer ready ?


Author
Message
Charles R Hankey
Charles R Hankey
StrataFrame VIP (1.3K reputation)StrataFrame VIP (1.3K reputation)StrataFrame VIP (1.3K reputation)StrataFrame VIP (1.3K reputation)StrataFrame VIP (1.3K reputation)StrataFrame VIP (1.3K reputation)StrataFrame VIP (1.3K reputation)StrataFrame VIP (1.3K reputation)StrataFrame VIP (1.3K reputation)
Group: Forum Members
Posts: 524, Visits: 30K
This sound like it should be easy but it isn't.  I need to find out from with a VFP app if a particular printer is ready to print. i.e it's current status  (Ready, out of paper, off-line whatever)  This code, offered up on  Universal Thread, doesn't work because if the printer is installed the handle will happen successfully (assuming the printer server box is on line) no matter what the status of the printer is.

(code below is a VFP function with syntax adjusted from VB)

LPARAMETERS tcprintername

&&#DEFINE cJobs_OFFSET 77

DECLARE INTEGER OpenPrinter IN winspool.drv;

STRING pPrinterName, INTEGER @phPrinter, INTEGER pDefault

DECLARE INTEGER ClosePrinter IN winspool.drv INTEGER hPrinter

cPrinter=tcprintername

hPrinter=0

IF OpenPrinter(m.cPrinter, @hPrinter, 0) = 0

&&? "Unable to obtain handle for the printer."

RETURN -1

ENDIF

= ClosePrinter(hPrinter)

RETURN 0

I found this http://www.merrioncomputing.com/Programming/PrintStatus.htm and I think my answer for creating a dll in .net may be in here but putting it together is a little beyound my current understanding of how these pieces fit.

Anyone who has solved this, knows of a third party dll that can be obtained or purchased, or who has already invented this wheel - you guidance will be greatly appreciated.

Charles

Replies
Trent Taylor
Trent Taylor
StrataFrame Developer (14K reputation)StrataFrame Developer (14K reputation)StrataFrame Developer (14K reputation)StrataFrame Developer (14K reputation)StrataFrame Developer (14K reputation)StrataFrame Developer (14K reputation)StrataFrame Developer (14K reputation)StrataFrame Developer (14K reputation)StrataFrame Developer (14K reputation)
Group: StrataFrame Developers
Posts: 6.6K, Visits: 7K
We have several .NET assembleis that we setup as COM and allow access through VFP.  We had to in order to allow our older VFP stuff run at the same time as out .NET stuff.  In fact, we actually have our VFP EXE running inside of our .NET app so people don't even know that a VFP app is running inside of the .NET app...it just feels like one application.

At any rate, like Edhy mentioned, WMI is a good way to go, but you want to be careful about using the winmgmts:// approach.  If you recall, in VFP you pretty much had no choice, this is what you had to do.  But now, in .NET, we can take safer approach and not rely on that instance.  Here is a class that will return to you the state of the printer using WMI:

Imports System.Management

Public NotInheritable Class Printers

    ''' <summary>
    ''' Available printer states (that I have figured out, anyway)
    ''' </summary>
    ''' <remarks></remarks>
    Public Enum PrinterStates As Integer
        Online = 0
        LidOpen = 4194432
        OutOfPaper = 144
        OutOfPaperLidOpen = 4194448
        Printing = 1024
        Initializing = 32768
        ManualFeedInProgress = 160
        Offline = 4096
        Unknown = -1
    End Enum

    ''' <summary>
    ''' Determine the state for a printer
    ''' </summary>
    ''' <param name="printerName"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function GetPrinterStatus(ByVal printerName As String) As PrinterStates
        '-- Establish Locals
        Dim oConn As New ConnectionOptions()
        Dim oMS As New System.Management.ManagementScope("\root\CIMV2", oConn)
        'Dim oQuery As New System.Management.ObjectQuery("select PrinterState from Win32_Printer where Name = """ & printerName & """")
        Dim oQuery As New System.Management.ObjectQuery("SELECT * FROM Win32_Printer WHERE Name = """ & printerName & """")
        Dim oSearcher As ManagementObjectSearcher
        Dim oReturnCollection As ManagementObjectCollection
        Dim r As PrinterStates

        '-- Execute the query
        oSearcher = New ManagementObjectSearcher(oMS, oQuery)

        '-- Now get the results of the query
        oReturnCollection = oSearcher.Get()

        '-- Cycle through the results
        For Each oPrinter As ManagementObject In oReturnCollection
            '-- Make sure that there is a match on the name of the printer.  This should have already been addressed
            '   as part of the query, but better safe than sorry.
            If Not CType(oPrinter.Item("Name"), String).Equals(printerName, StringComparison.OrdinalIgnoreCase) Then Continue For

            '-- First determine if the printer is online.  This is required because the PrinterState doesn't always
            '   accurately return an Offline state.
            If CType(oPrinter.Item("WorkOffline"), Boolean) Then
                r = PrinterStates.Offline
            Else
                '-- Otherwise, return the state of the printer
                Try
                    r = CType(CType(oPrinter.Item("PrinterState"), Integer), PrinterStates)
                Catch ex As Exception
                    r = PrinterStates.Unknown
                End Try
            End If

            '-- One we make it this far, then we can bail
            Exit For
        Next

        '-- Return the results
        Return r
    End Function

End Class

Then you can just call the method on the desired printer.  Here is a quick sample of how to use this:

For Each printer As String In System.Drawing.Printing.PrinterSettings.InstalledPrinters
    MsgBox(printer & ControlChars.CrLf & Printers.GetPrinterStatus(printer).ToString())
Next

Edhy Rijo
E
StrataFrame VIP (6.4K reputation)StrataFrame VIP (6.4K reputation)StrataFrame VIP (6.4K reputation)StrataFrame VIP (6.4K reputation)StrataFrame VIP (6.4K reputation)StrataFrame VIP (6.4K reputation)StrataFrame VIP (6.4K reputation)StrataFrame VIP (6.4K reputation)StrataFrame VIP (6.4K reputation)
Group: StrataFrame Users
Posts: 2.4K, Visits: 23K
Hi Trent,

I am trying to test/implement your code above, but I am getting some missing references:

  • ConnectionOptions()
  • System.Management.ManagementScope()
  • System.Management.ObjectQuery()
  • ManagementObjectCollection
  • ManagementObjectSearcher()
  • ManagementObject

Could you please tell us what is the missing reference assembly?

Edhy Rijo

Trent Taylor
Trent Taylor
StrataFrame Developer (14K reputation)StrataFrame Developer (14K reputation)StrataFrame Developer (14K reputation)StrataFrame Developer (14K reputation)StrataFrame Developer (14K reputation)StrataFrame Developer (14K reputation)StrataFrame Developer (14K reputation)StrataFrame Developer (14K reputation)StrataFrame Developer (14K reputation)
Group: StrataFrame Developers
Posts: 6.6K, Visits: 7K
Add SYstem.Management as a reference.
Edhy Rijo
E
StrataFrame VIP (6.4K reputation)StrataFrame VIP (6.4K reputation)StrataFrame VIP (6.4K reputation)StrataFrame VIP (6.4K reputation)StrataFrame VIP (6.4K reputation)StrataFrame VIP (6.4K reputation)StrataFrame VIP (6.4K reputation)StrataFrame VIP (6.4K reputation)StrataFrame VIP (6.4K reputation)
Group: StrataFrame Users
Posts: 2.4K, Visits: 23K
Thanks, that did it!

Edhy Rijo

GO

Merge Selected

Merge into selected topic...



Merge into merge target...



Merge into a specific topic ID...




Threaded View
Threaded View
Charles R Hankey - 18 Years Ago
Edhy Rijo - 18 Years Ago
Charles R Hankey - 18 Years Ago
Edhy Rijo - 18 Years Ago
Trent L. Taylor - 18 Years Ago
Edhy Rijo - 18 Years Ago
                         Add SYstem.Management as a reference.
Trent L. Taylor - 18 Years Ago
                             Thanks, that did it!
Edhy Rijo - 18 Years Ago
Charles R Hankey - 18 Years Ago
             Glad it helped! :)
Trent L. Taylor - 18 Years Ago

Similar Topics

Reading This Topic

Login

Explore
Messages
Mentions
Search