You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Windows MAUI应用中监听系统互联网连接建立通知?

解决Windows MAUI中监听互联网连接状态的问题

实现思路的正确性

你的方向是对的:NetworkListManager搭配INetworkConnectionEvents是Windows系统层面精准监听网络连接(含互联网可达性)的正确方案,确实能区分「仅连路由器」和「连入互联网」的状态,比NetworkChange的IP地址变更事件更贴合需求。

事件未触发的常见原因及修复方案

1. 接收器实例被GC回收

MAUI中如果接收器是局部变量,会被垃圾回收机制销毁,导致事件无法触发。必须将接收器和NetworkListManager实例声明为全局字段(比如页面类的成员变量):

private NetworkListManager _networkListManager;
private NetworkConnectionEventsReceiver _eventReceiver;
private uint _cookie;

2. 未完成完整的事件注册流程

实例化后必须调用Advise完成注册,且页面销毁时要调用Unadvise取消注册,示例核心代码:

private void InitializeNetworkMonitoring()
{
    _networkListManager = new NetworkListManager();
    _eventReceiver = new NetworkConnectionEventsReceiver();
    int hr = _networkListManager.Advise(_eventReceiver, out _cookie);
    if (hr != 0)
    {
        Marshal.ThrowExceptionForHR(hr);
    }
}

protected override void OnDisappearing()
{
    base.OnDisappearing();
    if (_networkListManager != null && _cookie != 0)
    {
        _networkListManager.Unadvise(_cookie);
        _cookie = 0;
    }
}

3. 接收器类未标记COM可见性

因为NetworkListManager是COM组件,接收器类必须添加[ComVisible(true)]特性,否则COM无法识别:

[ComVisible(true)]
public class NetworkConnectionEventsReceiver : INetworkConnectionEvents
{
    // 接口实现代码
}

4. 未实现接口全部方法

INetworkConnectionEvents包含多个方法,必须全部实现(空实现也可以),否则COM交互会出错:

public void NetworkConnectionConnectivityChanged(Guid connectionId, NLM_CONNECTIVITY newConnectivity)
{
    bool hasInternet = (newConnectivity & (NLM_CONNECTIVITY.NLM_CONNECTIVITY_IPV4_INTERNET | NLM_CONNECTIVITY.NLM_CONNECTIVITY_IPV6_INTERNET)) != 0;
    // 处理连接状态变化逻辑
}

// 必须实现的其他接口方法
public void NetworkConnectionPropertyChanged(Guid connectionId, NLM_CONNECTION_PROPERTY_CHANGE flags) { }

5. 权限配置缺失(MSIX打包场景)

如果应用打包成MSIX,需要在Package.appxmanifest中添加网络相关权限:

<Capabilities>
    <Capability Name="internetClient" />
    <Capability Name="privateNetworkClientServer" />
</Capabilities>

可选优化:监听全局网络状态

如果需要监听整个系统的互联网可达性而非单个连接,可改用INetworkListManagerEvents接口的ConnectivityChanged方法,触发时机更贴合「系统联网状态变更」的需求:

[ComVisible(true)]
public class NetworkListEventsReceiver : INetworkListManagerEvents
{
    public void ConnectivityChanged(NLM_CONNECTIVITY newConnectivity)
    {
        bool hasInternet = (newConnectivity & (NLM_CONNECTIVITY.NLM_CONNECTIVITY_IPV4_INTERNET | NLM_CONNECTIVITY.NLM_CONNECTIVITY_IPV6_INTERNET)) != 0;
        // 处理全局联网状态变化
    }
}

总结

你的实现方向正确,事件未触发大概率是「接收器被回收」「注册流程不完整」「接口方法未全实现」这几个原因导致的,按照上述步骤调整后即可解决问题。

内容的提问来源于stack exchange,提问作者user7421317

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 16:40:08