Interop - EnumPrintProcessors

K

Keith M

Could some kind soul illustrate how I can call the EnumPrintProcessors Win32
API from c# code?

BOOL EnumPrintProcessors(
LPTSTR pName, // print server name
LPTSTR pEnvironment, // environment name
DWORD Level, // information level
LPBYTE pPrintProcessorInfo, // processor data buffer
DWORD cbBuf, // size of data buffer
LPDWORD pcbNeeded, // bytes received or required
LPDWORD pcReturned // number of processors
);I am having particular trouble with the pPrintProcessorInfo parameter.

This is defined as an LPBYTE and will eventually end up with an array of
PRINTPROCESSOR_INFO_1 structures within it.

I cant quite translate this concept into C#

Thanks for any assistance, I have been trawling round msdn and the net to
little avail.
 
N

Nicholas Paldino [.NET/C# MVP]

Keith,

Assuming that the definition here is correct, this is how I would
translate it:

[DllImport("dll name", CharSet=CharSet.Auto)]
static extern bool EnumPrintProcessors(
string pName,
string pEnvironment,
[MarshalAs(UnmanagedType.U4)]
int Level,
IntPtr pPrintProcessorInfo,
[MarshalAs(UnmanagedType.U4)]
int cbBuf,
[MarshalAs(UnmanagedType.U4)]
ref int pcbNeeded,
[MarshalAs(UnmanagedType.U4)]
ref int pcReturned);

The reason for the cbBuf parameter being declared as IntPtr is that the
P/Invoke layer can not marshal values back for c-style arrays (it will only
marshal back the first element). In order to make this work, you will have
to allocate unmanaged memory (through the static methods on the Marshal
class) and then pass that IntPtr through to the function. Upon return, you
can use the static PtrToStructure method on the Marshal class to get the
managed representation of the structure. Then, you have to release the
unmanaged memory.

You can also use unsafe code to do this, but it would be hard to
recommend how without seeing the structure of the PRINTPROCESSOR_INFO_1
structure.

Hope this helps.
 
W

Willy Denoyette [MVP]

Keith M said:
Could some kind soul illustrate how I can call the EnumPrintProcessors
Win32
API from c# code?

BOOL EnumPrintProcessors(
LPTSTR pName, // print server name
LPTSTR pEnvironment, // environment name
DWORD Level, // information level
LPBYTE pPrintProcessorInfo, // processor data buffer
DWORD cbBuf, // size of data buffer
LPDWORD pcbNeeded, // bytes received or required
LPDWORD pcReturned // number of processors
);I am having particular trouble with the pPrintProcessorInfo parameter.

This is defined as an LPBYTE and will eventually end up with an array of
PRINTPROCESSOR_INFO_1 structures within it.

I cant quite translate this concept into C#

Thanks for any assistance, I have been trawling round msdn and the net to
little avail.

Why using PInvoke when it's that easy to do using System.Management and WMI
classes.
Herewith a small sample...

using System.Management ;
....
GetPropPrinter("somePrinterDevice"); // UNC path or local printer name

static int GetPropPrinter(string printerDevice)
{
string path = "win32_printer.DeviceId='" + printerDevice + "'";
using (ManagementObject printer = new ManagementObject(path))
{
printer.Get();
PropertyDataCollection printerProperties = printer.Properties;
foreach (PropertyData printerProperty in printerProperties ) {
if(printerProperty.Value !=null) // Show only non-null property values
Console.WriteLine("Property = {0}\t Value = {1}",
printerProperty.Name, printerProperty.Value);
}
}
}

Willy.
 
K

Keith M

Thanks for that. the PtrToStructure call would seem to be appropriate.

Unfortunately I cant see how to use it with an array of structures,
allocated as an array of bytes, coming back in.

From the documentation:
"The buffer must be large enough to receive the array of structures and any
strings to which the structure members point. "

So if I got back an array with 2 structures represented within, how would I
get them into two PRINTPROCESSOR_INFO_1
structures?

PRINTPROCESSOR_INFO_1 by the way is defined thus:

typedef struct _PRINTPROCESSOR_INFO_1
{
LPTSTR pName;
}


Thanks
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

EnumMonitors in c# 3
managed and unmanaged code 1
A IP Control 2
Revealing The Power of DirectX 11 1
Asp.net Important Topics. 0

Top