startdocprinter返回错误的非零打印队列JobID。它无效并在后续运行中减少

时间:2016-04-11 18:43:01

标签: vb.net winapi system.printing

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

一切都很完美,它是假脱机,打印,一般生活很好,但是我从StartDocPrinter返回的ID不能用于查找打印作业状态。这是错的。

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

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

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

我认为,我似乎无法找到参考资料的一件事是,StartDocPrinter和其他所有内容"不会返回/使用相同的JobID,但我还没有找到明确的引用或在它们之间进行转换的方法。

感谢任何帮助!

特里

修改

WEIRDNESS-LEVEL:无限

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

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

一旦作业完成假脱机,PrintSystemJobInfo.JobIdentifier 就会改变并成为"正常" JobIdentifier在200范围内,按顺序递增,与所有其他工作内联。

我所学到的是,我的声明似乎很好,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

`

0 个答案:

没有答案