473,513 Members | 2,665 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Getting list of printer paper names / sizes: calling DeviceCapabilities from C#

I'm having a devil of a time calling DeviceCapabilities() in order to
get the list of paper names / codes / sizes for a printer. Here is my
code and the input it produces:

[DllImport("winspool.drv", SetLastError=true)]
static extern Int32 DeviceCapabilities(
[MarshalAs(UnmanagedType.LPTStr)] string device,
[MarshalAs(UnmanagedType.LPTStr)] string port,
Int16 capability,
out IntPtr outputBuffer,
[MarshalAs(UnmanagedType.LPStruct)] DEVMODE deviceMode);

[DllImport("winspool.drv", SetLastError=true)]
static extern Int32 DeviceCapabilities(
[MarshalAs(UnmanagedType.LPTStr)] string device,
[MarshalAs(UnmanagedType.LPTStr)] string port,
Int16 capability,
out IntPtr outputBuffer,
IntPtr deviceMode);

[DllImport("winspool.drv", SetLastError=true)]
static extern bool EnumPrintersW(Int32 flags,
[MarshalAs(UnmanagedType.LPTStr)] string printerName,
Int32 level, IntPtr buffer, Int32 bufferSize, out Int32
requiredBufferSize, out Int32 numPrintersReturned);

public static PaperInfo[] GetDefinedPapers(string printerName)
{
PRINTER_INFO_5 info5;
int requiredSize;
int numPrinters;
bool foundPrinter = EnumPrintersW(PRINTER_ENUM_LOCAL |
PRINTER_ENUM_CONNECTIONS, printerName, 5, (IntPtr)null, 0, out
requiredSize, out numPrinters);
Console.WriteLine("Required size is: {0}", requiredSize);
int info5Size = requiredSize;
IntPtr info5Ptr = Marshal.AllocHGlobal(info5Size);
try
{
foundPrinter = EnumPrintersW(PRINTER_ENUM_LOCAL |
PRINTER_ENUM_CONNECTIONS, printerName, 5, info5Ptr, info5Size, out
requiredSize, out numPrinters);
Console.WriteLine("Size: {0}, required size: {1}, num printers:
{2}", info5Size, requiredSize, numPrinters);
string port = null;
for (int i = 0; i < numPrinters; i++)
{
info5 = (PRINTER_INFO_5)Marshal.PtrToStructure((IntPtr)((i *
Marshal.SizeOf(typeof(PRINTER_INFO_5))) + (int)info5Ptr),
typeof(PRINTER_INFO_5));
if (info5.PrinterName == printerName)
{
port = info5.PortName;
}
Console.WriteLine("Printer: '{0}', Port:'{1}'", info5.PrinterName,
info5.PortName);
}
IntPtr buffer;
int numNames = DeviceCapabilities(printerName, port, DC_PAPERNAMES,
out buffer, (IntPtr)null);
if (numNames < 0)
{
int errorCode = GetLastError();
IntPtr bufferPtr;
FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM, (IntPtr)null, errorCode,
GetUserDefaultLangID(), out bufferPtr, 0, (IntPtr)null);
string errorMessage = Marshal.PtrToStringUni(bufferPtr);
Console.WriteLine("Number of names = {2}: {0} / {1}", errorCode,
errorMessage, numNames);
return new PaperInfo[0];
}
string[] names = new string[numNames];
for (int i = 0; i < numNames; i++)
{
names[i] = Marshal.PtrToStringAuto((IntPtr)((i * 64) +
(int)buffer), 64);
}
int numPapers = DeviceCapabilities(printerName, port, DC_PAPERS,
out buffer, (IntPtr)null);
if (numPapers < 0)
{
Console.WriteLine("No papers");
return new PaperInfo[0];
}
short[] kinds = new short[numPapers];
for (int i = 0; i < numPapers; i++)
{
kinds[i] = Marshal.ReadInt16(buffer, i * 16);
}
int numSizes = DeviceCapabilities(printerName, port, DC_PAPERSIZE,
out buffer, (IntPtr)null);
if (numSizes < 0)
{
Console.WriteLine("No sizes");
return new PaperInfo[0];
}
int[] widths = new int[numSizes];
int[] heights = new int[numSizes];
for (int i = 0; i < numSizes; i++)
{
widths[i] = Marshal.ReadInt32(buffer, i * 64);
heights[i] = Marshal.ReadInt32(buffer, i * 64 + 32);
}

int finalSize = Math.Min(Math.Min(numNames, numPapers), numSizes);
PaperInfo[] result = new PaperInfo[finalSize];
for (int i = 0; i < finalSize; i++)
{
result[i] = new PaperInfo(names[i], kinds[i], widths[i],
heights[i]);
}
return result;
}
finally
{
Marshal.FreeHGlobal(info5Ptr);
}
}

The output from this method is:

Required size is: 444
Size: 444, required size: 444, num printers: 4
Printer: 'Zebra IS', Port:'IP_xxx.xxx.xxx.xxx'
Printer: 'Zebra 105SL (200dpi)', Port:'IP_yyy.yyy.yyy.yyy'
Printer: 'Microsoft Office Live Meeting Document Writer',
Port:'Microsoft Office Live Meeting Document Writer Port:'
Printer: 'Main IS', Port:'zzz.zzz.zzz.zzz'
Number of names = -1: 126 / The specified module could not be found.

Does anyone know why the call to DeviceCapabilities() fails with a
LastError indicating "The specified module could not be found"? Do I
have to load the device driver first, or something? The printer and
port name I am passing to DeviceCapabilities is the correct one.

Nov 17 '05 #1
1 11847
Hi Bruce

Have been successful in fixing the problem
I am also having the same problem with devicecapabilities.
Can you let me know what you found.

thanks.
Iyyengar.

"Bruce Wood" wrote:
I'm having a devil of a time calling DeviceCapabilities() in order to
get the list of paper names / codes / sizes for a printer. Here is my
code and the input it produces:

[DllImport("winspool.drv", SetLastError=true)]
static extern Int32 DeviceCapabilities(
[MarshalAs(UnmanagedType.LPTStr)] string device,
[MarshalAs(UnmanagedType.LPTStr)] string port,
Int16 capability,
out IntPtr outputBuffer,
[MarshalAs(UnmanagedType.LPStruct)] DEVMODE deviceMode);

[DllImport("winspool.drv", SetLastError=true)]
static extern Int32 DeviceCapabilities(
[MarshalAs(UnmanagedType.LPTStr)] string device,
[MarshalAs(UnmanagedType.LPTStr)] string port,
Int16 capability,
out IntPtr outputBuffer,
IntPtr deviceMode);

[DllImport("winspool.drv", SetLastError=true)]
static extern bool EnumPrintersW(Int32 flags,
[MarshalAs(UnmanagedType.LPTStr)] string printerName,
Int32 level, IntPtr buffer, Int32 bufferSize, out Int32
requiredBufferSize, out Int32 numPrintersReturned);

public static PaperInfo[] GetDefinedPapers(string printerName)
{
PRINTER_INFO_5 info5;
int requiredSize;
int numPrinters;
bool foundPrinter = EnumPrintersW(PRINTER_ENUM_LOCAL |
PRINTER_ENUM_CONNECTIONS, printerName, 5, (IntPtr)null, 0, out
requiredSize, out numPrinters);
Console.WriteLine("Required size is: {0}", requiredSize);
int info5Size = requiredSize;
IntPtr info5Ptr = Marshal.AllocHGlobal(info5Size);
try
{
foundPrinter = EnumPrintersW(PRINTER_ENUM_LOCAL |
PRINTER_ENUM_CONNECTIONS, printerName, 5, info5Ptr, info5Size, out
requiredSize, out numPrinters);
Console.WriteLine("Size: {0}, required size: {1}, num printers:
{2}", info5Size, requiredSize, numPrinters);
string port = null;
for (int i = 0; i < numPrinters; i++)
{
info5 = (PRINTER_INFO_5)Marshal.PtrToStructure((IntPtr)((i *
Marshal.SizeOf(typeof(PRINTER_INFO_5))) + (int)info5Ptr),
typeof(PRINTER_INFO_5));
if (info5.PrinterName == printerName)
{
port = info5.PortName;
}
Console.WriteLine("Printer: '{0}', Port:'{1}'", info5.PrinterName,
info5.PortName);
}
IntPtr buffer;
int numNames = DeviceCapabilities(printerName, port, DC_PAPERNAMES,
out buffer, (IntPtr)null);
if (numNames < 0)
{
int errorCode = GetLastError();
IntPtr bufferPtr;
FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM, (IntPtr)null, errorCode,
GetUserDefaultLangID(), out bufferPtr, 0, (IntPtr)null);
string errorMessage = Marshal.PtrToStringUni(bufferPtr);
Console.WriteLine("Number of names = {2}: {0} / {1}", errorCode,
errorMessage, numNames);
return new PaperInfo[0];
}
string[] names = new string[numNames];
for (int i = 0; i < numNames; i++)
{
names[i] = Marshal.PtrToStringAuto((IntPtr)((i * 64) +
(int)buffer), 64);
}
int numPapers = DeviceCapabilities(printerName, port, DC_PAPERS,
out buffer, (IntPtr)null);
if (numPapers < 0)
{
Console.WriteLine("No papers");
return new PaperInfo[0];
}
short[] kinds = new short[numPapers];
for (int i = 0; i < numPapers; i++)
{
kinds[i] = Marshal.ReadInt16(buffer, i * 16);
}
int numSizes = DeviceCapabilities(printerName, port, DC_PAPERSIZE,
out buffer, (IntPtr)null);
if (numSizes < 0)
{
Console.WriteLine("No sizes");
return new PaperInfo[0];
}
int[] widths = new int[numSizes];
int[] heights = new int[numSizes];
for (int i = 0; i < numSizes; i++)
{
widths[i] = Marshal.ReadInt32(buffer, i * 64);
heights[i] = Marshal.ReadInt32(buffer, i * 64 + 32);
}

int finalSize = Math.Min(Math.Min(numNames, numPapers), numSizes);
PaperInfo[] result = new PaperInfo[finalSize];
for (int i = 0; i < finalSize; i++)
{
result[i] = new PaperInfo(names[i], kinds[i], widths[i],
heights[i]);
}
return result;
}
finally
{
Marshal.FreeHGlobal(info5Ptr);
}
}

The output from this method is:

Required size is: 444
Size: 444, required size: 444, num printers: 4
Printer: 'Zebra IS', Port:'IP_xxx.xxx.xxx.xxx'
Printer: 'Zebra 105SL (200dpi)', Port:'IP_yyy.yyy.yyy.yyy'
Printer: 'Microsoft Office Live Meeting Document Writer',
Port:'Microsoft Office Live Meeting Document Writer Port:'
Printer: 'Main IS', Port:'zzz.zzz.zzz.zzz'
Number of names = -1: 126 / The specified module could not be found.

Does anyone know why the call to DeviceCapabilities() fails with a
LastError indicating "The specified module could not be found"? Do I
have to load the device driver first, or something? The printer and
port name I am passing to DeviceCapabilities is the correct one.

Nov 17 '05 #2

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

303
17421
by: mike420 | last post by:
In the context of LATEX, some Pythonista asked what the big successes of Lisp were. I think there were at least three *big* successes. a. orbitz.com web site uses Lisp for algorithms, etc. b....
0
1238
by: Kevin | last post by:
I'm trying to convert my VB6 program to VB2005. In my VB6 program I'm able to retrieve the paper bins for the selected printer and set the bin when printing. I'm using the DeviceCapabilities API...
2
3978
by: anniec | last post by:
Hi, I've got a Zebra 110XIIIPlus and I've made a barcode software in A2K. I need to be able to print 4 different size of barcode... all in 4'' widht. My problem is that all label are being...
7
2029
by: Jean Paul Mertens | last post by:
Hello, Is there a way to send a string of text to a generic tekst printer under ..NET. Somethings as in the good old days File f = Open("LPT1"); f.Writeline("Blablabla"); The goal is to use...
1
4820
by: Ed Sutton | last post by:
My C# app. apparently has problems with PageSettings not being initialized properly after calling PageSetupDialog. If a user selects a non-default printer from PageSetupDialog, the PageSize is...
0
1529
by: Academic | last post by:
I posted this in the vb group but it is a pretty esoteric question and I did not get a reply. I'm hoping someone here has some experience generating custom printer forms. If I generate a new...
6
9742
by: Ian | last post by:
I am trying to get MS Access 2000 to print names and addresses onto a Dymo 400 label printer, I have set the Access Report to automatically select the correct printer, then select the label size of...
7
6025
by: ARC | last post by:
Hello all, What's the proper paper size setting if you want to do a receipt printer report, that's a continuous form? I don't really see an option for a continuous paper size. Thanks! Andy
23
11408
by: Al Grant | last post by:
I have a 'printable' button to generate printable output and want this to use A3 if available, irrespective of the user's default printer setting. Is there any way to set a page's preferred...
0
7157
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
7379
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
7535
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
1
7098
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
7521
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
1
5084
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
3232
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
3221
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
798
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.