Torna al Thread
Imports System.Runtime.InteropServices
'strutture per recuperare le informazioni sulla porta (per ora mi basta PORT_INFO_1)
Public Structure PORT_INFO_1
Dim pPortName As String
End Structure
Public Structure PORT_INFO_2
Dim pPortName As String
Dim pMonitorName As String
Dim pDescription As String
Dim fPortType As Integer
Dim Reserved As Integer
End Structure
'aggiunge una porta
Public Declare Function AddPortEx Lib "winspool.drv" Alias "AddPortExA" (ByVal pName As String, ByVal pLevel As Integer, ByRef lpBuffer As _
PORT_INFO_1, ByVal pMonitorName As String) As Integer
'recupera l'elenco di porte installate
'EnumPorts member descriptions:
'pName: String specifying the name of the server whose
'printer ports you wish to enumerate. If pName is
'vbNullString, the function enumerates the local
'machine's printer ports.
'nLevel: Specifies the type of information returned in
'the lpbPorts buffer. If nLevel is 1, lpbPorts receives
'an array of PORT_INFO_1 structures. If nLevel is 2,
'lpbPorts receives an array of PORT_INFO_2 structures.
'lpbPorts: Pointer to a buffer that receives an array of
'PORT_INFO_1 or PORT_INFO_2 structures. Each structure
'contains data that describes an available printer port.
'The buffer must be large enough to store the strings
'pointed to by the structure members.
'cbBuf: the size, in bytes, of the buffer pointed to by lpbPorts.
'pcbNeeded: receives the number of bytes copied to the lpbPorts
'buffer. If the the buffer is too small, the function fails and
'the variable receives the number of bytes required.
'pcReturned: variable that receives the number of PORT_INFO_1 or
'PORT_INFO_2 structures returned in the pPorts buffer. This
'corresponds to the number of printer ports that are available
'on the specified machine.
Declare Function EnumPorts Lib "winspool.drv" Alias "EnumPortsA" _
(ByVal pName As String, ByVal Level As Integer, ByVal lpbPorts As IntPtr, _
ByVal cbBuf As Integer, ByRef pcbNeeded As Integer, ByRef pcReturned As Integer) As Integer
'controlla se la porta esiste, altrimenti la crea
Private Sub AddPort(ByVal PortName As String)
Dim ret, pcbNeeded, pcReturned As Integer
Dim TempBuff As IntPtr, i As Short
Dim FoundedPorts() As PORT_INFO_1 'elenco delle porte trovate
Dim Found As Boolean = False 'indica se la porta è già installata
Try
'NOTA: modifica del codice proposto su http://vbcity.com/forums/topic.asp?tid=47438 utilizzando PORT_INFO_1 anziché PORT_INFO_2
' Make the first call to the function
ret = EnumPorts("", 1, TempBuff, 0, pcbNeeded, pcReturned)
' Set the size of the pointer to return the data based upon the size of the buffer required
TempBuff = Marshal.AllocHGlobal(pcbNeeded + 1)
' Make the call again with the buffer set
ret = EnumPorts("", 1, TempBuff, pcbNeeded, pcbNeeded, pcReturned)
' Determine whether the call was successful
If ret Then
' Set the pointer to process as the first one returned
Dim CurrentPort As IntPtr = TempBuff
' Re-dimension the array of port structures
ReDim FoundedPorts(pcReturned)
' Loop through the results
For i = 1 To pcReturned
' Convert the pointer to a structure
FoundedPorts(i) = Marshal.PtrToStructure(CurrentPort, GetType(PORT_INFO_1))
If FoundedPorts(i).pPortName = PortName Then
Found = True
End If
' Obtain the next port pointer from the buffer
CurrentPort = IntPtr.op_Explicit(CurrentPort.ToInt32 + Marshal.SizeOf(GetType(PORT_INFO_1)))
Next
End If
FoundedPorts = Nothing
If Not Found Then 'se la porta non esiste già, viene aggiunta
Dim Port As New PORT_INFO_1
Port.pPortName = PortName
AddPortEx(Nothing, 1, Port, "Local Port")
End If
Catch ex As Exception
'gli errori andranno gestiti dal chiamante
Throw ex
End Try
End Sub