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,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();
}
}
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]
- m...@spam.guard.caspershouse.com
"Gordon Truslove" <Gordon....@QCL-Solutions.com> wrote in message
news:%23GO4Xyv...@TK2MSFTNGP12.phx.gbl...
Thanks.
"Nicholas Paldino [.NET/C# MVP]" <m...@spam.guard.caspershouse.com> wrote in
message news:ecOkNTyk...@TK2MSFTNGP11.phx.gbl...
"Gordon Truslove" <Gordon....@QCL-Solutions.com> wrote in message
news:OnDHNyyk...@TK2MSFTNGP11.phx.gbl...