0

我正在使用 MSKB RawPrinterHelper 代码的 vb.net/win32 示例的略微修改版本将 RAW 打印作业发送到打印队列。

一切正常,它可以打印,它可以打印,而且通常生活很好,但是我从 StartDocPrinter 返回的 ID 不能用于查找打印作业状态。这是错误的。

使用 ManagementObjectSearcher 查找作业状态所需的 JobID 与 StartDocPrinter 返回的 ID 不匹配。

更奇怪的是,StartDocPrinter 返回的句柄在每次调用时都会减小。

它看起来几乎像某种有符号/无符号溢出条件。

我考虑过的一件事,我似乎找不到参考,是 StartDocPrinter 和“其他一切”不返回/使用相同的 JobID,但我还没有找到明确的参考或转换方法它们之间。

任何帮助表示赞赏!

特里

编辑

怪异等级:无限

我编写了一个应用程序来监控打印队列并不断从打印队列中返回 PrintSystemJobInfo.JobIdentifiers 列表。

当打印作业正在假脱机时,它的 ID 在 29,000 范围内,并且每个新作业都会将其一。然而 。. . .

作业完成假脱机后,PrintSystemJobInfo.JobIdentifier将更改并变为 200 范围内的“正常”JobIdentifier,按递增顺序,与所有其他作业内联。

我了解到的是,我的声明似乎很好,并且 JobIdentifier 在作业完成假脱机时实际上会发生变化。

???

`

<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
Structure DOCINFOW
    <MarshalAs(UnmanagedType.LPWStr)> Public pDocName As String
    <MarshalAs(UnmanagedType.LPWStr)> Public pOutputFile As String
    <MarshalAs(UnmanagedType.LPWStr)> Public pDataType As String
End Structure

<DllImport("winspool.Drv", EntryPoint:="StartDocPrinterW", _
   SetLastError:=True, CharSet:=CharSet.Unicode, _
   ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _
Public Shared Function StartDocPrinter(ByVal hPrinter As IntPtr, ByVal level As Int32, ByRef pDI As DOCINFOW) As UInt32
End Function


Public Shared Function SendBytesToPrinter(ByVal szPrinterName As String, ByVal pBytes As IntPtr, ByVal dwCount As Int32, JobName As String) As UInteger

    Dim hPrinter As IntPtr
    Dim dwError As Int32
    Dim di As New DOCINFOW

    Dim dwWritten As Int32
    Dim pjID As UInteger = 0

    Dim PrintQueueName As String = ""
    Dim PrintServerName As String = ""

    Try
        Dim pd As New PRINTER_DEFAULTS

        With di
            .pDocName = JobName
            .pDataType = "RAW"
        End With

        If OpenPrinter(szPrinterName, hPrinter, pd) Then  
            pjID = StartDocPrinter(hPrinter, 1, di)
            If pjID = 0 Then
              ' it's an error. 
            Else
                    If StartPagePrinter(hPrinter) Then
                        If WritePrinter(hPrinter, pBytes, dwCount, dwWritten) = False Then
                            dwError = Marshal.GetLastWin32Error()

                        End If
                        EndPagePrinter(hPrinter)
                    End If
                End If
                EndDocPrinter(hPrinter)
            End If
            ClosePrinter(hPrinter)
        End If

    Return pjID
End Function

`

4

0 回答 0