C++ 如何从Windows应用程序检测禁用的网络接口连接?
我想知道什么时候界面被禁用了 如果我进入windows管理器并禁用2个已启用连接中的一个,GetIfTable()只返回1个接口的状态,它将不再看到断开连接的接口。 (返回1个表) 我如何才能得到返回的内容,即禁用的界面仍然存在,但当前已禁用 谢谢C++ 如何从Windows应用程序检测禁用的网络接口连接?,c++,windows,winapi,networking,wmi,C++,Windows,Winapi,Networking,Wmi,我想知道什么时候界面被禁用了 如果我进入windows管理器并禁用2个已启用连接中的一个,GetIfTable()只返回1个接口的状态,它将不再看到断开连接的接口。 (返回1个表) 我如何才能得到返回的内容,即禁用的界面仍然存在,但当前已禁用 谢谢 我想您只需要阅读注册表 例如,这是在web上找到的关于事物应该是什么样子的片段: [HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Network\{4D36E972-E325-11CE-BFC1-08
我想您只需要阅读注册表 例如,这是在web上找到的关于事物应该是什么样子的片段:
[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Network\{4D36E972-E325-11CE-BFC1-08002BE10318}\{1E6AF554-25FF-40FC-9CEE-EB899472C5A3}\Connection]
"PnpInstanceID"="PCI\\VEN_14E4&DEV_1696&SUBSYS_12BC103C&REV_03\\4&3A321F38&0&10F0"
"MediaSubType"=dword:00000001
"Name"="Lan Name"
"ShowIcon"=dword:00000000
"IpCheckingEnabled"=dword:00000001
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Network\{4D36E972-E325-11CE-BFC1-08002BE10318}\{1E6AF554-25FF-40FC-9CEE-EB899472C5A3}\Connection]
"PnpInstanceID"="PCI\\VEN_14E4&DEV_1696&SUBSYS_12BC103C&REV_03\\4&3A321F38&0&10F0"
"MediaSubType"=dword:00000001
"Name"="Lan Name"
"ShowIcon"=dword:00000000
"IpCheckingEnabled"=dword:00000001
IP_适配器_地址结构包含操作状态成员。 看 我认为它可以用来检测禁用的NIC。我没有试过 下面是一个测试代码:
ULONG nFlags= 0;
if (WINVER>=0x0600) // flag supported in Vista and later
nFlags= 0x0100; // GAA_FLAG_INCLUDE_ALL_INTERFACES
// during system initialization, GetAdaptersAddresses may return ERROR_BUFFER_OVERFLOW and supply nLen,
// but in a subsequent call it may return ERROR_BUFFER_OVERFLOW and supply greater nLen !
ULONG nLen= sizeof (IP_ADAPTER_ADDRESSES);
BYTE* pBuf= NULL;
DWORD nErr= 0 ;
do
{
delete[] pBuf;
pBuf= new BYTE[nLen];
nErr= ::GetAdaptersAddresses(AF_INET, nFlags, NULL, (IP_ADAPTER_ADDRESSES*&)pBuf, &nLen);
}
while (ERROR_BUFFER_OVERFLOW == nErr);
if (NO_ERROR != nErr)
{
delete[] pBuf;
TCHAR czErr[300]= _T("GetAdaptersAddresses failed. ");
REPORT(REP_ERROR, _T("GetAdapterInfo"), GetSysErrStr(nErr, czErr, 300));
return false;
}
const IP_ADAPTER_ADDRESSES* pAdaptersAddresses= (IP_ADAPTER_ADDRESSES*&)pBuf;
while (pAdaptersAddresses) // for each adapter
{
TCHAR czAdapterName [500]; str_cpy(czAdapterName , 500, pAdaptersAddresses->AdapterName );
TCHAR czDesc [500]; str_cpy(czDesc , 500, pAdaptersAddresses->Description );
TCHAR czFriendlyName[500]; str_cpy(czFriendlyName, 500, pAdaptersAddresses->FriendlyName);
const IF_OPER_STATUS& Stat= pAdaptersAddresses->OperStatus; // 1:up, 2:down...
...
pAdaptersAddresses= pAdaptersAddresses->Next;
}
如何使用中所示的
netcon.h
中的接口?该示例中的代码以编程方式启用和禁用接口,但我做了一些修改,以便您可以查询状态:
#include <netcon.h>
// wszName is the name of the connection as appears in Network Connections folder
// set bEnable to true to enable and to false to disable
bool GetConnectionStatus(LPCWSTR wszName, bool *status)
{
bool result = false;
if (!status)
return false;
typedef void (__stdcall * LPNcFreeNetconProperties)(NETCON_PROPERTIES* pProps);
HMODULE hmod = LoadLibrary("netshell.dll");
if (!hmod)
return false;
LPNcFreeNetconProperties NcFreeNetconProperties =
(LPNcFreeNetconProperties)GetProcAddress(hmod, "NcFreeNetconProperties");
if (!NcFreeNetconProperties )
return false;
INetConnectionManager * pMan = 0;
HRESULT hres = CoCreateInstance(CLSID_ConnectionManager,
0,
CLSCTX_ALL,
__uuidof(INetConnectionManager),
(void**)&pMan);
if (SUCCEEDED(hres))
{
IEnumNetConnection * pEnum = 0;
hres = pMan->EnumConnections(NCME_DEFAULT, &pEnum);
if (SUCCEEDED(hres))
{
INetConnection * pCon = 0;
ULONG count;
while (pEnum->Next(1, &pCon, &count) == S_OK && !done)
{
NETCON_PROPERTIES * pProps = 0;
hres = pCon->GetProperties(&pProps);
if (SUCCEEDED(hres))
{
if (wcscmp(pProps->pszwName,wszName) == 0)
{
*status = pProps->Status == NCS_CONNECTED;
}
NcFreeNetconProperties(pProps);
}
pCon->Release();
}
pEnum->Release();
}
pMan->Release();
}
FreeLibrary(hmod);
return result;
}
#包括
//wszName是网络连接文件夹中显示的连接名称
//将bEnable设置为true可启用,设置为false可禁用
bool GetConnectionStatus(LPCWSTR wszName,bool*状态)
{
布尔结果=假;
如果(!状态)
返回false;
typedef void(uu stdcall*LPNcFreeNetconProperties)(NETCON_PROPERTIES*pProps);
HMODULE hmod=LoadLibrary(“netshell.dll”);
如果(!hmod)
返回false;
LPNcFreeNetconProperties NcFreeNetconProperties=
(LPNcFreeNetconProperties)GetProcAddress(hmod,“NcFreeNetconProperties”);
如果(!NcFreeNetconProperties)
返回false;
INetConnectionManager*pMan=0;
HRESULT hres=CoCreateInstance(CLSID_ConnectionManager,
0,
CLSCTX_ALL,
__uuidof(iNet连接管理器),
(void**)和pMan);
如果(成功(hres))
{
IEnumNetConnection*pEnum=0;
hres=pMan->EnumConnections(NCME\u默认值,&pEnum);
如果(成功(hres))
{
INetConnection*pCon=0;
乌龙计数;
而(pEnum->Next(1,&pCon,&count)==S_确定&&!完成)
{
NETCON_属性*pProps=0;
hres=pCon->GetProperties(&pProps);
如果(成功(hres))
{
如果(wcscmp(pProps->pszwName,wszName)==0)
{
*状态=pProps->status==NCS\U已连接;
}
NcFreeNetconProperties(pProps);
}
pCon->Release();
}
pEnum->Release();
}
pMan->Release();
}
免费图书馆;
返回结果;
}
另一个选项是使用WMI类,检查NetConnectionStatus
和NetEnabled
属性。根据,您可以查询WMI以获取此信息(此处提供了C代码)
使用C++查询WMI,请参阅以下两个链接:
wmic NIC where(ConfigManagerErrorCode=22)get Description,Index,NetConnectionID,PNPDeviceID
输出:
Description Index NetConnectionID PNPDeviceID
Broadcom 802.11g Network Adapter 8 WiFi PCI\VEN_14E4&DEV_4320&SUBSYS_041814E4&REV_03\4&31B6CD7&0&00F0
1394 Net Adapter 13 1394 V1394\NIC1394\1B9E0F31E8C00
TAP-Win32 Adapter V9 14 Steganos Internet Anonym 2012 VPN Adapter ROOT\NET\0000
VirtualBox Host-Only Ethernet Adapter 24 VirtualBox Host-Only Network ROOT\NET\0001
这里的哪个字段是dis/enabled状态?我从内存中不知道,而且我不靠近任何windows PC。我希望你能找到更多关于这个指针的信息。。。关于这一点,现在我认为基于PnpInstanceId的信息,您应该在HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\PCI中找到驱动程序信息,在那里您应该可以看到ConfigFlags key。如果设置为0,则NIC卡在1禁用时启用。我记不太清楚这一点,但我认为首先必须调用RegOpenKeyEx函数以获取密钥,然后使用该密钥必须调用RegQueryValueEx以获取特定值。请检查如此古老的问题和MSDN文档如何准确地调用这些函数。不幸的是,这里没有任何内容表明已启用。我尝试了这个方法,它的行为与GetIfTable()相同,只返回一个nic的状态(链表)…我希望至少能用IF_OPER_状态返回信息…循环中没有使用'done'变量-复制/粘贴问题:-)如果你发现这个WMI类给你想要的状态,请注意,WMI确实为您提供了“轮询服务”,以定期检查值是否已更改。请看一看(但如果您正在将其构建到应用程序中,请小心,因为您可能会发现WMI轮询虽然看起来很简单,但却很重要。)