如何从Windows应用程序检测禁用的网络接口连接?

问题描述:

我想知道一个接口何时被禁用。如何从Windows应用程序检测禁用的网络接口连接?

如果我进入Windows管理器并禁用其中一个启用的连接,则GetIfTable()仅返回约1个接口的状态,它不会再看到已断开连接的状态。 (返回1个表)

我怎样才能得到的东西,以返回残疾人界面仍然存在目前禁用?

谢谢。

http://msdn.microsoft.com/en-us/library/aa365943%28VS.85%29.aspx

我想你只需要读取注册表。

例如,这是事物应该是什么样子的网站上发现了一个片段:

[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 
+0

这里的哪个字段是dis/enabled状态? – 2011-05-06 22:13:41

+1

我不知道从记忆中,我不在任何Windows PC的附近。我希望你可以找到更多关于这个指针的信息......现在就对此进行评论 – sehe 2011-05-06 22:16:24

+1

我想根据来自PnpInstanceId的信息,你应该在HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ Enum \ PCI中找到驱动程序信息,你应该看到ConfigFlags键。如果设置为0,则禁用1禁用NIC卡。 – Zuljin 2011-05-06 22:58:27

的IP_ADAPTER_ADDRESSES结构持有OperStatus成员。 请参阅MSDN documentation

我认为它可以用来检测禁用的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; 
} 
+0

不幸的是,这里没有任何内容表示启用。我试过这种方法,它的行为与GetIfTable()只返回一个nic的状态(链接列表)相同...我期望至少用IF_OPER_STATUS返回信息.... – 2011-05-09 20:44:57

如何使用从netcon.h接口,如this example说明?在该示例中的代码启用和禁用程序的界面,但我已经做了一些修改,让你可以查询状态改为:

#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; 
} 
+0

好吧,我会检查出来,谢谢... – 2011-05-09 21:20:21

+0

'done'变量不用于循环 - 复制/粘贴问题:-) – 2011-05-13 07:21:21

另一种选择是使用Win32_NetworkAdapter WMI类,检查NetConnectionStatusNetEnabled性质。

+0

如果您发现此WMI类为您提供了所需的状态,请注意,WMI确实为您提供了“轮询服务“来定期检查值是否已经改变。看一看[__InstanceModificationEvent](http://technet.microsoft.com/en-us/library/ee156572.aspx)(但是如果你将它建立到一个应用程序中,要小心,因为你可能会发现WMI轮询是尽管表面简单,但重量很重。) – Daryn 2013-05-27 23:34:02

根据this CodeGuru forum message,您可以向WMI查询此信息(此处提供了C#代码)。

要查询WMI使用C++,看这两个环节:

命令行:

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