Webで探すのにすごく苦労したので成果を残す。

苦労したのはDeclareの書き方とVBで構造体のポインタはどう扱うのか。
C++で書いたときは簡単だったんだけどねぇ。

ちょっといじってるけど、おそらくまるごとコピーで動くはず。
なにか足りなかったら適当に増やしてね。

Imports System.Runtime.InteropServices

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

Declare Function EnumPorts Lib "winspool.drv" Alias "EnumPortsA" (ByVal pName As String, ByVal Level As Integer, ByVal lpbPorts As Integer, ByVal cbBuf As Integer, ByRef pcbNeeded As Integer, ByRef pcReturned As Integer) As Integer

Declare Function HeapAlloc Lib "kernel32" (ByVal hHeap As Long, ByVal dwFlags As Long, ByVal dwBytes As Long) As Long
Declare Function GetProcessHeap Lib "kernel32" () As Long
Declare Function HeapFree Lib "kernel32" (ByVal hHeap As Long, ByVal dwFlags As Long, ByVal lpMem As Object) As Long
Declare Sub CopyMem Lib "kernel32" Alias "RtlMoveMemory" (ByVal pTo As Object, ByVal uFrom As Object, ByVal lSize As Long)

Dim bufSize As Integer
Dim numPorts As Integer
Dim tmp As IntPtr = IntPtr.Zero '暫定の入れ物

PrinterUtil.EnumPorts(vbNullString, 2, CInt(tmp), 0, bufSize, numPorts)
tmp = Marshal.AllocHGlobal(bufSize - 1)

If PrinterUtil.EnumPorts(vbNullString, 2, CInt(tmp), bufSize, bufSize, numPorts) = 0 Then
' Error処理
End If

Dim portInfo(numPorts) As PORT_INFO_2
Dim curPtr As IntPtr = tmp

For i = 1 To numPorts
portInfo(i) = CType(Marshal.PtrToStructure(curPtr, GetType(PORT_INFO_2)), PORT_INFO_2)
curPtr = IntPtr.op_Explicit(curPtr.ToInt32 + Marshal.SizeOf(GetType(PORT_INFO_2)))
Next
Marshal.FreeHGlobal(tmp)

これであとはportInfoの配列でいじり放題。

ポインタ扱うの面倒だね。


VB.NET基礎学習Bible―270例題で学ぶプログラミングの散歩道/技術評論社

¥3,110
Amazon.co.jp