FindNextPrinterChangeNotification problem

FindNextPrinterChangeNotification problem

Post by Duncan Jone » Wed, 27 Nov 2002 07:30:54



I have declared the PrinterNotifyInfo structure that it
wants in as a class thus:

'------------------------------------------------
Imports System.Runtime.InteropServices

<StructLayout(LayoutKind.Explicit)> _
Public Class PrinterNotifyOptions
    <FieldOffset(0)> Public dwVersion As Integer
    <FieldOffset(4)> Public dwFlags As Integer
    <FieldOffset(8)> Public Count As Integer
    '\\ --JOB_NOTIFY_OPTIONS_TYPE
    <FieldOffset(12)> Public wType As Int16
    <FieldOffset(14)> Public wReserved0 As Int16
    <FieldOffset(16)> Public dwReserved1 As Int32
    <FieldOffset(20)> Public dwReserved2 As Int32
    <FieldOffset(24)> Public FieldCount As Int32
    <FieldOffset(28)> Public pFields As IntPtr

#Region "Public Enumerated Types"
    Public Enum Printer_Notification_Types
        PRINTER_NOTIFY_TYPE = &H0
        JOB_NOTIFY_TYPE = &H1
    End Enum

    Public Enum Printer_Notify_Field_Indexes
        PRINTER_NOTIFY_FIELD_SERVER_NAME = &H0
        PRINTER_NOTIFY_FIELD_PRINTER_NAME = &H1
        PRINTER_NOTIFY_FIELD_SHARE_NAME = &H2
        PRINTER_NOTIFY_FIELD_PORT_NAME = &H3
        PRINTER_NOTIFY_FIELD_DRIVER_NAME = &H4
        PRINTER_NOTIFY_FIELD_COMMENT = &H5
        PRINTER_NOTIFY_FIELD_LOCATION = &H6
        PRINTER_NOTIFY_FIELD_DEVMODE = &H7
        PRINTER_NOTIFY_FIELD_SEPFILE = &H8
        PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR = &H9
        PRINTER_NOTIFY_FIELD_PARAMETERS = &HA
        PRINTER_NOTIFY_FIELD_DATATYPE = &HB
        PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR = &HC
        PRINTER_NOTIFY_FIELD_ATTRIBUTES = &HD
        PRINTER_NOTIFY_FIELD_PRIORITY = &HE
        PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY = &HF
        PRINTER_NOTIFY_FIELD_START_TIME = &H10
        PRINTER_NOTIFY_FIELD_UNTIL_TIME = &H11
        PRINTER_NOTIFY_FIELD_STATUS = &H12
        PRINTER_NOTIFY_FIELD_STATUS_STRING = &H13
        PRINTER_NOTIFY_FIELD_CJOBS = &H14
        PRINTER_NOTIFY_FIELD_AVERAGE_PPM = &H15
        PRINTER_NOTIFY_FIELD_TOTAL_PAGES = &H16
        PRINTER_NOTIFY_FIELD_PAGES_PRINTED = &H17
        PRINTER_NOTIFY_FIELD_TOTAL_BYTES = &H18
        PRINTER_NOTIFY_FIELD_BYTES_PRINTED = &H19
        PRINTER_NOTIFY_FIELD_OBJECT_GUID = &H1A
    End Enum

    Public Enum Job_Notify_Field_Indexes
        JOB_NOTIFY_FIELD_PRINTER_NAME = &H0
        JOB_NOTIFY_FIELD_MACHINE_NAME = &H1
        JOB_NOTIFY_FIELD_PORT_NAME = &H2
        JOB_NOTIFY_FIELD_USER_NAME = &H3
        JOB_NOTIFY_FIELD_NOTIFY_NAME = &H4
        JOB_NOTIFY_FIELD_DATATYPE = &H5
        JOB_NOTIFY_FIELD_PRINT_PROCESSOR = &H6
        JOB_NOTIFY_FIELD_PARAMETERS = &H7
        JOB_NOTIFY_FIELD_DRIVER_NAME = &H8
        JOB_NOTIFY_FIELD_DEVMODE = &H9
        JOB_NOTIFY_FIELD_STATUS = &HA
        JOB_NOTIFY_FIELD_STATUS_STRING = &HB
        JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR = &HC
        JOB_NOTIFY_FIELD_DOCUMENT = &HD
        JOB_NOTIFY_FIELD_PRIORITY = &HE
        JOB_NOTIFY_FIELD_POSITION = &HF
        JOB_NOTIFY_FIELD_SUBMITTED = &H10
        JOB_NOTIFY_FIELD_START_TIME = &H11
        JOB_NOTIFY_FIELD_UNTIL_TIME = &H12
        JOB_NOTIFY_FIELD_TIME = &H13
        JOB_NOTIFY_FIELD_TOTAL_PAGES = &H14
        JOB_NOTIFY_FIELD_PAGES_PRINTED = &H15
        JOB_NOTIFY_FIELD_TOTAL_BYTES = &H16
        JOB_NOTIFY_FIELD_BYTES_PRINTED = &H17
    End Enum

#End Region

    Public Sub New()

        '\\ As it stands, version is always 2
        dwVersion = 2
        '\\ We must have at least one notification -
status makes sense to test with...
        'NotifyJobStatus = True
        FieldCount = 1
        Dim pfld1 As Short =
Job_Notify_Field_Indexes.JOB_NOTIFY_FIELD_STATUS

        '\\ Use pointer to array per your suggestion...
        pFields = Marshal.AllocHGlobal(2)
        Marshal.WriteInt16(pFields, 0, pfld1)

    End Sub

End Class
'----------------------------------------------------

And when I pass it to FindFirstPrinterChangeNotification
it goes OK but when a print job occurs and the wait
object triggers I have to call
FindNextPrinterChangeNotification to get the info that
has changed which I have declared thus:-

'---------------------------------------------------
<DllImport("winspool.drv",
EntryPoint:="FindNextPrinterChangeNotification", _
    SetLastError:=True, CharSet:=CharSet.Ansi, _
    ExactSpelling:=True, _
    CallingConvention:=CallingConvention.StdCall)> _
    Public Shared Function
FindNextPrinterChangeNotification _
                            (<InAttribute()> ByVal
hChangeObject As IntPtr, _
                             <OutAttribute()> ByRef
pdwChange As IntPtr, _
                             <InAttribute()> ByVal
pPrinterNotifyOptions As PrinterNotifyOptions, _
                             <OutAttribute()> ByRef
lppPrinterNotifyInfo As IntPtr _
                                 ) As Boolean

    End Function
'------------------------------------------------------

Now when this is called the variable pdwChange is filled
with the correct value to indicate what has changed but
lppPrinterNotifyInfo is never non-zero.

Any thoughts at all?

Thanks in advance,
Duncan

 
 
 

1. Problem with FindNextPrinterChangeNotification (null reference in last parameter)

My problem is that the last parameter (out p) in
FindNextPrinterChangeNotification(hNotify,out
ChangeReason,IntPtr.Zero,out p)
always returns a pointer to null.

This is my code:

[DllImport("winspool.drv")]
public static extern bool OpenPrinter(string pPrinterName, out IntPtr
phPrinter, ref structPrinterDefaults pDefaults);
[DllImport("winspool.drv")]
public static extern IntPtr FindFirstPrinterChangeNotification(IntPtr
hPrinter, uint fdwFlags, uint fdwOptions, IntPtr
pPrinterNotifyOptions);
[DllImport("winspool.drv")]
static extern bool FindNextPrinterChangeNotification(IntPtr hChange,
out uint pdwChange, IntPtr pPrinterNotifyOptions, out IntPtr
ppPrinterNotifyInfo);

IntPtr nowt=IntPtr.Zero;
hNotify=FindFirstPrinterChangeNotification(hPrinter,
0x0000FF00,0,nowt); // 0x0000FF00 = PRINTER_CHANGE_JOB
WaitForSingleObject(hNotify, 0xffffffff);
IntPtr p=IntPtr.Zero;
b = FindNextPrinterChangeNotification(hNotify,out
ChangeReason,IntPtr.Zero,out p);

When I check if(p != IntPtr.Zero) , then it says is does equal
IntPtr.Zero
and if I use the following code:
PRINTER_NOTIFY_INFO info = (PRINTER_NOTIFY_INFO)Marshal.PtrToStructure(
p, typeof(PRINTER_NOTIFY_INFO) );
then I get a NullRefernceException.

Maybe this has something to do with nowt (while calling FindFirst...)
being IntPtr.Zero?
Or have I missed anything else?

2. Network Issue that hasMicrosoft and Dell Scratching there..... Um heads

3. Web Services Problem (System.InvalidOperationException)

4. Sheets.Add() in Excel Interop?

5. Zero Deployment problems - System.Security.SecurityException raised

6. Netware client messages

7. Repost: Problems with shared forms and .resx files (MissingManifestResourceException)

8. Considering _mood_ in wizard-design

9. Exception management application block and System.Web.HttpUnhandledException

10. Error trying to generate a value for a System.Data.OleDb.OleDbConnection type property

11. Does DataTable.Select(FilterExpression) always force new index?

12. System.ComponentModel.Description Support

13. URGENT HELP needed - System.Security.SecurityException: Permission denied