Board index » delphi » get printer ports assigned to printers

get printer ports assigned to printers

I know how to get a list of all available printers (including
network printers) with printer.printers.  Is there an easy way
to get the printer ports assigned to these printers?  

(The printer port is under Network, right click on a printer,
"capture printer port").

Jud McCranie

 

Re:get printer ports assigned to printers


Quote
Jud McCranie wrote:
>I know how to get a list of all available printers (including
>network printers) with printer.printers.  Is there an easy way
>to get the printer ports assigned to these printers?  

>(The printer port is under Network, right click on a printer,
>"capture printer port").

Use Win32-API function EnumPrinters with PRINTER_INFO_2 which has a
PortName property.

Cheers,
Udo
--
Contact:  mailto:newsgroup.re...@gmx.net
Reply to newsgroup. Unrequested mails will be ignored.

Re:get printer ports assigned to printers


Quote
Udo Nesshoever <this.will.be.dele...@gmx.net> wrote:
>Use Win32-API function EnumPrinters with PRINTER_INFO_2 which has a
>PortName property.

OK, but I don't know how to call an API from Delphi.  For
instance, what do you have to add to uses statement?  What are
these data types (LPTSTR, LPByte, LPDWORD), just string, byte,
and cardinal?

BOOL EnumPrinters(

    DWORD Flags,        // types of printer objects to enumerate
    LPTSTR Name,        // name of printer object
    DWORD Level,        // specifies type of printer info
structure
    LPBYTE pPrinterEnum,        // pointer to buffer to receive
printer info structures
    DWORD cbBuf,        // size, in bytes, of array
    LPDWORD pcbNeeded,  // pointer to variable with no. of bytes
copied (or required)
    LPDWORD pcReturned  // pointer to variable with no. of
printer info. structures copied
   );

Jud McCranie

Re:get printer ports assigned to printers


Quote
"Jud McCranie" <jud.mccra...@mindspring.com> wrote in message

news:e793qso49ugvg3tqcup1p9d989u7sa7s8b@4ax.com...

Quote
> I know how to get a list of all available printers (including
> network printers) with printer.printers.  Is there an easy way
> to get the printer ports assigned to these printers?

> (The printer port is under Network, right click on a printer,
> "capture printer port").

The port name is typically at the end of the printer description, e.g. HP
LaserJet 4 on LPT1:.

function PortNameFromPrinterDescription (pDesc : string) : string;

var    i        : integer;

begin
if (pDesc = '') or (pDesc [Length (pDesc)]) <> ':'
then result := ''
else begin
    i := Length (pDesc) - 1;
    while (i > 0) and (pDesc [i] <> ' ') do
        dec (i);
    if i > 0
    then result := copy (pDesc, i + 1, 99)
    else result := pDesc;
    end;
end;

Usage:
    portName := PortNameFromPrinterDescription (Printer.Printers [index]);

Re:get printer ports assigned to printers


In article <9fc6qs03gq8b27444acfm8alj8l7dp0...@4ax.com>, Jud McCranie

Quote
<jud.mccra...@mindspring.com> writes:
>OK, but I don't know how to call an API from Delphi.  For
>instance, what do you have to add to uses statement?  What are
>these data types (LPTSTR, LPByte, LPDWORD), just string, byte,
>and cardinal?

Jud

If you do an Advanced search in the Delphi Source folder for "n EnumPrinters("
(adding "n" and "(" because it is a function) you will find the Delphi
declaration in a file (WinSpool.pas, which "WinSpool" you must add to the uses
clause) open that in WordPad and search again and you will find the Delphi
declaration for the API :-

function EnumPrinters(Flags: DWORD; Name: PChar; Level: DWORD;
  pPrinterEnum: Pointer; cbBuf: DWORD; var pcbNeeded, pcReturned: DWORD): BOOL;
stdcall;

PChar is a "pointer to a string", which "string" will be a number of characters
followed by a 0 value byte. Delphi will convert between strings and PChars by
type casting. The declaration for TPrinterInfo2 in the same file gives you the
Delphi types of the returned info.

You have to allocate memory enough for one buffer (of type TPrinterInfo2) and
call the API. If it fails with pcbNeeded > you have allocated, re-allocate the
memory to pcbNeeded and re-call.

pcReturned will indicate the number of TPrinterInfo2 records which have been
returned. If this is > 1, you have to step through these, incrementing
PPrinterInfo2 by SizeOf(TPrinterInfo2) and extract the information you require.

With APIs you have to be somewhat of a mind reader and consider the effect on
your calling activities of _all_ the possible meanings of the description <gg>.
MS API descriptions appear to be for those who know how it works and just need
a reminder <g>. They are seldom _wrong_, they just rarely supply all the
information you require in a clear description.

Alan Lloyd
alangll...@aol.com

Re:get printer ports assigned to printers


On 23 Aug 2000 06:35:33 GMT, alangll...@aol.com (AlanGLLoyd) wrote
really good advice, except for one thing:

Quote
> you will find the Delphi
>declaration in a file (WinSpool.pas, which "WinSpool" you must add to the uses
>clause) open that in WordPad and search again and you will find the Delphi
>declaration for the API :-

WordPad!?  Are you nuts?  That piece of %^&% should be deleted from
your disk.  Use an editor that works, like Delphi, for instance.

Duncan Murdoch

Re:get printer ports assigned to printers


Quote
"Bruce Roberts" <no.junk.please....@attcanada.net> wrote:
>> I know how to get a list of all available printers (including
>> network printers) with printer.printers.  Is there an easy way
>> to get the printer ports assigned to these printers?

>> (The printer port is under Network, right click on a printer,
>> "capture printer port").

>The port name is typically at the end of the printer description, e.g. HP
>LaserJet 4 on LPT1:.

But not if it is a network printer (at least not on my network
and the other 2 I tried).

Jud McCranie

Re:get printer ports assigned to printers


Quote
Jud McCranie <jud.mccra...@mindspring.com> wrote:
>>The port name is typically at the end of the printer description, e.g. HP
>>LaserJet 4 on LPT1:.

>But not if it is a network printer (at least not on my network
>and the other 2 I tried).

Also if the printer is on a USB port, it doesn't have LPTx: (and
I assume that it doesn't have LPT for a COM port either).

Jud McCranie

Re:get printer ports assigned to printers


Quote
alangll...@aol.com (AlanGLLoyd) wrote:
>If you do an Advanced search in the Delphi Source folder for "n EnumPrinters("
>(adding "n" and "(" because it is a function) you will find the Delphi
>declaration in a file (WinSpool.pas, which "WinSpool" you must add to the uses
>clause) open that in WordPad and search again and you will find the Delphi
>declaration for the API :-

Thanks, I think that will help me a lot and enable me to do it.

...

Quote
>With APIs you have to be somewhat of a mind reader and consider the effect on
>your calling activities of _all_ the possible meanings of the description <gg>.
>MS API descriptions appear to be for those who know how it works and just need
>a reminder <g>. They are seldom _wrong_, they just rarely supply all the
>information you require in a clear description.

You seem to be absolutely right about all you said!

Jud McCranie

Re:get printer ports assigned to printers


Quote
alangll...@aol.com (AlanGLLoyd) wrote:

>function EnumPrinters(Flags: DWORD; Name: PChar; Level: DWORD;
>  pPrinterEnum: Pointer; cbBuf: DWORD; var pcbNeeded, pcReturned: DWORD): BOOL;

Thanks, I've almost got it working.  The problem is that it
isn't seeing network printers (on my W98 network).  I'm using
PRINTER_ENUM_LOCAL or PRINTER_ENUM_SHARED.  One computer that
has a local printer and should see a network printer sees only
the local printer and another one that should see 2 network
printers doesn't see any.  Here's my code:

type buf = array[ 0 .. 4095] of char;

var cbBuf,
    flags,
    level,
    pcbNeeded,
    pcReturned : dword;
    name : pChar;
    buffer : buf;
    pPrinterEnum : ^buf;
    PrtInfo : TPrinterInfo2;
    PrtStr : string;
begin
flags := PRINTER_ENUM_LOCAL or PRINTER_ENUM_SHARED;
name  := '';
level := 2;
cbBuf := 4096;
pPrinterEnum := @Buffer;

EnumPrinters( flags, name, level, pPrinterEnum, cbBuf,
                 pcbNeeded, pcReturned);

// pcbNeeded = 452, pcReturned = 1
// sizeof( TPrinterInfo2) = 84

move( buffer, PrtInfo, SizeOf( PrtInfo));

with PrtInfo do
PrtStr := IntToStr( pcReturned) + '  ' +
         string( pPrinterName) + ' ' + string( pPortName);

Jud McCranie

Re:get printer ports assigned to printers


In article <39a3bc6d.234...@newshost.uwo.ca>, dmurd...@pair.com (Duncan

Quote
Murdoch) writes:
>WordPad!?  Are you nuts?  That piece of %^&% should be deleted from
>your disk.  Use an editor that works, like Delphi, for instance.

I dont want an editor, and I don't want it to "work", one needs only a simple
viewer at that point with select/copy-to-clipboard. The Find results window is
already on-top, its quicker to select, (right-click and select Send To), its
quicker to open, and has a find facility. I can look at the declaration, get it
on the clip-board and close WordPad while you're looking for the file in the
Delphi Editor File Open dialog. Its just a better tool for that particular job.

Alan Lloyd
alangll...@aol.com

Re:get printer ports assigned to printers


In article <jdr8qskq6bdvofdi2ov9nunhi8s50e0...@4ax.com>, Jud McCranie

Quote
<jud.mccra...@mindspring.com> writes:
>Thanks, I've almost got it working.  The problem is that it
>isn't seeing network printers (on my W98 network).  I'm using
>PRINTER_ENUM_LOCAL or PRINTER_ENUM_SHARED.  One computer that
>has a local printer and should see a network printer sees only
>the local printer and another one that should see 2 network
>printers doesn't see any.  Here's my code:

Your code looks OK AFAICS. There is an oddity that 452 bytes are needed but
only one lot of info of 84 bytes is returned. I wonder what's in the other 368
bytes ? Have you looked ?

Have you tried using only PRINTER_ENUM_LOCAL. MSDN says :-

"PRINTER_ENUM_LOCAL The function ignores the Name parameter, and enumerates the
locally installed printers.
Windows 95: The function will also enumerate network printers because they are
handled by the local print provider."

and

"PRINTER_ENUM_SHARED The function enumerates printers that have the shared
attribute. Cannot be used in isolation; use an OR operation to combine with
another PRINTER_ENUM type."

Alan Lloyd
alangll...@aol.com

Re:get printer ports assigned to printers


On 24 Aug 2000 05:07:05 GMT, alangll...@aol.com (AlanGLLoyd) wrote:

Quote
>In article <39a3bc6d.234...@newshost.uwo.ca>, dmurd...@pair.com (Duncan
>Murdoch) writes:

>>WordPad!?  Are you nuts?  That piece of %^&% should be deleted from
>>your disk.  Use an editor that works, like Delphi, for instance.

>I dont want an editor, and I don't want it to "work", one needs only a simple
>viewer at that point with select/copy-to-clipboard. The Find results window is
>already on-top, its quicker to select, (right-click and select Send To), its
>quicker to open, and has a find facility. I can look at the declaration, get it
>on the clip-board and close WordPad while you're looking for the file in the
>Delphi Editor File Open dialog. Its just a better tool for that particular job.

You don't need to use the File Open dialog to open a file -- you can
just drag it from the Find results window into an open Delphi editor
window.  That's really quick, and then you get all the benefits of the
IDE for navigating through the file.

It's also really easy to add a good editor/viewer to the Send To menu,
if you prefer that:  just set up a shortcut in \Windows\SendTo.  (I
wouldn't do this with Delphi, since it is so slow to load, but there
are about a million text editors that work better than WordPad.
Actually, there might be a command line option in Delphi that tells it
to load the file into the currently running copy, rather than starting
a new one; if so, that would be nearly as quick as the drag and drop
method.)

Duncan Murdoch

Go to page: [1] [2]

Other Threads