首页 > 解决方案 > 连接到 Internet 时由 Windows 发送的事件

问题描述

我需要在我的程序中知道何时恢复到互联网的连接。

实际上我可以检查它是否与类似的东西有关

CComPtr<INetworkListManager> pNLM;
HRESULT hr = CoCreateInstance(CLSID_NetworkListManager, NULL, CLSCTX_ALL, __uuidof(INetworkListManager), (LPVOID*)&pNLM);
if (SUCCEEDED(hr))
{
    VARIANT_BOOL isConnected;
    pNLM->get_IsConnectedToInternet(&isConnected);
    if (isConnected == VARIANT_TRUE)

但是我找不到一个很好的方法来通知连接已经恢复。对我来说,投票不是一个好方法。

我发现::NotifyAddrChange()了,但是只要在将 IPv4 地址映射到接口的表中发生更改,就会触发这种情况。

建立连接时是否发送特定事件?

标签: c++windowseventsnetworking

解决方案


感谢我的一位同事,我得到了答案。

这是将调用回调的类

#include "Event.h"

Event::Event(const std::function<void()>& cb)
    : methodTobeCalled(cb)
{
}

HRESULT Event::NetworkConnectionConnectivityChanged(GUID, NLM_CONNECTIVITY)
{
    if (methodTobeCalled)
        methodTobeCalled();

    return S_OK;
}

HRESULT Event::NetworkConnectionPropertyChanged(GUID, NLM_CONNECTION_PROPERTY_CHANGE)
{
    return S_OK;
}

STDMETHODIMP Event::QueryInterface(REFIID refIID, void** pIFace)
{
    HRESULT hr = S_OK;
    *pIFace = nullptr;
    if (IsEqualIID(refIID, IID_IUnknown))
    {
        *pIFace = (IUnknown *)this;
        ((IUnknown *)*pIFace)->AddRef();
    }
    else if (IsEqualIID(refIID, IID_INetworkConnectionEvents))
    {
        *pIFace = (INetworkConnectionEvents *)this;
        ((IUnknown *)*pIFace)->AddRef();
    }
    else
    {
        hr = E_NOINTERFACE;
    }

    return hr;
}

ULONG Event::AddRef(void)
{
    return static_cast<ULONG>(InterlockedIncrement(&m_ref));
}

ULONG Event::Release(void)
{
    LONG Result = InterlockedDecrement(&m_ref);
    return static_cast<ULONG>(Result);
}

在主类的ctor中(这里没有错误处理):

::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
::CoCreateInstance(CLSID_NetworkListManager, nullptr, CLSCTX_ALL, IID_INetworkListManager, (LPVOID *)&m_pNLM);
m_pNLM->QueryInterface(IID_IConnectionPointContainer, (void **)&m_pCpc);
m_pCpc->FindConnectionPoint(IID_INetworkConnectionEvents, &m_pConnectionPoint);
m_event = std::make_unique<NetworkEvent>(std::bind(&MainClass::methodTobeCalled, this));
hr = m_pConnectionPoint->Advise((IUnknown *)m_event.get(), &m_cookie);

需要的变量:

std::unique_ptr<NetworkEvent> m_event;
DWORD m_cookie;
CComPtr<IConnectionPoint> m_pConnectionPoint;
CComPtr<INetworkListManager> m_pNLM;
CComPtr<IConnectionPointContainer> m_pCpc;

将在每个网络事件中调用的方法将是

MainClass::methodTobeCalled()

在这种方法中,可以检查连接是否可用。O 可以检查 NetworkConnectionConnectivityChanged() 中的 NLM_CONNECTIVITY 标志


推荐阅读