• WMI调用发生 InitializationFailure 错误的解决过程


    调用 WMI 接口是获取系统信息的常用手段。本人在一个项目中需要获取本机的网卡信息,自然而然地就采用 WMI 调用的方式,代码也非常简洁。程序部署在绝大多数的客户机器上都运行得非常顺利,但在其中一台机器上却由于调用WMI而抛出 ManagementException,ErrorCode 为 InitializationFailure ,中文提示为“初始化失败”。由于是初次使用 WMI ,解决问题着实花了一番功夫,故在此记录问题的解决过程,为遇到类似问题的时提供参考。

    先看通过WMI获取网卡信息的C#代码:

    获取网卡MAC和IP地址
    1 try
    2 {
    3 List<NetworkAdapterConfiguration> nacfgList = new List<NetworkAdapterConfiguration>();
    4 ManagementClass mc = new
    5 ManagementClass("Win32_NetworkAdapterConfiguration");
    6 ManagementObjectCollection moc2 = mc.GetInstances();
    7 NetworkAdapterConfiguration nacfg;
    8 foreach (ManagementObject mo in moc2)
    9 {
    10 if ((bool)mo["IPEnabled"] == true)
    11 {
    12 nacfg = new NetworkAdapterConfiguration();
    13 nacfg._macAddress = mo["MacAddress"].ToString();
    14 nacfg._ipAddress = (string[])mo["IPAddress"];
    15 nacfgList.Add(nacfg);
    16
    17 mo.Dispose();
    18 }
    19 }
    20 return nacfgList.ToArray();
    21 }
    22 catch (ManagementException ex)
    23 {
    24 Logger.Error("=========Get NetwordAdapterConfiguration=========");
    25 Logger.Error(ex);
    26 Logger.Error("=== Data:{0}", ex.Data == null ? "null" : ex.Data.ToString());
    27
    28 Logger.Error("=== ErrorCode:{0}", ex.ErrorCode);
    29 Logger.Error("=== ErrorInformation:{0}", ex.ErrorInformation);
    30 Logger.Error("=== HelpLink:{0}", ex.HelpLink);
    31 throw;
    32 }

    错误是在第 6 行 ManagementObjectCollection moc2 = mc.GetInstances(); 抛出 ManagementException,ErrorCode 为 InitializationFailure 。

    经查MSDN,InitializationFailure 是.NET命名空间 System.Management 中的 ManagementStatus 枚举值之一,对该值的说明是:组件(如提供程序)由于内部原因未能初始化。

    但如何解决问题呢?在MSDN中没有找到答案,只好寻求百度帮忙。

    一番查找之后,终于了解了 WMI 的体系结构,以下是转载的WMI体系结构说明:

     

    Windows管理规范WMI的四层结构(由低到高)

    • 托管系统(管理系统)是数据来源,通常是操作系统、服务、应用程序、设备驱动、网络、打印机等。
    • 提供程序作为托管系统与上层的公共信息模型对象管理器CIMOM间的中间层,为上层提取下层的相关信息、触发事件,为下层生成事件通知,并将管理信息和接口映射到CIM库的类上。
    • 公共信息模型对象管理器CIMOM是公共信息模型CIM储存库的管理接口。CIM储存库是一个面向对象的数据库,这些对象间可以建立关联,开发人员也可以在现有环境中添加新的类来表示新的托管对象。两者统一由WinMGMT表示,通过一组COM接口进行访问。而这个CIMOM又相当于上层使用者的代理。
    • 使用者就是系统管理应用程序(如 Microsoft Systems Management Server)或者第三方的应用程序或者脚本,它就是最终要向用户显示托管系统相关信息的程序。

    如图

    WMI的体系结构

    根据一些资料的提示,InitializationFailure 有可能是 CIM 储存库已损坏导致的,于是朝着这个方向进行尝试,进行 CIM 储存库的重建。

    重建过程操作如下:

    1. 停止 WMI 服务
      WMI在系统中表现为一个系统服务 winmgmt(显示名称:Windows Management Instrumentation),要进行 WMI 调用必须启动该服务。
      注:系统中的杀毒软件、防火墙或者其它的服务有可能会依赖于该服务,停止winmgmt服务时,必须先停止这些依赖服务。
    2. 移除原来的存储库
      可以在控制台输入以下命令,通过重命名 Repository 目录的方式移除原来的储存库。
          cd /d %windir%\system32\wbem
          rename Repository Rep_bak
    3. 执行 Mofcmp 命令,重新编译 wbem 目录下的 mof 和 mfl 文件
      Mofcomp.exe 是一个操作系统工具,用于编译 MOF 文件,并将文件中包含的信息添加到 WMI 的存储库中。
      在控制台输入以下命令:
          cd /d %windir%\system32\wbem
          for %i in (*.mof,*.mfl) do Mofcomp %i
      命令执行成功后,存储库即完成重建。

    执行完重建操作后,重新运行程序,WMI 调用恢复正常,至此,问题成功解决!

    参考资料:

      1、WMI问题全解(Windows管理规范)<转>

  • 相关阅读:
    echarts图表重设尺寸
    文本文档中各字母出现次数汇总(java)
    30道随机运算
    随机生成验证码
    原码,反码,补码
    动手动脑(一)
    模拟银行ATM系统(基础版)
    2018暑期周总结报告(五)
    2018暑期周总结报告(四)
    2018暑期周总结报告(三)
  • 原文地址:https://www.cnblogs.com/haiq/p/1935556.html
Copyright © 2020-2023  润新知