Windows网络桥接:事件无法调用任何订户 (异常来自 HRESULT:0x80040201)异常处理
开发Windows网络桥接使用接口Com组件:Interop.NETCONLib。设置成X64位时调用EnableSharing。出现一下异常
System.Runtime.InteropServices.COMException (0x80040201): 事件无法调用任何订户 (异常来自 HRESULT:0x80040201)
在 NETCONLib.INetSharingConfiguration.EnableSharing(tagSHARINGCONNECTIONTYPE Type)
在 MagicSettingService.NetShare.IcsManager.ShareConnection(INetConnection connectionToShare, INetConnection homeConnection) 位置 C:\Users\t25220\Desktop\网络\NetShareTool\NetShareTool\NetShare\IcsManager.cs:行号 99
在 MagicSettingService.NetShare.NetShareManager.<>c__DisplayClass21_0.<StartShareAsync>b__2() 位置 C:\Users\t25220\Desktop\网络\NetShareTool\NetShareTool\NetShare\NetShareManager.cs:行号 143
以为是EnableSharing函数有关。问题确实暴露在调用这个函数,通过定位发现是在取消共享分享时有问题。
复现步骤是先设置网络分享
1 在x86使用Wmi清楚网络共享
/// <summary> /// 清理之前的网络共享数据 /// </summary> public static void CleanupWMISharingEntries() { var scope = new ManagementScope("root\\Microsoft\\HomeNet"); scope.Connect(); var options = new PutOptions(); options.Type = PutType.UpdateOnly; var query = new ObjectQuery("SELECT * FROM HNet_ConnectionProperties"); var srchr = new ManagementObjectSearcher(scope, query); foreach (ManagementObject entry in srchr.Get()) { if ((bool)entry["IsIcsPrivate"]) entry["IsIcsPrivate"] = false; if ((bool)entry["IsIcsPublic"]) entry["IsIcsPublic"] = false; entry.Put(options); } }
2 调用Interop.NETCONLib 设置共享
/// <summary> /// 设置网络共享 /// </summary> /// <param name="connectionToShare"></param> /// <param name="homeConnection"></param> /// <exception cref="ArgumentException"></exception> public static void ShareConnection(INetConnection connectionToShare, INetConnection homeConnection) { if ((connectionToShare == homeConnection) && (connectionToShare != null)) throw new ArgumentException("选中共享网络连接不能为同一个"); CleanupWMISharingEntries(); if (connectionToShare != null) { var sc = GetConfiguration(connectionToShare); sc.EnableSharing(tagSHARINGCONNECTIONTYPE.ICSSHARINGTYPE_PUBLIC); } if (homeConnection != null) { var hc = GetConfiguration(homeConnection); hc.EnableSharing(tagSHARINGCONNECTIONTYPE.ICSSHARINGTYPE_PRIVATE); } }
在调用到EnableSharing正常,在x64 时候,则会出现 事件无法调用任何订户 (异常来自 HRESULT:0x80040201)
为了兼容X86和X64架构。取消网络共享使用DisableSharing接口
/// <summary> /// 停止当前的网络共享 /// </summary> public static void DisableSharing() { var share = GetCurrentlySharedConnections(); if (share.SharedConnection != null) GetConfiguration(share.SharedConnection).DisableSharing(); if (share.HomeConnection != null) GetConfiguration(share.HomeConnection).DisableSharing(); }
则调用正常
/// <summary> /// 设置网络共享 /// </summary> /// <param name="connectionToShare"></param> /// <param name="homeConnection"></param> /// <exception cref="ArgumentException"></exception> public static void ShareConnection(INetConnection connectionToShare, INetConnection homeConnection) { if ((connectionToShare == homeConnection) && (connectionToShare != null)) throw new ArgumentException("选中共享网络连接不能为同一个"); DisableSharing(); if (connectionToShare != null) { var sc = GetConfiguration(connectionToShare); sc.EnableSharing(tagSHARINGCONNECTIONTYPE.ICSSHARINGTYPE_PUBLIC); } if (homeConnection != null) { var hc = GetConfiguration(homeConnection); hc.EnableSharing(tagSHARINGCONNECTIONTYPE.ICSSHARINGTYPE_PRIVATE); } }
3 当网络共享时已经设置,未取消网络共享时,也会出现事件无法调用任何订户 (异常来自 HRESULT:0x80040201)。因此在x64下采用Wmi 清理不完全,和x86不一致,缺少清理逻辑。建议采用EnableSharing Api。