Imports System
Imports System.Collections.Generic
Imports System.ComponentModel
Imports System.Data
Imports System.Drawing
Imports System.Text
Imports System.Windows.Forms
Imports System.Security
Imports System.Drawing.Printing
Imports System.Runtime.InteropServices
Public Class Form1
Private Const PRINTER_ENUM_LOCAL As Integer = 2
Private Const PRINTER_ENUM_CONNECTIONS As Integer = 4
Private Const DC_PAPERNAMES As Integer = 16
Private Const DC_PAPERS As Integer = 2
Private Const DC_PAPERSIZE As Integer = 3
Private Const DC_BINNAMES As Integer = 12
<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)> _
Private Structure PRINTER_INFO_5
<MarshalAs(UnmanagedType.LPTStr)> _
Public PrinterName As String
<MarshalAs(UnmanagedType.LPTStr)> _
Public PortName As String
<MarshalAs(UnmanagedType.U4)> _
Public Attributes As Int32
<MarshalAs(UnmanagedType.U4)> _
Public DeviceNotSelectedTimeout As Int32
<MarshalAs(UnmanagedType.U4)> _
Public TransmissionRetryTimeout As Int32
End Structure
<DllImport("winspool.drv", EntryPoint:="DeviceCapabilitiesA", SetLastError:=True)> _
Public Shared Function DeviceCapabilities( _
ByVal device As String, _
ByVal port As String, _
ByVal capability As Int16, _
ByVal outputBuffer As IntPtr, _
ByVal deviceMode As IntPtr) As Int32
End Function
<DllImport("winspool.drv", SetLastError:=True)> _
Public Shared Function EnumPrintersW(ByVal flags As Int32, _
ByVal printerName As String, _
ByVal level As Int32, ByVal buffer As IntPtr, ByVal bufferSize As Int32, ByRef _
requiredBufferSize As Int32, ByRef numPrintersReturned As Int32) As Boolean
End Function
<DllImport("kernel32.dll", EntryPoint:="GetLastError", SetLastError:=False, _
ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall), _
SuppressUnmanagedCodeSecurityAttribute()> _
Public Shared Function GetLastError() As Int32
End Function
Public Shared Sub GetDefinedPapers(ByVal printerName As String)
Dim info5 As PRINTER_INFO_5
Dim PRINT_INFO As PRINTER_INFO_5 = Nothing
Dim requiredSize As Integer
Dim numPrinters As Integer
Dim intI As Integer
Dim foundPrinter As Boolean = EnumPrintersW(PRINTER_ENUM_LOCAL + PRINTER_ENUM_CONNECTIONS, _
String.Empty, 5, IntPtr.Zero, 0, requiredSize, numPrinters)
Dim info5Size As Integer = requiredSize
Dim info5Ptr As IntPtr = Marshal.AllocHGlobal(info5Size)
Dim buffer As IntPtr = IntPtr.Zero
Try
foundPrinter = EnumPrintersW(PRINTER_ENUM_LOCAL + PRINTER_ENUM_CONNECTIONS, _
String.Empty, 5, info5Ptr, info5Size, requiredSize, numPrinters)
Dim port As String = Nothing
For intI = 0 To numPrinters - 1
info5 = Marshal.PtrToStructure(CType(Integer.Parse(intI * Marshal.SizeOf(PRINT_INFO.GetType)) + CType(info5Ptr, Int32), IntPtr), PRINT_INFO.GetType)
If info5.PrinterName = printerName Then
port = info5.PortName
Exit For
End If
Next
Dim numNames As Integer
numNames = DeviceCapabilities(printerName, port, DC_PAPERNAMES, IntPtr.Zero, IntPtr.Zero)
If (numNames < 0) Then
Dim errorCode As Integer = GetLastError()
Console.WriteLine("Number of names = {1}: {0}", errorCode, numNames)
Return
End If
buffer = Marshal.AllocHGlobal(numNames * 64)
numNames = DeviceCapabilities(printerName, port, DC_PAPERNAMES, buffer, IntPtr.Zero)
If numNames < 0 Then
Dim errorCode As Integer = GetLastError()
Console.WriteLine("Number of names = {1}: {0}", errorCode, numNames)
Return
End If
Dim names(numNames - 1) As String
For intI = 0 To numNames - 1
names(intI) = Marshal.PtrToStringAnsi(CType((intI * 64) + CType(buffer, Integer), IntPtr))
Next
Marshal.FreeHGlobal(buffer)
buffer = IntPtr.Zero
Dim numPapers As Integer = DeviceCapabilities(printerName, port, DC_PAPERS, IntPtr.Zero, IntPtr.Zero)
If numPapers < 0 Then
Console.WriteLine("No papers")
Return
End If
buffer = Marshal.AllocHGlobal(numPapers * 2)
numPapers = DeviceCapabilities(printerName, port, DC_PAPERS, buffer, IntPtr.Zero)
If numPapers < 0 Then
Console.WriteLine("No papers")
Return
End If
Dim kinds(numPapers - 1) As String
For intI = 0 To numPapers - 1
kinds(intI) = Marshal.ReadInt16(buffer, intI * 2)
Next
For intI = 0 To numPapers - 1
Console.WriteLine("Paper {0} : {1}", kinds(intI), names(intI))
Next
Dim numPaperboxs As Integer = DeviceCapabilities(printerName, port, DC_BINNAMES, IntPtr.Zero, IntPtr.Zero)
If numPaperboxs < 0 Then
Console.WriteLine("No papers")
Return
End If
buffer = Marshal.AllocHGlobal(numPapers * 2)
numPaperboxs = DeviceCapabilities(printerName, port, DC_BINNAMES, buffer, IntPtr.Zero)
If numPaperboxs < 0 Then
Console.WriteLine("No papers")
Return
End If
Dim arrBoxsNm(numPaperboxs - 1) As String
For intI = 0 To numPaperboxs - 1
arrBoxsNm(intI) = Marshal.PtrToStringAnsi(CType((intI * 24) + CType(buffer, Integer), IntPtr))
Next
For intI = 0 To numPaperboxs - 1
Console.WriteLine("PaperboxNm {0}", arrBoxsNm(intI))
Next
Finally
Marshal.FreeHGlobal(info5Ptr)
End Try
End Sub
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
GetDefinedPapers("//Print/Canon LASER SHOT LBP-1420")
End Sub
End Class