我想制作一个程序,为我提供所选打印机的打印计数器。我想知道在任何给定时间设备已经完成了多少打印/复印。
有没有简单的方法来实现这一目标?我已经搜索过,但似乎无法找到解决方案。
提前谢谢。
编辑(添加代码:这是我在互联网上找到的代码,它将作为列出所有已安装打印机+属性来源的起点:Wade Brooks)
Imports System.Drawing.Printing 'Printer Settings
Imports System.Runtime.InteropServices 'Printer Information
Imports System.text 'String Builder
Public Class frmPrinterInfoExample
#Region "Imports for Printer Information"
<DllImport("winspool.drv", EntryPoint:="OpenPrinterW", CharSet:=CharSet.Auto, SetLastError:=True, ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _
Private Shared Function OpenPrinter(ByVal pPrinterName As String, ByRef hPrinter As IntPtr, ByVal pDefault As IntPtr) As Boolean
End Function
<DllImport("winspool.drv", CharSet:=CharSet.Auto, SetLastError:=True, ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _
Private Shared Function ClosePrinter(ByVal hPrinter As IntPtr) As Boolean
End Function
<DllImport("winspool.drv", EntryPoint:="GetPrinterW", CharSet:=CharSet.Auto, SetLastError:=True, ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _
Private Shared Function GetPrinter(ByVal hPrinter As IntPtr, ByVal dwLevel As Integer, ByVal pPrinter As IntPtr, ByVal cbBuf As Integer, ByRef pcbNeeded As Integer) As Boolean
End Function
#End Region
#Region "Variables"
Dim mstrInfo As StringBuilder 'Info for User
'Printer Info structure
<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)> Public Structure PRINTER_INFO_2
Dim pServerName As String
Dim pPrinterName As String
Dim pShareName As String
Dim pPortName As String
Dim pDriverName As String
Dim pComment As String
Dim pLocation As String
Dim pDevMode As Integer
Dim pSepFile As String
Dim pPrintProcessor As String
Dim pDatatype As String
Dim pParameters As String
Dim pSecurityDescriptor As Integer
Dim Attributes As Integer
Dim Priority As Integer
Dim DefaultPriority As Integer
Dim StartTime As Integer
Dim UntilTime As Integer
Dim Status As Integer
Dim cJobs As Integer
Dim AveragePPM As Integer
End Structure
#End Region
#Region "Private Methods"
''' <summary>
''' Populate printer list
''' </summary>
Private Sub btnPrinterList_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPrinterList.Click
Try
PopulateInstalledPrintersCombo()
Catch ex As Exception
MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK)
End Try
End Sub
''' <summary>
''' List of installed printers
''' </summary>
Private Sub PopulateInstalledPrintersCombo()
Try
cboInstalledPrinters.Items.Clear()
' Add list of installed printers found to the combo box.
For Each strPrinter As String In PrinterSettings.InstalledPrinters
cboInstalledPrinters.Items.Add(strPrinter)
Next
If cboInstalledPrinters.Items.Count > 0 Then
cboInstalledPrinters.SelectedIndex = 0
End If
Catch ex As Exception
MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK)
End Try
End Sub
''' <summary>
''' Show other printer info to user
''' </summary>
Private Sub OtherPrinterInfo()
Dim prtPrinter As PrinterSettings = Nothing
Try
prtPrinter = New PrinterSettings
prtPrinter.PrinterName = cboInstalledPrinters.Text
'Assumes textbox1 cleared in calling function
mstrInfo.Append(String.Format("SupportsColor: {0}{1}", prtPrinter.SupportsColor, vbCrLf))
mstrInfo.Append(String.Format("IsDefaultPrinter: {0}{1}", prtPrinter.IsDefaultPrinter, vbCrLf))
mstrInfo.Append(String.Format("CanDuplex: {0}{1}", prtPrinter.CanDuplex, vbCrLf))
mstrInfo.Append(String.Format("IsPlotter: {0}{1}", prtPrinter.IsPlotter, vbCrLf))
mstrInfo.Append(String.Format("MaximumCopies: {0}{1}", prtPrinter.MaximumCopies, vbCrLf))
Catch ex As Exception
MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK)
End Try
End Sub
''' <summary>
''' Printer Information
''' </summary>
Private Function GetPrinterInfo(ByVal sName As String) As PRINTER_INFO_2
Dim hPrinter As IntPtr = IntPtr.Zero
Dim pPrinterInfo As IntPtr = IntPtr.Zero
Dim iNeed As Integer = -1
Dim SizeOf As Integer = -1
Try
'Open printer object
If (Not OpenPrinter(sName, hPrinter, IntPtr.Zero)) Then
Marshal.ThrowExceptionForHR(System.Runtime.InteropServices.Marshal.GetHRForLastWin32Error())
End If
Try
' Get the number of bytes needed.
GetPrinter(hPrinter, 2, IntPtr.Zero, 0, iNeed)
' Allocate enough memory.
pPrinterInfo = Marshal.AllocHGlobal(iNeed)
SizeOf = iNeed
If (Not GetPrinter(hPrinter, 2, pPrinterInfo, SizeOf, iNeed)) Then
Marshal.ThrowExceptionForHR(System.Runtime.InteropServices.Marshal.GetHRForLastWin32Error())
End If
' Now marshal the structure manually.
Dim PrinterInfo As PRINTER_INFO_2 = CType(Marshal.PtrToStructure(pPrinterInfo, GetType(PRINTER_INFO_2)), PRINTER_INFO_2)
Return PrinterInfo
Catch ex As Exception
MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK)
Finally
' Close the printer object.
ClosePrinter(hPrinter)
' Deallocate the memory.
Marshal.FreeHGlobal(pPrinterInfo)
End Try
Catch ex As Exception
MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK)
End Try
Return New PRINTER_INFO_2()
End Function
''' <summary>
''' Handles printer info button click
''' </summary>
Private Sub btnPrinterInfo_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPrinterInfo.Click
Try
Cursor = Cursors.WaitCursor
If mstrInfo IsNot Nothing Then
mstrInfo = Nothing
End If
mstrInfo = New StringBuilder
Dim PrinterInformation As PRINTER_INFO_2 = GetPrinterInfo(cboInstalledPrinters.Text)
txtPrinterInfo.Clear()
'Show info in Text box
If PrinterInformation.pPrinterName IsNot Nothing Then
mstrInfo.Append(String.Format("PrinterName: {0}{1}", PrinterInformation.pPrinterName, vbCrLf))
End If
If PrinterInformation.pPortName IsNot Nothing Then
mstrInfo.Append(String.Format("PortName: {0}{1}", PrinterInformation.pPortName, vbCrLf))
End If
If PrinterInformation.pComment IsNot Nothing Then
mstrInfo.Append(String.Format("Comment: {0}{1}", PrinterInformation.pComment, vbCrLf))
End If
If PrinterInformation.pDatatype IsNot Nothing Then
mstrInfo.Append(String.Format("Datatype: {0}{1}", PrinterInformation.pDatatype, vbCrLf))
End If
If PrinterInformation.pDriverName IsNot Nothing Then
mstrInfo.Append(String.Format("DriverName: {0}{1}", PrinterInformation.pDriverName, vbCrLf))
End If
If PrinterInformation.pLocation IsNot Nothing Then
mstrInfo.Append(String.Format("Location: {0}{1}", PrinterInformation.pLocation, vbCrLf))
End If
If PrinterInformation.pParameters IsNot Nothing Then
mstrInfo.Append(String.Format("Parameters: {0}{1}", PrinterInformation.pParameters, vbCrLf))
End If
If PrinterInformation.pPrintProcessor IsNot Nothing Then
mstrInfo.Append(String.Format("PrintProcessor: {0}{1}", PrinterInformation.pPrintProcessor, vbCrLf))
End If
If PrinterInformation.pServerName IsNot Nothing Then
mstrInfo.Append(String.Format("ServerName: {0}{1}", PrinterInformation.pServerName, vbCrLf))
End If
If PrinterInformation.pShareName IsNot Nothing Then
mstrInfo.Append(String.Format("ShareName: {0}{1}", PrinterInformation.pShareName, vbCrLf))
End If
'Get other info
OtherPrinterInfo()
'Add info to textbox
txtPrinterInfo.Text = mstrInfo.ToString
Catch ex As Exception
MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK)
Finally
'Clean up
If (mstrInfo IsNot Nothing) Then
mstrInfo = Nothing
End If
Cursor = Cursors.Default
End Try
End Sub
''' <summary>
''' Close Form
''' </summary>
Private Sub cmdClose_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdClose.Click
Try
Close()
Catch ex As Exception
MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK)
End Try
End Sub
#End Region
编辑2我发现这个功能确实给了我一些打印机的打印计数器但不是全部。一般的惠普打印机都没问题,但多功能打印机(京瓷/柯尼卡美能达)总是返回错误和值0。
Public Function GetPageCount(ByVal PrinterIP As String) As Integer
Dim tcpClient As TcpClient
Dim connector As New cliConnector
Try
tcpClient = connector.Connect(PrinterIP, 9100, 1000)
tcpClient.SendTimeout = 1000
tcpClient.ReceiveTimeout = 1000
Dim networkStream As NetworkStream = tcpClient.GetStream()
If networkStream.CanWrite And networkStream.CanRead Then
' Do a simple write.
Dim txt As String
txt = Chr(27) & "%-12345X@PJL" & vbLf & "@PJL INFO PAGECOUNT" & vbLf & Chr(27) & "%-12345X" & vbLf
Dim sendBytes As [Byte]() = Encoding.ASCII.GetBytes(txt)
networkStream.Write(sendBytes, 0, sendBytes.Length)
' Read the NetworkStream into a byte buffer.
Dim bytes(tcpClient.ReceiveBufferSize) As Byte
networkStream.Read(bytes, 0, CInt(tcpClient.ReceiveBufferSize))
' Output the data received from the host to the console.
Dim returndata As String = Encoding.ASCII.GetString(bytes)
tcpClient.Close()
Return returndata.Substring(returndata.IndexOf(vbNewLine) + 1, returndata.Substring(returndata.IndexOf(vbNewLine) + 1).IndexOf(vbNewLine))
Else
If Not networkStream.CanRead Then
tcpClient.Close()
Return False
Else
If Not networkStream.CanWrite Then
tcpClient.Close()
Return False
End If
End If
End If
tcpClient.Close()
Catch ex As Exception
MessageBox.Show(ex.Message)
Return False
End Try
End Function
答案 0 :(得分:0)
SNMP将是您最好的选择,我想几乎所有针对办公/商务用途的新型打印机都会支持这一点。
Cristian在这里发表了一篇精彩的文章,对此进行了更多解释。 SNMP for Local printer?
您可以在此处获取用于连接支持SNMP的设备的示例VB.net代码: http://www.snmpsharpnet.com/?page_id=105
还有一个开源的.Net库 - https://sharpsnmplib.codeplex.com/ - 我从来没有使用过这个,但它似乎有很好的记录。
远离编码帮助,但是 - 使用Spiceworks这样的东西会更容易,这些东西是免费的,可以完全满足您的需求和更多。 http://www.spiceworks.com
您可以从此处获取Spiceworks的打印机报告(http://community.spiceworks.com/reports/1237)。