Printer Status

  • Thread starter Thread starter Gordon Truslove
  • Start date Start date
G

Gordon Truslove

Has anybody managed to get GetPrinter and PRINER_INFO_2 to work?
I would like to retrieve the printer status.
 
Gordon,

What are the definitions you are using? The PRINTER_INFO_2 structure
has a lot of information (if you include the DEVMODE structure as well), and
there could be errors in how you are accessing it.

Can you show the definitions that you have?
 
I've tried about 3-4 variations. Here is the biggest. I've tried avoiding
the devmode and security descriptor but it still fails.
[ DllImport("winspool.drv" )]

public static extern bool GetPrinter(IntPtr hPrinter,long Level,ref
PRINTERINFO2 pPrinter,long cbBuf,ref long pcbNeeded);


[StructLayout( LayoutKind.Sequential)]

public struct PRINTERINFO2

{

[MarshalAs(UnmanagedType.LPWStr)]public string pServerName;

[MarshalAs(UnmanagedType.LPWStr)]public string pPrinterName;

[MarshalAs(UnmanagedType.LPWStr)]public string pShareName;

[MarshalAs(UnmanagedType.LPWStr)]public string pPortName;

[MarshalAs(UnmanagedType.LPWStr)]public string pDriverName;

[MarshalAs(UnmanagedType.LPWStr)]public string pComment;

[MarshalAs(UnmanagedType.LPWStr)]public string pLocation;

public DEVMODE pDevMode;

[MarshalAs(UnmanagedType.LPWStr)]public string pSepFile;

[MarshalAs(UnmanagedType.LPWStr)]public string pPrintProcessor;

[MarshalAs(UnmanagedType.LPWStr)]public string pDatatype;

[MarshalAs(UnmanagedType.LPWStr)]public string pParameters;

public SECURITY_DESCRIPTOR pSecurityDescriptor;

public long Attributes;

public long Priority;

public long DefaultPriority;

public long StartTime;

public long UntilTime;

public long Status;

public long cJobs;

public long AveragePPM;

}

[StructLayout( LayoutKind.Sequential)]

public struct SECURITY_DESCRIPTOR{

public byte Revision;

public byte Sbz1;

public long Control;

public long Owner;

public long Group;

public ACL sACL;

public ACL Dacl;

}

[StructLayout( LayoutKind.Sequential)]

public struct ACL{

public byte AclRevision;

public byte Sbz1;

public int AclSize;

public int AceCount;

public int Sbz2;

}



[StructLayout( LayoutKind.Sequential)]

public struct DEVMODE{

public string dmDeviceName;

public int dmSpecVersion;

public int dmDriverVersion;

public int dmSize;

public int dmDriverExtra;

public long dmFields;

public int dmOrientation;

public int dmPaperSize;

public int dmPaperLength;

public int dmPaperWidth;

public int dmScale;

public int dmCopies;

public int dmDefaultSource;

public int dmPrintQuality;

public int dmColor;

public int dmDuplex;

public int dmYResolution;

public int dmTTOption;

public int dmCollate;

public string dmFormName;

public int dmLogPixels;

public long dmBitsPerPel;

public long dmPelsWidth;

public long dmPelsHeight;

public long dmDisplayFlags;

public long dmDisplayFrequency;

public long dmICMMethod;

public long dmICMIntent;

public long dmMediaType;

public long dmDitherType;

public long dmReserved1;

public long dmReserved2;

}

Nicholas Paldino said:
Gordon,

What are the definitions you are using? The PRINTER_INFO_2 structure
has a lot of information (if you include the DEVMODE structure as well), and
there could be errors in how you are accessing it.

Can you show the definitions that you have?


--
- Nicholas Paldino [.NET/C# MVP]
- nick(dot)paldino=at=exisconsulting<dot>com

Gordon Truslove said:
Has anybody managed to get GetPrinter and PRINER_INFO_2 to work?
I would like to retrieve the printer status.
 
Gordon,

Ahh...

The first thing is that all of the places you are using long you should
be using int. In C, a long is a 32-bit integer. In C#, a long is a 64-bit
integer, which is throwing everything off. So you should be changing the
longs to ints.

Additionally, you should set the unmanaged type to LPTStr and set the
CharSet value in the StructLayout attribute to CharSet.Auto (as well as in
the DllImport declaration as well).

Finally, the SECURITY_DESCRIPTOR and DEVMODE structures are not embedded
in the PRINTER_INFO_2 structure. Rather, they are pointers. You can
replace these fields with IntPtr and set them to zero if you are not using
them.

However, when the call is complete, you need to be aware if they were
populated and free the memory that the pointers point to if there is
something there.

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- nick(dot)paldino=at=exisconsulting<dot>com


Gordon Truslove said:
I've tried about 3-4 variations. Here is the biggest. I've tried avoiding
the devmode and security descriptor but it still fails.
[ DllImport("winspool.drv" )]

public static extern bool GetPrinter(IntPtr hPrinter,long Level,ref
PRINTERINFO2 pPrinter,long cbBuf,ref long pcbNeeded);


[StructLayout( LayoutKind.Sequential)]

public struct PRINTERINFO2

{

[MarshalAs(UnmanagedType.LPWStr)]public string pServerName;

[MarshalAs(UnmanagedType.LPWStr)]public string pPrinterName;

[MarshalAs(UnmanagedType.LPWStr)]public string pShareName;

[MarshalAs(UnmanagedType.LPWStr)]public string pPortName;

[MarshalAs(UnmanagedType.LPWStr)]public string pDriverName;

[MarshalAs(UnmanagedType.LPWStr)]public string pComment;

[MarshalAs(UnmanagedType.LPWStr)]public string pLocation;

public DEVMODE pDevMode;

[MarshalAs(UnmanagedType.LPWStr)]public string pSepFile;

[MarshalAs(UnmanagedType.LPWStr)]public string pPrintProcessor;

[MarshalAs(UnmanagedType.LPWStr)]public string pDatatype;

[MarshalAs(UnmanagedType.LPWStr)]public string pParameters;

public SECURITY_DESCRIPTOR pSecurityDescriptor;

public long Attributes;

public long Priority;

public long DefaultPriority;

public long StartTime;

public long UntilTime;

public long Status;

public long cJobs;

public long AveragePPM;

}

[StructLayout( LayoutKind.Sequential)]

public struct SECURITY_DESCRIPTOR{

public byte Revision;

public byte Sbz1;

public long Control;

public long Owner;

public long Group;

public ACL sACL;

public ACL Dacl;

}

[StructLayout( LayoutKind.Sequential)]

public struct ACL{

public byte AclRevision;

public byte Sbz1;

public int AclSize;

public int AceCount;

public int Sbz2;

}



[StructLayout( LayoutKind.Sequential)]

public struct DEVMODE{

public string dmDeviceName;

public int dmSpecVersion;

public int dmDriverVersion;

public int dmSize;

public int dmDriverExtra;

public long dmFields;

public int dmOrientation;

public int dmPaperSize;

public int dmPaperLength;

public int dmPaperWidth;

public int dmScale;

public int dmCopies;

public int dmDefaultSource;

public int dmPrintQuality;

public int dmColor;

public int dmDuplex;

public int dmYResolution;

public int dmTTOption;

public int dmCollate;

public string dmFormName;

public int dmLogPixels;

public long dmBitsPerPel;

public long dmPelsWidth;

public long dmPelsHeight;

public long dmDisplayFlags;

public long dmDisplayFrequency;

public long dmICMMethod;

public long dmICMIntent;

public long dmMediaType;

public long dmDitherType;

public long dmReserved1;

public long dmReserved2;

}

in message news:%[email protected]...
Gordon,

What are the definitions you are using? The PRINTER_INFO_2 structure
has a lot of information (if you include the DEVMODE structure as well), and
there could be errors in how you are accessing it.

Can you show the definitions that you have?


--
- Nicholas Paldino [.NET/C# MVP]
- nick(dot)paldino=at=exisconsulting<dot>com

Gordon Truslove said:
Has anybody managed to get GetPrinter and PRINER_INFO_2 to work?
I would like to retrieve the printer status.
 
Well I'm getting closer. ifferent error this time

122 - The data area passed to a system call is too small.

[StructLayout( LayoutKind.Sequential,CharSet=CharSet.Auto)]

public struct PRINTERINFO2

{

[MarshalAs(UnmanagedType.LPTStr)]public string pServerName;

[MarshalAs(UnmanagedType.LPTStr)]public string pPrinterName;

[MarshalAs(UnmanagedType.LPTStr)]public string pShareName;

[MarshalAs(UnmanagedType.LPTStr)]public string pPortName;

[MarshalAs(UnmanagedType.LPTStr)]public string pDriverName;

[MarshalAs(UnmanagedType.LPTStr)]public string pComment;

[MarshalAs(UnmanagedType.LPTStr)]public string pLocation;

public IntPtr pDevMode;

[MarshalAs(UnmanagedType.LPTStr)]public string pSepFile;

[MarshalAs(UnmanagedType.LPTStr)]public string pPrintProcessor;

[MarshalAs(UnmanagedType.LPTStr)]public string pDatatype;

[MarshalAs(UnmanagedType.LPTStr)]public string pParameters;

public IntPtr pSecurityDescriptor;

public int Attributes;

public int Priority;

public int DefaultPriority;

public int StartTime;

public int UntilTime;

public int Status;

public int cJobs;

public int AveragePPM;

}

public class Printer

{

[ DllImport( "winspool.drv",CharSet=CharSet.Unicode,ExactSpelling=false,

CallingConvention=CallingConvention.StdCall )]

public static extern long OpenPrinter(string pPrinterName,ref IntPtr
phPrinter, int pDefault);

[ DllImport(

"winspool.drv",CharSet=CharSet.Unicode,ExactSpelling=true,

CallingConvention=CallingConvention.StdCall )]

public static extern long ClosePrinter(IntPtr hPrinter);

[ DllImport(

"winspool.drv" ,CharSet=CharSet.Auto)]

public static extern bool GetPrinter(IntPtr hPrinter,int Level,ref
PRINTERINFO2 pPrinter,int cbBuf,ref int pcbNeeded);

}

public class App

{

public static void Main ()

{

System.IntPtr lhPrinter=new System.IntPtr();

Printer.OpenPrinter("Epson EPL-5700",ref lhPrinter,0);

PRINTERINFO2 PI=new PRINTERINFO2();

int Need=0;

Console.WriteLine(Printer.GetPrinter(lhPrinter,2,ref
PI,Marshal.SizeOf(PI),ref Need));


Console.WriteLine("Error "+Marshal.GetLastWin32Error());


Printer.ClosePrinter(lhPrinter);

Console.ReadLine();

}

}
 
Well I'm getting closer. different error this time

122 - The data area passed to a system call is too small.

[StructLayout( LayoutKind.Sequential,CharSet=CharSet.Auto)]

public struct PRINTERINFO2

{

[MarshalAs(UnmanagedType.LPTStr)]public string pServerName;

[MarshalAs(UnmanagedType.LPTStr)]public string pPrinterName;

[MarshalAs(UnmanagedType.LPTStr)]public string pShareName;

[MarshalAs(UnmanagedType.LPTStr)]public string pPortName;

[MarshalAs(UnmanagedType.LPTStr)]public string pDriverName;

[MarshalAs(UnmanagedType.LPTStr)]public string pComment;

[MarshalAs(UnmanagedType.LPTStr)]public string pLocation;

public IntPtr pDevMode;

[MarshalAs(UnmanagedType.LPTStr)]public string pSepFile;

[MarshalAs(UnmanagedType.LPTStr)]public string pPrintProcessor;

[MarshalAs(UnmanagedType.LPTStr)]public string pDatatype;

[MarshalAs(UnmanagedType.LPTStr)]public string pParameters;

public IntPtr pSecurityDescriptor;

public int Attributes;

public int Priority;

public int DefaultPriority;

public int StartTime;

public int UntilTime;

public int Status;

public int cJobs;

public int AveragePPM;

}

public class Printer

{

[ DllImport( "winspool.drv",CharSet=CharSet.Unicode,ExactSpelling=false,

CallingConvention=CallingConvention.StdCall )]

public static extern long OpenPrinter(string pPrinterName,ref IntPtr
phPrinter, int pDefault);

[ DllImport(

"winspool.drv",CharSet=CharSet.Unicode,ExactSpelling=true,

CallingConvention=CallingConvention.StdCall )]

public static extern long ClosePrinter(IntPtr hPrinter);

[ DllImport(

"winspool.drv" ,CharSet=CharSet.Auto)]

public static extern bool GetPrinter(IntPtr hPrinter,int Level,ref
PRINTERINFO2 pPrinter,int cbBuf,ref int pcbNeeded);

}

public class App

{

public static void Main ()

{

System.IntPtr lhPrinter=new System.IntPtr();

Printer.OpenPrinter("Epson EPL-5700",ref lhPrinter,0);

PRINTERINFO2 PI=new PRINTERINFO2();

int Need=0;

Console.WriteLine(Printer.GetPrinter(lhPrinter,2,ref
PI,Marshal.SizeOf(PI),ref Need));


Console.WriteLine("Error "+Marshal.GetLastWin32Error());


Printer.ClosePrinter(lhPrinter);

Console.ReadLine();

}

}
 
Back
Top