【问题标题】:Get Print Counter VB.net获取打印计数器 VB.net
【发布时间】:2014-09-21 17:38:36
【问题描述】:

我想制作一个程序,为我提供所选打印机的打印计数器。我想随时知道设备打印/复印了多少次。

有没有简单的方法来实现这一点?我已经搜索过,但似乎找不到解决方案。

提前谢谢你。

编辑(添加代码:这是我在互联网上找到的代码,将作为列出所有已安装打印机 + 属性来源的起点: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

EDIT 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

【问题讨论】:

  • 您应该提供一些关于您已经尝试过的内容的见解。这在很大程度上是本网站的预期。请参考这里:stackoverflow.com/help/how-to-ask
  • 感谢 Jens 的回复,但我真的没有太多可以开始的地方。我在列出设备上已安装的打印机及其一些属性方面找到了一些帮助。但我不知道如何找到打印柜台。
  • 只需添加一些这些信息就可以了。它不需要是工作代码。它显示了值得赞赏的研究工作,它可以帮助人们提供答案。
  • 这是我在原始帖子中包含的当前使用的代码。但这是我在互联网上找到的代码。 (来源:韦德布鲁克斯)
  • 这通常是不可能的。由打印机驱动程序决定如何生成文档的多个副本。如果它知道打印作业适合打印机的内存,那么它将只发送一次作业并告诉打印机打印它的频率。如果没有,那么它必须多次绕线。当然,打印作业可以从多台机器提交,打印机本身往往有一个页面计数器,但没有标准的方法来获取该值。打印机制造商通常有某种实用程序来查询它。

标签: vb.net printing


【解决方案1】:

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

您可以从此处 (http://community.spiceworks.com/reports/1237) 获取 Spiceworks 的打印机报告插件。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-09
    • 2010-09-18
    • 1970-01-01
    • 2015-09-23
    相关资源
    最近更新 更多