element Posted April 10, 2004 Posted April 10, 2004 Hi, I've been attempting to get this to work for around 5 hours now, getting a little tired of it failing me :S Please can somebody tell me where I'm going wrong, actually - I know where I'm going wrong but I don't know how to fix it. <StructLayout(LayoutKind.Sequential)> Public Class MIB_IFTABLE Public dwNumEntries As Integer <MarshalAs(UnmanagedType.SafeArray)> Public table() As MIB_IFROW End Class <StructLayout(LayoutKind.Sequential)> Public Class MIB_IFROW <VBFixedArray(511)> Public wszName() As Byte '511 'Public wszName As Byte() Public dwIndex As Int32 Public dwType As Int32 Public dwMtu As Int32 Public dwSpeed As Int32 Public dwPhysAddrLen As Int32 <VBFixedArray(7)> Public bPhysAddr() As Byte '7 'Public bPhysAddr() As Byte Public dwAdminStatus As Int32 Public dwOperStatus As Int32 Public dwLastChange As Int32 Public dwInOctets As Int32 Public dwInUcastPkts As Int32 Public dwInNUcastPkts As Int32 Public dwInDiscards As Int32 Public dwInErrors As Int32 Public dwInUnknownProtos As Int32 Public dwOutOctets As Int32 Public dwOutUcastPkts As Int32 Public dwOutNUcastPkts As Int32 Public dwOutDiscards As Int32 Public dwOutErrors As Int32 Public dwOutQLen As Int32 Public dwDescrLen As Int32 <VBFixedArray(255)> Public bDescr() As Byte '255 'Public bDescr() As Byte End Class Above are the classes used. I cannot use Structures for some reason, it says: Additional information: Can not marshal field table of type MIB_IFTABLE: This type can not be marshaled as a structure field. (Note this only happens when I un-comment out the table variable in the MIB_IFTABLE structure) This is the error I get with the code I use below: An unhandled exception of type 'System.Runtime.InteropServices.SafeArrayTypeMismatchException' occurred in mscorlib.dll Additional information: Mismatch has occurred between the runtime type of the array and the sub type recorded in the metadata. Dim lRetSize As Int32, lRows As Int32, ret As Long Dim IfRowTable As New MIB_IFTABLE Dim pStruct As IntPtr = IntPtr.Zero ret = GetIfTable(pStruct, lRetSize, 0) pStruct = Marshal.AllocHGlobal(lRetSize) ret = GetIfTable(pStruct, lRetSize, 0) IfRowTable = Marshal.PtrToStructure(pStruct, GetType(MIB_IFTABLE)) Marshal.FreeHGlobal(pStruct) It is strange, because when I comment out the table variable, it gives me the value of 1311096 in dwNumEntries. This value *should* be two (2 network devices, loopback + NIC) Thank you for any help/advice in advance, Tom Quote
element Posted April 14, 2004 Author Posted April 14, 2004 Alright I've figured it all out, in fact, I did so like 2 hours after my original post. I'll paste in the code for a class I have written. Imports System.Runtime.InteropServices Class clsNetworkStats #Region " DECLARES " Private Const MAX_INTERFACE_NAME_LEN As Long = 256 Private Const ERROR_SUCCESS As Long = 0 Private Const MAXLEN_IFDESCR As Long = 256 Private Const MAXLEN_PHYSADDR As Long = 8 <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> Private Structure MIB_IFROW <MarshalAs(UnmanagedType.ByValTStr, sizeconst:=MAX_INTERFACE_NAME_LEN)> Public wszName As String Public dwIndex As UInt32 Public dwType As UInt32 Public dwMtu As UInt32 Public dwSpeed As UInt32 Public dwPhysAddrLen As UInt32 <MarshalAs(UnmanagedType.ByValArray, sizeconst:=MAXLEN_PHYSADDR)> Public bPhysAddr() As Byte Public dwAdminStatus As UInt32 Public dwOperStatus As UInt32 Public dwLastChange As UInt32 Public dwInOctets As UInt32 Public dwInUcastPkts As UInt32 Public dwInNUcastPkts As UInt32 Public dwInDiscards As UInt32 Public dwInErrors As UInt32 Public dwInUnknownProtos As UInt32 Public dwOutOctets As UInt32 Public dwOutUcastPkts As UInt32 Public dwOutNUcastPkts As UInt32 Public dwOutDiscards As UInt32 Public dwOutErrors As UInt32 Public dwOutQLen As UInt32 Public dwDescrLen As UInt32 <MarshalAs(UnmanagedType.ByValArray, sizeconst:=MAXLEN_IFDESCR)> Public bDescr() As Byte End Structure Public Structure IFROW_HELPER Public Name As String Public Index As Integer Public Type As Integer Public Mtu As Integer Public Speed As Integer Public PhysAddrLen As Integer Public PhysAddr As String Public AdminStatus As Integer Public OperStatus As Integer Public LastChange As Integer Public InOctets As Integer Public InUcastPkts As Integer Public InNUcastPkts As Integer Public InDiscards As Integer Public InErrors As Integer Public InUnknownProtos As Integer Public OutOctets As Integer Public OutUcastPkts As Integer Public OutNUcastPkts As Integer Public OutDiscards As Integer Public OutErrors As Integer Public OutQLen As Integer Public Description As String Public InMegs As String Public OutMegs As String End Structure <DllImport("iphlpapi")> Private Shared Function GetIfTable(ByRef pIfRowTable As Byte, ByRef pdwSize As Int32, ByVal bOrder As Int32) As Int32 End Function <DllImport("iphlpapi")> Private Shared Function GetIfEntry(ByRef pIfRow As MIB_IFROW) As Int32 End Function #End Region Private m_Adapters As ArrayList Public Sub New(Optional ByVal IgnoreLoopBack As Boolean = True) Dim lRetSize As Int32, lRows As Int32, ret As Long, i As Byte Dim ifrow As New MIB_IFROW Dim buff(0) As Byte '--//////////////////////////////////////////////////////////////////////////////////////////// ret = GetIfTable(0&, lRetSize, 0) ret = GetIfTable(buff(0), lRetSize, 0) lRows = buff(0) m_Adapters = New ArrayList(lRows) For i = 1 To lRows ifrow = New MIB_IFROW ifrow.dwIndex = Convert.ToUInt32(i) ret = GetIfEntry(ifrow) Dim ifhelp As IFROW_HELPER = PrivToPub(ifrow) If IgnoreLoopBack = True Then If ifhelp.Description.IndexOf("Loopback") < 0 Then m_Adapters.Add(ifhelp) End If Else m_Adapters.Add(ifhelp) End If Next '--//////////////////////////////////////////////////////////////////////////////////////////// End Sub Public Function GetAdapter(ByVal index As Integer) As IFROW_HELPER Return m_Adapters(index) End Function <DebuggerStepThrough()> Private Function PrivToPub(ByVal pri As MIB_IFROW) As IFROW_HELPER Dim ifhelp As New IFROW_HELPER ifhelp.Name = pri.wszName.Trim ifhelp.Index = Convert.ToInt32(pri.dwIndex) ifhelp.Type = Convert.ToInt32(pri.dwType) ifhelp.Mtu = Convert.ToInt32(pri.dwMtu) ifhelp.Speed = Convert.ToInt32(pri.dwSpeed) ifhelp.PhysAddrLen = Convert.ToInt32(pri.dwPhysAddrLen) ifhelp.PhysAddr = System.Text.Encoding.ASCII.GetString(pri.bPhysAddr) ifhelp.AdminStatus = Convert.ToInt32(pri.dwAdminStatus) ifhelp.OperStatus = Convert.ToInt32(pri.dwOperStatus) ifhelp.LastChange = Convert.ToInt32(pri.dwLastChange) ifhelp.InOctets = Convert.ToInt32(pri.dwInOctets) ifhelp.InUcastPkts = Convert.ToInt32(pri.dwInUcastPkts) ifhelp.InNUcastPkts = Convert.ToInt32(pri.dwInNUcastPkts) ifhelp.InDiscards = Convert.ToInt32(pri.dwInDiscards) ifhelp.InErrors = Convert.ToInt32(pri.dwInErrors) ifhelp.InUnknownProtos = Convert.ToInt32(pri.dwInUnknownProtos) ifhelp.OutOctets = Convert.ToInt32(pri.dwOutOctets) ifhelp.OutUcastPkts = Convert.ToInt32(pri.dwOutUcastPkts) ifhelp.OutNUcastPkts = Convert.ToInt32(pri.dwOutNUcastPkts) ifhelp.OutDiscards = Convert.ToInt32(pri.dwOutDiscards) ifhelp.OutErrors = Convert.ToInt32(pri.dwOutErrors) ifhelp.OutQLen = Convert.ToInt32(pri.dwOutQLen) ifhelp.Description = System.Text.Encoding.ASCII.GetString(pri.bDescr, 0, Convert.ToInt32(pri.dwDescrLen)) ifhelp.InMegs = ToMegs(ifhelp.InOctets) ifhelp.OutMegs = ToMegs(ifhelp.OutOctets) Return ifhelp End Function <DebuggerStepThrough()> Private Function ToMegs(ByVal lSize As Long) As String Dim sDenominator As String = " B" 'If lSize > 1024 Then lSize = (lSize / 1024) * 1000 'Windows styleee filesizing :) If lSize > 1000 Then sDenominator = " KB" lSize = lSize / 1000 ElseIf lSize <= 1000 Then sDenominator = " B" lSize = lSize End If ToMegs = Format(lSize, "###,###0") & sDenominator End Function End Class Quote
Recommended Posts