此范例会以递归方式列举网络芳邻的网络资源,在此范例中会使用到 mpr.dll API 函式库的 WNetEnumResource、WNetOpenEnum、WNetCloseEnum 函式来进行网络芳邻的网络资源的列举动作。
TAPIMpr 类别为 mpr.dll API 函式库的操作类别
1: ''' <summary>
2: ''' 网络芳邻相关函式库(mpr.dll)。
3: ''' </summary>
4: Public NotInheritable Class TAPIMpr
5: Public Enum EResourceScope As Integer
6: ''' <summary>
7: ''' 正联机的资源。
8: ''' </summary>
   9:              RESOURCE_CONNECTED = &H1 10: ''' <summary>
11: ''' 网络上所有的资源。
12: ''' </summary>
  13:              RESOURCE_GLOBALNET = &H2 14: ''' <summary>
15: ''' 曾经联机的资源。
16: ''' </summary>
  17:              RESOURCE_REMEMBERED = &H3 18: End Enum
  19:    20: Public Enum EResourceType As Integer
21: ''' <summary>
22: ''' 所有网络资源。
23: ''' </summary>
  24:              RESOURCETYPE_ANY = &H0 25: ''' <summary>
26: ''' 网络磁盘驱动器。
27: ''' </summary>
  28:              RESOURCETYPE_DISK = &H1 29: ''' <summary>
30: ''' 网络打印机。
31: ''' </summary>
  32:              RESOURCETYPE_PRINT = &H2 33: ''' <summary>
34: ''' 未知。
35: ''' </summary>
  36:              RESOURCETYPE_UNKNOWN = &HFFFFFFFF 37: End Enum
  38:    39: Public Enum EResourceDisplayType As Integer
40: ''' <summary>
41: ''' 一般资源。
42: ''' </summary>
  43:              RESOURCEDISPLAYTYPE_GENERIC = 0 44: ''' <summary>
45: ''' 网域资源。
46: ''' </summary>
  47:              RESOURCEDISPLAYTYPE_DOMAIN = 1 48: ''' <summary>
49: ''' 服务器资源。
50: ''' </summary>
  51:              RESOURCEDISPLAYTYPE_SERVER = 2 52: ''' <summary>
53: ''' 共享资源。
54: ''' </summary>
  55:              RESOURCEDISPLAYTYPE_SHARE = 3 56: ''' <summary>
57: ''' 档案资源。
58: ''' </summary>
  59:              RESOURCEDISPLAYTYPE_FILE = 4   60:              RESOURCEDISPLAYTYPE_GROUP = 5   61:              RESOURCEDISPLAYTYPE_NETWORK = 6   62:              RESOURCEDISPLAYTYPE_ROOT = 7   63:              RESOURCEDISPLAYTYPE_SHAREADMIN = 8   64:              RESOURCEDISPLAYTYPE_DIRECTORY = 9   65:              RESOURCEDISPLAYTYPE_TREE = 10   66:              RESOURCEDISPLAYTYPE_NDSCONTAINER = 11 67: End Enum
  68:    69: Public Enum EResourceUsage As Integer
  70:              RESOURCEUSAGE_CONNECTABLE = &H1   71:              RESOURCEUSAGE_CONTAINER = &H2   72:              RESOURCEUSAGE_NOLOCALDEVICE = &H4   73:              RESOURCEUSAGE_SIBLING = &H8   74:              RESOURCEUSAGE_ATTACHED = &H10 75: RESOURCEUSAGE_ALL = (RESOURCEUSAGE_CONNECTABLE Or RESOURCEUSAGE_CONTAINER Or RESOURCEUSAGE_ATTACHED)
  76:              RESOURCEUSAGE_RESERVED = &H80000000 77: End Enum
  78:    79: ''' <summary>
80: ''' 网络资源定义。
81: ''' </summary>
82: <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)> _
83: Public Class TNetResource
84: Public dwScope As EResourceScope
85: Public dwType As EResourceType
86: Public dwDisplayType As EResourceDisplayType
87: Public dwUsage As EResourceUsage
  88:              <MarshalAs(UnmanagedType.LPTStr)> _ 89: Public LocalName As String
  90:              <MarshalAs(UnmanagedType.LPTStr)> _ 91: Public RemoteName As String
  92:              <MarshalAs(UnmanagedType.LPTStr)> _ 93: Public Comment As String
  94:              <MarshalAs(UnmanagedType.LPTStr)> _ 95: Public Provider As String
96: End Class
  97:    98: ''' <summary>
99: ''' 列举网络芳邻的网络资源。
100: ''' </summary>
101: ''' <param name="Handle">从 WNetOpenEnum 函数返回的一个句柄。</param>
102: ''' <param name="Count">最初设为要枚举的最大资源数量;或设为-1,表示枚举尽可能多的资源。一旦返回,就会设为实际枚举的资源数量。</param>
103: ''' <param name="NetResource">通常是一个字节缓冲区的首字节。该缓冲区装载了列举信息。</param>
104: ''' <param name="Size">缓冲区大小。</param>
105: <DllImport("mpr.dll", CharSet:=CharSet.Auto)> _
106: Public Shared Function WNetEnumResource(ByVal Handle As IntPtr, ByRef Count As Integer, ByVal NetResource As IntPtr, ByRef Size As Integer) As Integer
107: End Function
 108:    109: ''' <summary>
110: ''' 启动对网络资源进行列举的过程。这个函数会返回由 WNetEnumResource 函数用于列举资源所用的一个句柄。
111: ''' </summary>
112: ''' <param name="Scope">要列举的资源范围。</param>
113: ''' <param name="Type">要列举的资源类型。</param>
114: ''' <param name="Usage">要列举的资源使用状况。</param>
115: ''' <param name="NetResource">网络资源定义。</param>
116: ''' <param name="Handle">传出一个句柄。该句柄由 WNetEnumResource 函数使用。必须用 WNetCloseEnum 函数将其清除。</param>
117: <DllImport("mpr.dll", CharSet:=CharSet.Auto)> _
118: Public Shared Function WNetOpenEnum(ByVal Scope As EResourceScope, ByVal Type As EResourceType, ByVal Usage As EResourceUsage, ByVal NetResource As TNetResource, <Out()> ByRef Handle As IntPtr) As Integer
119: End Function
 120:    121: ''' <summary>
122: ''' 结束列举操作。
123: ''' </summary>
124: ''' <param name="Handle">由 WNetOpenEnum 函数返回的一个列举句柄。</param>
125: <DllImport("mpr.dll", CharSet:=CharSet.Auto)> _
126: Public Shared Function WNetCloseEnum(ByVal Handle As IntPtr) As Integer
127: End Function
 128:    129: End Class
下列程序代码中的 NetEnumResource 为列举网络芳邻的网络资源的函式,NetEnumResourceCallback 为执行 NetEnumResource 方法的回呼函式。
1: ''' <summary>
2: ''' 执行 NetEnumResource 方法的回呼函式。
3: ''' </summary>
4: ''' <param name="NetResource">网络资源定义。</param>
5: ''' <param name="Cancel">是否取消列举动作。</param>
6: Public Delegate Sub NetEnumResourceCallback(ByVal NetResource As TAPIMpr.TNetResource, ByRef Cancel As Boolean)
   7:    8: ''' <summary>
9: ''' 列举网络芳邻的网络资源。
10: ''' </summary>
11: ''' <param name="NetResource">网络资源定义。</param>
12: ''' <param name="CallBack">列举过程中的回呼函式。</param>
13: Public Shared Sub NetEnumResource(ByVal NetResource As TAPIMpr.TNetResource, ByVal CallBack As NetEnumResourceCallback)
14: Dim bCancel As Boolean
15: Dim iRet As Integer
16: Dim oHandle As IntPtr = New IntPtr()
17: Dim iEntries As Integer
18: Dim iBuffer As Integer = 16384
19: Dim oBuffer As IntPtr
20: Dim oNetResource As TAPIMpr.TNetResource
21: Dim iPtr As Int32
22: Dim N1 As Integer
23: Dim oStructure As Object
  24:    25: bCancel = False
26: Try
  27:                  iRet = TAPIMpr.WNetOpenEnum( _   28:                      TAPIMpr.EResourceScope.RESOURCE_GLOBALNET, _   29:                      TAPIMpr.EResourceType.RESOURCETYPE_ANY, _   30:                      TAPIMpr.EResourceUsage.RESOURCEUSAGE_ALL, NetResource, oHandle) 31: If iRet <> 0 Then Exit Sub
  32:      33:                  oBuffer = Marshal.AllocHGlobal(iBuffer) 34: Do
  35:                      iEntries = -1   36:                      iBuffer = 16384   37:                      iRet = TAPIMpr.WNetEnumResource(oHandle, iEntries, oBuffer, iBuffer) 38: If iRet <> 0 OrElse iEntries < 1 Then Exit Sub
  39:                      iPtr = oBuffer.ToInt32 40: For N1 = 0 To iEntries - 1
41: oStructure = Marshal.PtrToStructure(CType(iPtr, IntPtr), GetType(TAPIMpr.TNetResource))
42: oNetResource = DirectCast(oStructure, TAPIMpr.TNetResource)
  43:    44: '列举过程中的回呼函式
  45:                          CallBack.Invoke(oNetResource, bCancel) 46: If bCancel = True Then Exit Do
  47:    48: '若为 RESOURCEUSAGE_CONTAINER 则利用递归往下层列举网络资源
49: If (TAPIMpr.EResourceUsage.RESOURCEUSAGE_CONTAINER = _
50: (oNetResource.dwUsage And TAPIMpr.EResourceUsage.RESOURCEUSAGE_CONTAINER)) Then
  51:                              NetEnumResource(oNetResource, CallBack) 52: End If
  53:                          iPtr = iPtr + Marshal.SizeOf(oNetResource) 54: Next
55: Loop
  56:      57:                  Marshal.FreeHGlobal(oBuffer)   58:                  TAPIMpr.WNetCloseEnum(oHandle) 59: Catch ex As Exception
60: End Try
61: End Sub
在窗体上放置一个 ListBox 控件来显示列举的网络资源,呼叫 NetEnumResource 函式来进行列举,呼叫 NetEnumResource 函式的自变量需传入事先定义好的 NetEnumResourceCallback 回呼函式;当列举的过程序,当找到网络资源时就会执行 NetEnumResourceCallback 函式,利用传入的 NetResource 自变量就可以依序列举网络资源。
1: ''' <summary>
2: ''' 执行 WNetEnumResource 方法的回呼函式。
3: ''' </summary>
4: ''' <param name="NetResource">网络资源定义。</param>
5: ''' <param name="Cancel">是否取消列举动作。</param>
6: Public Sub NetEnumResourceCallback(ByVal NetResource As TAPIMpr.TNetResource, ByRef Cancel As Boolean)
7: Dim sText As String
   8:    9: sText = String.Format(" {0} : LocalName='{1}' RemoteName='{2}'", NetResource.dwDisplayType.ToString, NetResource.LocalName, NetResource.RemoteName)
  10:          ListBox1.Items.Add(sText)   11:          Application.DoEvents() 12: End Sub
  13:    14: Private Sub Button10_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button10.Click
15: Me.Cursor = Cursors.WaitCursor
16: Try
  17:              ListBox1.Items.Clear() 18: TBMpr.NetEnumResource(Nothing, New NetEnumResourceCallback(AddressOf NetEnumResourceCallback))
19: MsgBox("执行完成!")
20: Finally
21: Me.Cursor = Cursors.Default
22: End Try
23: End Sub