网卡工作状态检测,效果如图(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