ACC2000: Enumerating Local and Network Printers
ID: Q200611
|
The information in this article applies to:
SUMMARYAdvanced: Requires expert coding, interoperability, and multiuser skills.
This article shows you two procedures that use the EnumPrinters API
function to retrieve a list of printers available locally and also those printers on a network that may be connected to your computer.
The procedures demonstrate returning data to both the PRINTER_INFO_1
structure and the PRINTER_INFO_4 structure, each of which provides slightly
different information about the printer. If you are using Microsoft
Windows 95 or later, you can return data to the PRINTER_INFO_1 structure;
if you are using Microsoft Windows NT, you can return data to either
structure.
MORE INFORMATIONMicrosoft provides programming examples for illustration only, without warranty
either expressed or implied, including, but not limited to, the implied warranties of
merchantability and/or fitness for a particular purpose. This article assumes that you
are familiar with the programming language being demonstrated and the tools used to
create and debug procedures. Microsoft support professionals can help explain the functionality
of a particular procedure, but they will not modify these examples to provide added
functionality or construct procedures to meet your specific needs. If you have limited
programming experience, you may want to contact a Microsoft Certified Solution Provider
or the Microsoft fee-based consulting line at (800) 936-5200. For more information about
Microsoft Certified Solution Providers, please see the following page on the World Wide Web:
http://www.microsoft.com/mcsp/
For more information about the support options available from Microsoft, please see the
following page on the World Wide Web:
http://www.microsoft.com/support/supportnet/overview/overview.asp
The code in each of the two examples performs these steps:
- Calls the EnumPrinters API, which returns a buffer of data, a success flag, and a flag indicating whether the buffer is too small.
- If the buffer is too small, the code makes it the correct size and calls the API again.
- For each entry in the buffer, it extracts the data and prints it.
NOTE: When using these functions in your own applications, you may want to
return an array of data that can be displayed in a list box or grid rather
than print the values.
The buffer is in the following format:
|rec1|rec2|...|recn|...garbage...|strn|...|str2|str1|
INFO records containing string pointers and numeric values are added from
the left and the string text for each record is added from the right. The
area between the end of the last record and the start of the last string
text contains garbage.
The buffer is declared as type Long, which makes extracting data from the
records easier - all fields are either Long or pointers (pointers map to
Long).
The StrLen() and PtrToStr() functions are used to set up the receiving
string variable and to copy the text from the buffer to the variable.
- Create a module and type the following lines in the Declarations section:
Option Compare Database
Option Explicit
Const PRINTER_ENUM_CONNECTIONS = &H4
Const PRINTER_ENUM_LOCAL = &H2
Type PRINTER_INFO_1
flags As Long
pDescription As String
PName As String
PComment As String
End Type
Type PRINTER_INFO_4
pPrinterName As String
pServerName As String
Attributes As Long
End Type
Declare Function EnumPrinters Lib "winspool.drv" Alias _
"EnumPrintersA" (ByVal flags As Long, ByVal name As String, _
ByVal Level As Long, pPrinterEnum As Long, ByVal cdBuf As Long, _
pcbNeeded As Long, pcReturned As Long) As Long
Declare Function PtrToStr Lib "Kernel32" Alias "lstrcpyA" _
(ByVal RetVal As String, ByVal Ptr As Long) As Long
Declare Function StrLen Lib "Kernel32" Alias "lstrlenA" _
(ByVal Ptr As Long) As Long
- Type the following procedures:
Sub EnumeratePrintersWin()
Dim Success As Boolean, cbRequired As Long, cbBuffer As Long
Dim Buffer() As Long, nEntries As Long
Dim I As Long, PFlags As Long, PDesc As String, PName As String
Dim PComment As String, Temp As Long
cbBuffer = 3072
ReDim Buffer((cbBuffer \ 4) - 1) As Long
Success = EnumPrinters(PRINTER_ENUM_CONNECTIONS Or _
PRINTER_ENUM_LOCAL, _
vbNullString, _
1, _
Buffer(0), _
cbBuffer, _
cbRequired, _
nEntries)
If Success Then
If cbRequired > cbBuffer Then
cbBuffer = cbRequired
Debug.Print "Buffer too small. Trying again with " & _
cbBuffer & " bytes."
ReDim Buffer(cbBuffer \ 4) As Long
Success = EnumPrinters(PRINTER_ENUM_CONNECTIONS Or _
PRINTER_ENUM_LOCAL, _
vbNullString, _
1, _
Buffer(0), _
cbBuffer, _
cbRequired, _
nEntries)
If Not Success Then
Debug.Print "Error enumerating printers."
Exit Sub
End If
End If
Debug.Print "There are " & nEntries & _
" local and connected printers."
For I = 0 To nEntries - 1
PFlags = Buffer(4 * I)
PDesc = Space$(StrLen(Buffer(I * 4 + 1)))
Temp = PtrToStr(PDesc, Buffer(I * 4 + 1))
PName = Space$(StrLen(Buffer(I * 4 + 2)))
Temp = PtrToStr(PName, Buffer(I * 4 + 2))
PComment = Space$(StrLen(Buffer(I * 4 + 2)))
Temp = PtrToStr(PComment, Buffer(I * 4 + 2))
Debug.Print PFlags, PDesc, PName, PComment
Next I
Else
Debug.Print "Error enumerating printers."
End If
End Sub
Sub EnumeratePrintersNT()
Dim Success As Boolean, cbRequired As Long, cbBuffer As Long
Dim Buffer() As Long, nEntries As Long
Dim I As Long, PName As String, SName As String
Dim Attrib As Long, Temp As Long
cbBuffer = 3072
ReDim Buffer((cbBuffer \ 4) - 1) As Long
Success = EnumPrinters(PRINTER_ENUM_CONNECTIONS Or _
PRINTER_ENUM_LOCAL, _
vbNullString, _
4, _
Buffer(0), _
cbBuffer, _
cbRequired, _
nEntries)
If Success Then
If cbRequired > cbBuffer Then
cbBuffer = cbRequired
Debug.Print "Buffer too small. Trying again with " & _
cbBuffer & " bytes."
ReDim Buffer(cbBuffer \ 4) As Long
Success = EnumPrinters(PRINTER_ENUM_CONNECTIONS Or _
PRINTER_ENUM_LOCAL, _
vbNullString, _
4, _
Buffer(0), _
cbBuffer, _
cbRequired, _
nEntries)
If Not Success Then
Debug.Print "Error enumerating printers."
Exit Sub
End If
End If
Debug.Print "There are " & nEntries & _
" local and connected printers."
For I = 0 To nEntries - 1
PName = Space$(StrLen(Buffer(I * 3)))
Temp = PtrToStr(PName, Buffer(I * 3))
SName = Space$(StrLen(Buffer(I * 3 + 1)))
Temp = PtrToStr(SName, Buffer(I * 3 + 1))
Attrib = Buffer(I * 3 + 2)
Debug.Print "Printer: " & PName, "Server: " & SName, _
"Attributes: " & Hex$(Attrib)
Next I
Else
Debug.Print "Error enumerating printers."
End If
End Sub
- To test this function, type the following line in the Immediate window, and then press ENTER:
EnumeratePrintersWIN
The output should be similar to the following:
There are 1 local and connected printers.
8388608 \\NCPRINT\HP5SI@1155,HP LaserJet 5Si MX,HP5SI@1155
\\NCPRINT\HP5SI@1155 \\NCPRINT\HP5SI@1155
If you are using Microsoft Windows NT, type:
EnumeratePrintersNT
The output should be similar to the following:
There are 1 local and connected printers.
Printer: \\NCPRINT\HP5SI@1155 Server: \\NCPRINT
Attributes: 10
REFERENCES
For more information about the EnumPrinters function, please refer to the
Win32 SDK.
Additional query words:
Keywords : kbnetwork kbprg kbprint kbdta
Version : WINDOWS:2000
Platform : WINDOWS
Issue type : kbhowto
|