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