0

I'm using a slightly modified version of the vb.net/win32 example of the MSKB RawPrinterHelper code to send RAW print jobs to the print queue.

Everything works perfectly, It spools, it prints, and generally life is good, however the ID I get back from StartDocPrinter cannot be used to lookup the print job status. It's just wrong.

The JobID needed to lookup the Job Status with ManagementObjectSearcher does not match the ID returned by StartDocPrinter.

Even more strange, is that StartDocPrinter returns a handle that decreases each time it's called.

It looks almost like some sort of signed/unsigned overflow condition.

One thing I've considered, that I can't seem to find a reference for, is that StartDocPrinter and "everything else" does not return/use the same JobID, but I haven't found a definitive reference or a way to convert between them.

Any help is appreciated!

Terry

EDIT

WEIRDNESS-LEVEL: Infinite

I wrote an app to monitor the print queue and continuously return a list of PrintSystemJobInfo.JobIdentifiers from the print queue.

While the print job is spooling, it has an ID that's in the 29,000 range, and each new job decrements it by one. HOWEVER . . . .

Once the job has finished spooling, the PrintSystemJobInfo.JobIdentifier changes and becomes a "normal" JobIdentifier in the 200 range, in increasing sequence, right inline with all the other jobs.

What I have learned is that my declaration seems to be fine and the JobIdentifier actually changes when the job finishes spooling.

?????

`

<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

`

Terry Carmen
  • 3,720
  • 1
  • 16
  • 32
  • Something subtle is wrong here. The job ID it returns should be usable anywhere a print job ID is usable. Please show your declaration of `StartDocPrinter`. – Carey Gregory Apr 11 '16 at 19:18
  • Also, you're not initializing `pOutputFile` in `DOCINFOW`. I'm not up on VB enough to know whether that will be initialized to zero or just left uninitialized. If it's the latter, that's breakage. – Carey Gregory Apr 11 '16 at 19:27
  • 1
    @CareyGregory a string member of a class/struct will initialise to Nothing (null in c#) – Stuart Whitehouse Apr 11 '16 at 19:50
  • Thanks, I added the decl for StartDocPrinter and the DOCINFOW structure. – Terry Carmen Apr 11 '16 at 20:33
  • Also, I just set pOutputFile to Nothing, but it didn't fix it. It's nice to do anyway, just so there's no question. – Terry Carmen Apr 11 '16 at 20:51
  • `What I have learned is that my declaration seems to be fine and the JobIdentifier actually changes when the job finishes spooling.` -- That doesn't match my experience at all. I have a print driver/print processor application that's been in use for many years and it uses job IDs heavily. It uses those IDs to track print jobs from beginning to end, so the behavior you describe would have broken it badly. You do, indeed, have an infinite weirdness level going here. – Carey Gregory Apr 15 '16 at 00:26
  • Would you mind sharing a small chunk of code that submits a raw print job and gets back an ID? (or are you using the same code I am?) I wouldn't have believed the changing ID either, if I hadn't watched it change. – Terry Carmen Apr 15 '16 at 20:02

0 Answers0