网卡工作状态检测

 网卡工作状态检测,效果如图(Windows XP/2000/2003下测试通过):

点击在新窗口中浏览此图片
在这一实例中,计算机中有两块网卡,其中一块为无线网卡,另一块为8139的100M以太网卡,无线网卡已连接可上网,有线网卡我故意把网线拔了。从图中可以看出检测完全正确,而且更难能可贵的是检测速度非常快,几乎不占任何资源(CPU负荷几乎没有)。

实现单元

  1 unit AdpUtils;
  2 interface
  3 uses Windows;
  4 const
  5   MAX_INTERFACE_NAME_LEN = 256;
  6   MAXLEN_PHYSADDR = 8;
  7   MAXLEN_IFDESCR = 256;
  8   MIB_IF_TYPE_OTHER = 1;
  9   MIB_IF_TYPE_ETHERNET = 6;
 10   MIB_IF_TYPE_TOKENRING = 9;
 11   MIB_IF_TYPE_FDDI = 15;
 12   MIB_IF_TYPE_PPP = 23;
 13   MIB_IF_TYPE_LOOPBACK = 24;
 14   MIB_IF_TYPE_SLIP = 28;
 15   MIB_IF_ADMIN_STATUS_UP = 1;
 16   MIB_IF_ADMIN_STATUS_DOWN = 2;
 17   MIB_IF_ADMIN_STATUS_TESTING = 3;
 18   MIB_IF_OPER_STATUS_NON_OPERATIONAL = 0;
 19   MIB_IF_OPER_STATUS_UNREACHABLE = 1;
 20   MIB_IF_OPER_STATUS_DISCONNECTED = 2;
 21   MIB_IF_OPER_STATUS_CONNECTING = 3;
 22   MIB_IF_OPER_STATUS_CONNECTED = 4;
 23   MIB_IF_OPER_STATUS_OPERATIONAL = 5;
 24 type
 25   MIB_PHYSADDR = array[0..MAXLEN_PHYSADDR - 1of Byte;
 26   MIB_IFDESCR = array[0..MAXLEN_IFDESCR - 1of Char;
 27   PMIB_IFROW = ^MIB_IFROW;
 28   MIB_IFROW = packed record
 29     wszName: array[0..MAX_INTERFACE_NAME_LEN - 1of WCHAR;
 30     dwIndex,
 31     dwType,
 32     dwMtu,
 33     dwSpeed,
 34     dwPhysAddrLen: DWORD;
 35     bPhysAddr: MIB_PHYSADDR;
 36     dwAdminStatus,
 37     dwOperStatus,
 38     dwLastChange,
 39     dwInOctets,
 40     dwInUcastPkts,
 41     dwInNUcastPkts,
 42     dwInDiscards,
 43     dwInErrors,
 44     dwInUnknownProtos,
 45     dwOutOctets,
 46     dwOutUcastPkts,
 47     dwOutNUcastPkts,
 48     dwOutDiscards,
 49     dwOutErrors,
 50     dwOutQLen,
 51     dwDescrLen: DWORD;
 52     bDescr: MIB_IFDESCR;
 53   end;
 54   PMIB_IFTABLE = ^MIB_IFTABLE;
 55   MIB_IFTABLE = packed record
 56     dwNumEntries: DWORD;
 57     table: array[0..0of MIB_IFROW;
 58   end;
 59   TAdapterStatus = record
 60     dwType,
 61     dwOperStatus: DWORD;
 62     bDescr: MIB_IFDESCR;
 63   end;
 64   TAdapterStatuses = array of TAdapterStatus;
 65 function GetIfTable(pIfTable: PMIB_IFTABLE; pdwSize: PULONG; bOrder: BOOL): DWORD;
 66   stdcallexternal 'iphlpapi.dll';
 67 function GetAdapterTypeString(const dwType: DWORD): string;
 68 function GetGetAdapterStatusString(const dwOperStatus: DWORD): string;
 69 procedure ScanAdapters(var AdapterStatuses: TAdapterStatuses);
 70 implementation
 71 var
 72   dwSize: DWORD;
 73   pMibIfTable: PMIB_IFTABLE;
 74 function GetAdapterTypeString(const dwType: DWORD): string;
 75 begin
 76   case dwType of
 77     MIB_IF_TYPE_OTHER: Result := '其他';
 78     MIB_IF_TYPE_ETHERNET: Result := '以太网';
 79     MIB_IF_TYPE_TOKENRING: Result := '令牌环';
 80     MIB_IF_TYPE_FDDI: Result := 'FDDI';
 81     MIB_IF_TYPE_PPP: Result := 'PPP';
 82     MIB_IF_TYPE_LOOPBACK: Result := '回路';
 83     MIB_IF_TYPE_SLIP: Result := 'SLIP';
 84   end;
 85 end;
 86 function GetGetAdapterStatusString(const dwOperStatus: DWORD): string;
 87 begin
 88   case dwOperStatus of
 89     MIB_IF_OPER_STATUS_NON_OPERATIONAL: Result := '掉线';
 90     MIB_IF_OPER_STATUS_UNREACHABLE: Result := '不可达';
 91     MIB_IF_OPER_STATUS_DISCONNECTED: Result := '断开';
 92     MIB_IF_OPER_STATUS_CONNECTING: Result := '连接中';
 93     MIB_IF_OPER_STATUS_CONNECTED: Result := '已连接';
 94     MIB_IF_OPER_STATUS_OPERATIONAL: Result := '连通';
 95   end;
 96 end;
 97 procedure ScanAdapters(var AdapterStatuses: TAdapterStatuses);
 98 var
 99   dwRetVal: DWORD;
100   num, i: Longint;
101 begin
102   dwRetVal := GetIfTable(pMibIfTable, @dwSize, False);
103   if dwRetVal = NO_ERROR then
104   begin
105     num := pMibIfTable^.dwNumEntries;
106     if Length(AdapterStatuses) <> num then
107       SetLength(AdapterStatuses, num);
108     for i := Low(AdapterStatuses) to High(AdapterStatuses) do
109     begin
110       AdapterStatuses[i].dwType := pMibIfTable^.table[i].dwType;
111       AdapterStatuses[i].dwOperStatus := pMibIfTable^.table[i].dwOperStatus;
112       AdapterStatuses[i].bDescr := pMibIfTable^.table[i].bDescr;
113     end;
114   end;
115 end;
116 initialization
117   GetIfTable(nil, @dwSize, False);
118   GetMem(pMibIfTable, dwSize);
119   
120 finalization
121   FreeMem(pMibIfTable);
122 end.
123 

调用实例

 1 unit MainForm;
 2 interface
 3 uses
 4   Classes, Controls, Forms, ExtCtrls, ComCtrls, AdpUtils;
 5 type
 6   TfrmMain = class(TForm)
 7     tmRefresh: TTimer;
 8     lvAdapters: TListView;
 9     procedure tmRefreshTimer(Sender: TObject);
10   private
11     FAdapterStatuses: TAdapterStatuses;
12     FAdapterNum: Integer;
13     procedure RefreshAdapterStatuses;
14   public
15     { Public declarations }
16   end;
17 var
18   frmMain: TfrmMain;
19 implementation
20 {$R *.dfm}
21 procedure TfrmMain.RefreshAdapterStatuses;
22 var
23   num, i: Integer;
24 begin
25   ScanAdapters(FAdapterStatuses);
26   num := Length(FAdapterStatuses);
27   if num = FAdapterNum then
28   begin
29     for i := 0 to num - 1 do
30       lvAdapters.Items[i].SubItems[1] := GetGetAdapterStatusString(FAdapterStatuses[i].dwOperStatus);
31   end
32   else begin
33     lvAdapters.Items.BeginUpdate;
34     lvAdapters.Items.Clear;
35     for i := 0 to num - 1 do
36     begin
37       lvAdapters.Items.Add;
38       lvAdapters.Items[i].Caption := GetAdapterTypeString(FAdapterStatuses[i].dwType);
39       lvAdapters.Items[i].SubItems.Add(FAdapterStatuses[i].bDescr);
40       lvAdapters.Items[i].SubItems.Add(GetGetAdapterStatusString(FAdapterStatuses[i].dwOperStatus));
41     end;
42     lvAdapters.Items.EndUpdate;
43     FAdapterNum := num;
44   end;
45 end;
46 procedure TfrmMain.tmRefreshTimer(Sender: TObject);
47 begin
48   RefreshAdapterStatuses;
49 end;
50 end.  
51 


谢祥选【小宇飞刀(xieyunc)】
原文地址:https://www.cnblogs.com/xieyunc/p/1447448.html