我正在尝试使用Sacha Barber提供的代码获取网络上所有电脑的所有计算机名称。原始文章的链接是here。代码最初是在C#中,但我已将其转换为VB。当我从Visual Studio以调试模式运行程序时,它通常(并非所有时间)运行正常,但是当我部署程序时,它几乎从不运行。
在以下行失败:
Dim svrInfo As _SERVER_INFO_100 = DirectCast(Marshal.PtrToStructure(tmpBuffer, _
GetType(_SERVER_INFO_100)), _SERVER_INFO_100)
我收到以下错误:
An unhandled exception of type 'System.ExecutionEngineException' occurred in mscorlib.dll HResult=-2146233082
我知道它与内存分配有关,但我不知道如何避免这个错误。我尝试过使用Debug Diagnostics Tool 1.2,但即便如此,我也不确定要寻找什么。
Imports System.Runtime.InteropServices
Public Class NetworkInfo
Dim CurrentDomain As AppDomain = AppDomain.CurrentDomain
'import the NetServerEnum function from the netapi32.dll
Private Declare Unicode Function NetServerEnum Lib "netapi32" _
(ByVal Servername As IntPtr, _
ByVal Level As Integer, _
ByRef bufptr As IntPtr, _
ByVal PrefMaxLen As Integer, _
ByRef entriesread As Integer, _
ByRef TotalEntries As Integer, _
ByVal serverType As Integer, _
ByVal Domain As IntPtr, _
ByVal ResumeHandle As IntPtr) As Integer
'import the NetApiBufferFree function from the netapi32.dll
Private Declare Unicode Function NetApiBufferFree Lib "netapi32.dll" _
(ByRef buffer As IntPtr) As UInteger
Public Structure _SERVER_INFO_100
Friend sv100_platform_id As Integer
<MarshalAs(UnmanagedType.LPWStr)> _
Friend sv100_name As String
End Structure
Public Function GetNetworkComputers() As ArrayList
Dim networkComputers As New ArrayList()
Const MAX_PREFERRED_LENGTH As Integer = -1
Dim SV_TYPE_WORKSTATION As Integer = 1
Dim SV_TYPE_SERVER As Integer = 2
Dim buffer As IntPtr = IntPtr.Zero
Dim tmpBuffer As IntPtr = IntPtr.Zero
Dim entriesRead As Integer = 0
Dim totalEntries As Integer = 0
Dim resHandle As Integer = 0
Dim sizeofINFO As Integer = Marshal.SizeOf(GetType(_SERVER_INFO_100))
Try
Dim ret As Integer = NetServerEnum(Nothing, 100, buffer, MAX_PREFERRED_LENGTH, entriesRead, totalEntries, _
SV_TYPE_WORKSTATION Or SV_TYPE_SERVER, Nothing, resHandle)
If ret = 0 Then
For i As Integer = 0 To totalEntries
tmpBuffer = New IntPtr(CType(buffer, Long) + (i * sizeofINFO))
Dim svrInfo As _SERVER_INFO_100 = DirectCast(Marshal.PtrToStructure(tmpBuffer, _
GetType(_SERVER_INFO_100)), _SERVER_INFO_100)
networkComputers.Add(svrInfo.sv100_name)
Next
End If
Catch ex As Exception
Console.WriteLine("Error getting network computers.")
Finally
NetApiBufferFree(buffer)
End Try
Return networkComputers
End Function
End Class