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。

 

 

 

posted on 2024-04-15 17:31  TanZhiWei  阅读(215)  评论(0编辑  收藏  举报