网卡工作状态检测,效果如图(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 - 1 ] of Byte;
26 MIB_IFDESCR = array [ 0 ..MAXLEN_IFDESCR - 1 ] of Char;
27 PMIB_IFROW = ^MIB_IFROW;
28 MIB_IFROW = packed record
29 wszName: array [ 0 ..MAX_INTERFACE_NAME_LEN - 1 ] of 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 .. 0 ] of 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 stdcall ; external ' 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
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 - 1 ] of Byte;
26 MIB_IFDESCR = array [ 0 ..MAXLEN_IFDESCR - 1 ] of Char;
27 PMIB_IFROW = ^MIB_IFROW;
28 MIB_IFROW = packed record
29 wszName: array [ 0 ..MAX_INTERFACE_NAME_LEN - 1 ] of 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 .. 0 ] of 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 stdcall ; external ' 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
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