在 XML 中表示对象

WMI 中的 XML 编码器组件可生成对象的 XML 表示形式。

在 C++ 中,可以通过调用 IWbemObjectTextSrc.GetText 方法来启动 XML 编码器,指定要用 XML 表示的对象以及在表示形式中使用的文本格式。 有关详细信息和代码示例,请参阅“使用 C/C++ 对 XML 中的对象进行编码”。

在 VBScript 或 Visual Basic 中,若要对 XML 实例的数据进行编码,请调用 SWbemObjectEx.GetText。 有关详细信息和代码示例,请参阅“使用 VBScript 对 XML 中的对象进行编码”。

本主题包括以下部分:

使用 C 或 C++ 对对象进行编码

以下过程介绍如何使用 C 或 C++ 对 XML 中的对象进行编码。

使用 C 或 C++ 对 XML 中的对象进行编码

  1. 设置程序以访问 WMI 数据。

    由于 WMI 基于 COM 技术,因此必须必要调用 CoInitializeExCoInitializeSecurity 函数才能访问 WMI。 有关详细信息,请参阅初始化 WMI 应用程序的 COM

  2. (可选)创建 IWbemContext 对象并初始化。

    无需创建 IWbemContext 对象,除非需要更改默认操作。 XML 编码器使用上下文对象来控制对象 XML 表示形式中包含的信息量。

    下表列出了可以为上下文对象指定的可选值。

    值/类型 含义
    "LocalOnly" VT_BOOL 如果为 TRUE,则生成的 XML 中仅存在类中本地定义的属性和方法。 默认值为 FALSE
    "IncludeQualifiers" VT_BOOL 如果为 TRUE,则生成的 XML 中包含类、实例、属性和方法限定符。 默认值为 FALSE
    "ExcludeSystemProperties" VT_BOOL 如果为 TRUE,则从输出中筛选掉 WMI 系统属性。 默认值为 FALSE
    "PathLevel" VT_I4
    0 = <生成 CLASS> 或 <INSTANCE> 元素。
    1 = 值 <。生成 NAMEDOBJECT> 元素。
    2 = 值 <。生成 OBJECTWITHLOCALPATH> 元素。
    3 = 值 <。生成 OBJECTWITHPATH> 。
    默认值为 0(零)。

    下面的代码示例演示如何初始化上下文对象以包含限定符和排除系统属性。

    VARIANT vValue;
    IWbemContext *pContext = NULL;
    HRESULT hr = CoCreateInstance (CLSID_WbemContext, 
                           NULL, 
                           CLSCTX_INPROC_SERVER,
                           IID_IWbemContext, 
                           (void**) &pContext);
    if (FAILED(hr))
    {
      printf("Create context failed with %x\n", hr);
      return hr;
    }
    
    // Generate a <VALUE.OBJECTWITHLOCALPATH> element
    VariantInit(&vValue);
    vValue.vt = VT_I4;
    vValue.lVal = 2;
    pContext->SetValue(L"PathLevel", 0, &vValue);
    VariantClear(&vValue);
    
    // Include qualifiers
    VariantInit(&vValue);
    vValue.vt = VT_BOOL;
    vValue.boolVal = VARIANT_TRUE;
    pContext->SetValue(L"IncludeQualifiers", 0, &vValue);
    VariantClear(&vValue);
    
    // Exclude system properties
    VariantInit(&vValue);
    vValue.vt = VT_BOOL;
    vValue.boolVal = VARIANT_TRUE;
    pContext->SetValue(L"ExcludeSystemProperties", 0, &vValue);
    VariantClear(&vValue);
    
  3. 获取对要以 XML 编码的类或实例的引用。

    初始化 COM 并连接到 WMI 后,调用 GetObject 以检索对指定类或实例的引用。 如果使用 BSTR 指定类或实例,请调用 SysFreeString 以释放 SysAllocString 分配的内存。

    下面的代码示例检索对 Win32_LogicalDisk 实例的引用。

    HRESULT hr = NULL;
    IWbemClassObject *pClass = NULL;
    BSTR strObj = SysAllocString(L"Win32_LogicalDisk");
    
    hr = pConnection->GetObject(strObj, 
                                0, 
                                NULL, 
                                &pClass, 
                                NULL);
    
    SysFreeString(strObj);
    if (FAILED(hr))
    {
      printf("GetObject failed with %x\n",hr)
      return hr;
    }
    
  4. 创建 IWbemObjectTextSrc 对象。

    获取了对对象的引用后,必须通过调用 CoCreateInstance 创建 IWbemObjectTextSrc 对象。 IWbemObjectTextSrc 对象用于生成实际的 XML 文本。

    下面的代码示例演示如何通过调用 CoCreateInstance 创建 IWbemObjectTextSrc 对象。

    HRESULT hr = NULL;
    IWbemObjectTextSrc *pSrc = NULL;
    
    hr = CoCreateInstance (CLSID_WbemObjectTextSrc, 
                           NULL,
                           CLSCTX_INPROC_SERVER,
                           IID_IWbemObjectTextSrc, 
                           (void**) &pSrc);
    
    if (FAILED(hr))
    {
        printf("CoCreateInstance of IWbemObjectTextSrc failed %x\n",hr);
        return hr;
    }
    
  5. 调用 IWbemObjectTextSrc.GetText 方法以获取对象的 XML 表示形式。

    设置对象的表示形式的上下文、获取对对象的引用并创建 IWbemObjectTextSrc 对象后,即可通过调用 IWbemObjectTextSrc.GetText 方法生成指定对象的 XML 表示形式。

    以下 C++ 示例代码生成 pClass 引用的对象的 XML 表示形式。 XML 表示形式在 strText 中返回。 GetText 的第三个参数指定要用于 XML 的文本格式,并且必须是 WMI_OBJ_TEXT_CIM_DTD_2_0 (0x1) 或WMI_OBJ_TEXT_WMI_DTD_2_0 (0x2)。 有关这些值的更多信息,请参阅 IWbemObjectTextSrc::GetText 参数值。

    HRESULT hr = NULL;
    BSTR strText = NULL;
    hr = pSrc->GetText(0, 
                       pClass, 
                       WMI_OBJ_TEXT_CIM_DTD_2_0,
                       pContext, 
                       &strText);
    
    // Perform a task with strText
    SysFreeString(strText);
    
    if (FAILED(hr))
    {
      printf("GetText failed with %x\n", hr);
      return hr;
    }
    

以下 C++ 示例代码包括上一过程中的所有步骤,并在 XML 中对 Win32_LogicalDisk 类进行编码,包括类、属性和方法限定符,不包括系统属性。

// The following #define statement is needed so that 
// the proper values are loaded by the #include files.
#define _WIN32_WINNT 0x0500

#include <stdio.h>
#include <wbemcli.h>
#pragma comment(lib, "wbemuuid.lib")

// Initialize the context object
// ---------------------------------------------
void FillUpContext(IWbemContext *pContext)
{
  VARIANT vValue;

  // IncludeQualifiers
  VariantInit(&vValue);
  vValue.vt = VT_BOOL;
  vValue.boolVal = VARIANT_FALSE;
  pContext->SetValue(L"IncludeQualifiers", 0, &vValue);
  VariantClear(&vValue);

  VariantInit(&vValue);
  vValue.vt = VT_I4;
  vValue.lVal = 0;
  pContext->SetValue(L"PathLevel", 0, &vValue);
  VariantClear(&vValue);

  // ExcludeSystemProperties
  VariantInit(&vValue);
  vValue.vt = VT_BOOL;
  vValue.boolVal = VARIANT_TRUE;
  pContext->SetValue(L"ExcludeSystemProperties", 0, &vValue);
  VariantClear(&vValue);
}

// Main method ... drives the program
// ---------------------------------------------
int _cdecl main(int argc, char * argv[])
{
  BSTR strNs = NULL;
  BSTR strObj = NULL;
  BSTR strText = NULL;

  if(FAILED(CoInitialize(NULL)))
    return 1;
  HRESULT hr = E_FAIL;
  IWbemObjectTextSrc *pSrc = NULL;

  IWbemLocator *pL = NULL;
  if(SUCCEEDED(hr = CoCreateInstance (CLSID_WbemLocator, 
                                      NULL, 
                                      CLSCTX_INPROC_SERVER,
                                      IID_IWbemLocator, 
                                      (void**) &pL)))
  {
    // Create a context object
    IWbemContext *pContext = NULL;
    if(SUCCEEDED(hr = CoCreateInstance (CLSID_WbemContext, 
                                        NULL, 
                                        CLSCTX_INPROC_SERVER,
                                        IID_IWbemContext, 
                                        (void**) &pContext)))
    {
      FillUpContext(pContext);
      IWbemServices *pConnection = NULL;
      strNs = SysAllocString(L"root\\cimv2");
      strText = NULL;
      if(SUCCEEDED(hr = pL->ConnectServer(strNs, 
                                          NULL, 
                                          NULL, 
                                          NULL, 
                                          0, 
                                          NULL, 
                                          NULL, 
                                          &pConnection)))
      {
        IWbemClassObject *pClass = NULL;
        strObj = SysAllocString(L"Win32_LogicalDisk");

        if(SUCCEEDED(hr = CoCreateInstance (CLSID_WbemObjectTextSrc, 
                                            NULL,
                                            CLSCTX_INPROC_SERVER,
                                            IID_IWbemObjectTextSrc, 
                                            (void**) &pSrc)))
        {
          // Test for GetObject
          if(SUCCEEDED(hr = pConnection->GetObject(strObj, 
                                                   0, 
                                                   NULL, 
                                                   &pClass, 
                                                   NULL)))
          {
            if(SUCCEEDED(hr = pSrc->GetText(0, 
                                            pClass, 
                                            WMI_OBJ_TEXT_CIM_DTD_2_0,
                                            pContext, 
                                            &strText)))
            {
              printf("GETOBJECT SUCCEEDED\n");
              printf("==========================================\n");
              wprintf(strText);
              pContext->Release();
              pClass->Release();
            }
            else
            {
              printf("GetText failed with %x\n", hr);
              // Free up the object
              pContext->Release();
              pClass->Release();
            }
          }
          else
            printf("GetObject failed with %x\n", hr);
        }
        else
          printf("CoCreateInstance on WbemObjectTextSrc failed with %x\n", hr);
      }
      else
        printf("ConnectServer on root\\cimv2 failed with %x\n", hr);
    }
    else
      printf("CoCreateInstance on Context failed with %x\n", hr);
  }
  else
    printf("CoCreateInstance on Locator failed with %x\n", hr);

// Clean up memory
  if (strNs != NULL)
    SysFreeString(strNs);
  if (strObj != NULL)
    SysFreeString(strObj);
  if (strText != NULL)
    SysFreeString(strText);
  if (pSrc != NULL)
    pSrc->Release();
  if (pL != NULL)
    pL->Release();
  return 0;
}

使用 VBScript 对对象进行编码

以下过程介绍如何使用 VBScript 对 XML 中的对象进行编码。

使用 VBScript 对 XML 中的对象进行编码

  1. (可选)创建 SWbemNamedValueSet 对象并对其进行初始化,以便设置 XML 表示形式所需的上下文值。

    下面的代码示例演示值如何指示 XML 编码器生成 <VALUE.OBJECTWITHLOCALPATH> 元素,并在构造对象的 XML 表示形式时包括所有限定符且排除系统属性。

    ' Create an optional SWbemNamedValueSet object
    set context = CreateObject("wbemscripting.SWbemNamedValueSet")
    
    ' Initialize the value set object to set the context
    ' Generate a <VALUE.OBJECTWITHLOCALPATH> element
    context.add "PathLevel", 2 
    context.add "IncludeQualifiers", true 
    context.add "ExcludeSystemProperties", true '
    
  2. 检索要用 XML 表示的对象或类的实例。

    下面的代码示例检索对象的实例。

    ' Retrieve the object/class to be represented in XML
    set myObj = GetObject("winmgmts:\\.\root\cimv2:win32_LogicalDisk")
    
  3. 调用在上一步中创建的实例的 GetText_ 方法,使用 1 作为参数可指定与 CIM DTD 版本 2.0 对应的文本格式,或使用 2 指定与 WMI DTD 版本 2.0 对应的文本格式。 如果在第 1 步中创建了 SWbemNamedValueSet 对象,请将其作为第三个参数包含在参数列表中。

    下面的代码示例演示如何调用实例的 GetText_ 方法。

    ' Get the XML representation of the object
    strText = myObj.GetText_(2,,context)
    
    ' If you have not used a SWbemNamedValueSet object
    ' enter the following line.
    strText = myObj.GetText_(2)
    
  4. (可选)验证第 3 步中生成的 XML 是格式正确的 XML(方法是创建并初始化 XML 文档对象模型 (DOM) 对象),然后将 XML 文本加载到其中。

    下面的代码示例演示如何创建和初始化 XML DOM 对象并将 XML 文本加载到其中。

    ' Create an XMLDOM object
    set xml = CreateObject("Microsoft.xmldom")
    
    ' Initialize the XMLDOM object so results are returned synchronously
    xml.async = false
    
    ' Load the XML into the XMLDOM object
    xml.loadxml strText
    
  5. 输出对象的 XML 表示形式。

    下面的代码示例演示如何使用 wscript 输出 XML。

    wscript.echo strText
    

    如果选择使用 XML DOM 来验证生成的 XML 的格式是否正确,请将上一行替换为以下内容。

    wscript.echo xml.xml
    

以下 VBScript 示例包括上一过程中的所有步骤,并在 XML 中对 Win32_LogicalDisk 类进行编码,包括类、属性和方法限定符,不包括系统属性。

' Create optional SWbemNamedValueSet object
set context = CreateObject("Wbemscripting.SWbemNamedValueSet")

' Initialize the context object
context.add "PathLevel", 2
context.add "IncludeQualifiers", true
context.add "ExcludeSystemProperties", true

' Retrieve the object/class to be represented in XML
set myObj = GetObject("winmgmts:\\.\root\cimv2:Win32_LogicalDisk")

' Get the XML representation of the object
strText = myObj.GetText_(2,,context)
' If you have not used a SWbemNamedValueSet object 
'   use the following line
'   strText = myObj.GetText(2)

' Print the XML representation
wscript.echo strText

' If you choose to use the XML DOM to verify 
'   that the XML generated is well-formed, replace the last
'   line in the above code example with the following lines:

' Create an XMLDOM object
set xml = CreateObject("Microsoft.xmldom")

' Initialize the XMLDOM object so results are 
'   returned synchronously
xml.async = false

' Load the XML into the XMLDOM object
xml.loadxml strText

' Print the XML representation
wscript.echo xml.xml

使用 WMI