By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
457,954 Members | 1,248 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 457,954 IT Pros & Developers. It's quick & easy.

How do i get the printer status

P: n/a
I've been trying to get the printer status using GetPrinter and
Printer_Info_2

I'm getting closer, but it still fails.

Error 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,ExactSpelli ng=false,

CallingConvention=CallingConvention.StdCall )]

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

[ DllImport(

"winspool.drv",CharSet=CharSet.Unicode,ExactSpelli ng=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,r ef
PI,Marshal.SizeOf(PI),ref Need));
Console.WriteLine("Error "+Marshal.GetLastWin32Error());
Printer.ClosePrinter(lhPrinter);

Console.ReadLine();

}

}


Nov 15 '05 #1
Share this Question
Share on Google+
3 Replies


P: n/a
Gordon,

Looking into this some more, the correct way to call GetPrinter is to
first make a call to see how big the buffer will be for the call.
Apparently, the pointers in the structure point to the areas right after the
structure itself. Because of this, you will have to take a different
approach.

First, you will have to find out how much memory you need. You do that
with a call to GetPrinter initially:

// Get the number of bytes needed.
Printer.GetPrinter(lhPrinter, 2, IntPtr.Zero, 0, ref Need);

Notice that I changed the declaration of the function so that the third
parameter takes an IntPtr. At this point, Need should have the number of
bytes needed. You can then allocate the memory needed.

// Allocate that in unmanaged memory.
IntPtr pintStruct = Marshal.AllocCoTaskMem(Need);

At this point, you can call GetPrinter again, getting the information:

// Now make the call again and get the bytes in memory.
int SizeOf = Need;
Printer.GetPrinter(lhPrinter, 2, pintStruct, SizeOf, ref Need);

Now you can marshal the structure from unmanaged memory:

// Now marshal the structure manually.
PI = (PRINTERINFO2) Marshal.PtrToStructure(pintStruct,
typeof(PRINTERINFO2));

At this point, all you have to do is free the unmanaged memory:

// Deallocate the memory.
Marshal.FreeCoTaskMem(pintStruct);

Mind you there is no error handling in this code. I'll leave that to
you.

Hope this helps.

--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"Gordon Truslove" <Go*************@QCL-Solutions.com> wrote in message
news:%2****************@TK2MSFTNGP12.phx.gbl...
I've been trying to get the printer status using GetPrinter and
Printer_Info_2

I'm getting closer, but it still fails.

Error 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,ExactSpelli ng=false,

CallingConvention=CallingConvention.StdCall )]

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

[ DllImport(

"winspool.drv",CharSet=CharSet.Unicode,ExactSpelli ng=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,r ef
PI,Marshal.SizeOf(PI),ref Need));
Console.WriteLine("Error "+Marshal.GetLastWin32Error());
Printer.ClosePrinter(lhPrinter);

Console.ReadLine();

}

}

Nov 15 '05 #2

P: n/a
Great. I'm getting there. You can only check the status when the printer is
trying to print. Otherwise you just get status=0. So i'm working on some
kind of monitoring sysytem now.

Thanks.

"Nicholas Paldino [.NET/C# MVP]" <mv*@spam.guard.caspershouse.com> wrote in
message news:ec**************@TK2MSFTNGP11.phx.gbl...
Gordon,

Looking into this some more, the correct way to call GetPrinter is to
first make a call to see how big the buffer will be for the call.
Apparently, the pointers in the structure point to the areas right after the structure itself. Because of this, you will have to take a different
approach.

First, you will have to find out how much memory you need. You do that with a call to GetPrinter initially:

// Get the number of bytes needed.
Printer.GetPrinter(lhPrinter, 2, IntPtr.Zero, 0, ref Need);

Notice that I changed the declaration of the function so that the third parameter takes an IntPtr. At this point, Need should have the number of
bytes needed. You can then allocate the memory needed.

// Allocate that in unmanaged memory.
IntPtr pintStruct = Marshal.AllocCoTaskMem(Need);

At this point, you can call GetPrinter again, getting the information:

// Now make the call again and get the bytes in memory.
int SizeOf = Need;
Printer.GetPrinter(lhPrinter, 2, pintStruct, SizeOf, ref Need);

Now you can marshal the structure from unmanaged memory:

// Now marshal the structure manually.
PI = (PRINTERINFO2) Marshal.PtrToStructure(pintStruct,
typeof(PRINTERINFO2));

At this point, all you have to do is free the unmanaged memory:

// Deallocate the memory.
Marshal.FreeCoTaskMem(pintStruct);

Mind you there is no error handling in this code. I'll leave that to
you.

Hope this helps.

--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"Gordon Truslove" <Go*************@QCL-Solutions.com> wrote in message
news:%2****************@TK2MSFTNGP12.phx.gbl...
I've been trying to get the printer status using GetPrinter and
Printer_Info_2

I'm getting closer, but it still fails.

Error 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,ExactSpelli ng=false,

CallingConvention=CallingConvention.StdCall )]

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

[ DllImport(

"winspool.drv",CharSet=CharSet.Unicode,ExactSpelli ng=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,r ef
PI,Marshal.SizeOf(PI),ref Need));
Console.WriteLine("Error "+Marshal.GetLastWin32Error());
Printer.ClosePrinter(lhPrinter);

Console.ReadLine();

}

}


Nov 15 '05 #3

P: n/a
OK if anybody ever needs this. You can check the status by using
job=StartDocPrinter then StartPagePrinter then getprinter which will return
a status code, you can then remove the job usint setjob. This doesn't work
if another app has queued a job before this one.

"Gordon Truslove" <Go*************@QCL-Solutions.com> wrote in message
news:On**************@TK2MSFTNGP11.phx.gbl...
Great. I'm getting there. You can only check the status when the printer is trying to print. Otherwise you just get status=0. So i'm working on some
kind of monitoring sysytem now.

Thanks.

"Nicholas Paldino [.NET/C# MVP]" <mv*@spam.guard.caspershouse.com> wrote in message news:ec**************@TK2MSFTNGP11.phx.gbl...
Gordon,

Looking into this some more, the correct way to call GetPrinter is to first make a call to see how big the buffer will be for the call.
Apparently, the pointers in the structure point to the areas right after

the
structure itself. Because of this, you will have to take a different
approach.

First, you will have to find out how much memory you need. You do

that
with a call to GetPrinter initially:

// Get the number of bytes needed.
Printer.GetPrinter(lhPrinter, 2, IntPtr.Zero, 0, ref Need);

Notice that I changed the declaration of the function so that the

third
parameter takes an IntPtr. At this point, Need should have the number of bytes needed. You can then allocate the memory needed.

// Allocate that in unmanaged memory.
IntPtr pintStruct = Marshal.AllocCoTaskMem(Need);

At this point, you can call GetPrinter again, getting the information:
// Now make the call again and get the bytes in memory.
int SizeOf = Need;
Printer.GetPrinter(lhPrinter, 2, pintStruct, SizeOf, ref Need);

Now you can marshal the structure from unmanaged memory:

// Now marshal the structure manually.
PI = (PRINTERINFO2) Marshal.PtrToStructure(pintStruct,
typeof(PRINTERINFO2));

At this point, all you have to do is free the unmanaged memory:

// Deallocate the memory.
Marshal.FreeCoTaskMem(pintStruct);

Mind you there is no error handling in this code. I'll leave that to you.

Hope this helps.

--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"Gordon Truslove" <Go*************@QCL-Solutions.com> wrote in message
news:%2****************@TK2MSFTNGP12.phx.gbl...
I've been trying to get the printer status using GetPrinter and
Printer_Info_2

I'm getting closer, but it still fails.

Error 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,ExactSpelli ng=false,
CallingConvention=CallingConvention.StdCall )]

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

[ DllImport(

"winspool.drv",CharSet=CharSet.Unicode,ExactSpelli ng=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,r ef
PI,Marshal.SizeOf(PI),ref Need));
Console.WriteLine("Error "+Marshal.GetLastWin32Error());
Printer.ClosePrinter(lhPrinter);

Console.ReadLine();

}

}



Nov 15 '05 #4

This discussion thread is closed

Replies have been disabled for this discussion.