RoGetMetaDataFile 函数 (rometadataresolution.h)

查找并检索描述指定类型名称的应用程序二进制接口 (ABI) 的元数据文件。

语法

HRESULT RoGetMetaDataFile(
  [in]            const HSTRING        name,
  [in, optional]  IMetaDataDispenserEx *metaDataDispenser,
  [out, optional] HSTRING              *metaDataFilePath,
  [out, optional] IMetaDataImport2     **metaDataImport,
  [out, optional] mdTypeDef            *typeDefToken
);

参数

[in] name

类型: const HSTRING

要解析的名称,类型名称或命名空间。 名称输入字符串必须是非空的,并且不能包含嵌入的 NUL 字符。 如果名称是一个以点分隔的字符串,则最后一个点左侧的子字符串和最后一个点右侧的子字符串必须是非空的。

[in, optional] metaDataDispenser

类型: IMetaDataDispenserEx*

调用方可以选择传入的元数据分配器,以便 RoGetMetaDataFile 函数能够通过提供的 IMetaDataDispenserEx::OpenScope 方法打开元数据文件。 如果元数据分配器参数设置为 nullptr,则该函数 (RoMetadata.dll) 创建重构元数据读取器的内部实例,并使用其 IMetaDataDispenserEx::OpenScope 方法。 可以使用 MetaDataGetDispenser 函数创建元数据分配器。

[out, optional] metaDataFilePath

类型: HSTRING*

描述 ABI 的元数据 (.winmd) 文件的绝对路径,除非设置为 nullptr。 调用方负责通过调用 WindowsDeleteString 方法释放 HSTRING

[out, optional] metaDataImport

类型: IMetaDataImport2**

指向元数据文件读取器对象的指针。 如果调用方传入 nullptr ,则该函数将释放 IMetaDataImport2 引用,否则调用方必须释放该引用。 失败时,该值设置为 nullptr

[out, optional] typeDefToken

类型: mdTypeDef*

如果名称输入字符串成功解析为 typename,则此参数将设置为 typename 的标记。

失败时,此参数设置为 mdTypeDefNil

返回值

类型: HRESULT

此函数可以返回其中一个值。

返回代码 说明
S_OK
解析成功,这意味着输入字符串表示 .winmd 文件中定义的类型。
E_INVALIDARG
输入名称字符串的以下至少一个属性不保存:
  • 不为 null,不为空
  • 不包含嵌入的 null 字符。
  • 如果是以点分隔的字符串,则最后一个点左侧的子字符串和最后一个点右侧的子字符串必须是非空的。
RO_E_METADATA_NAME_NOT_FOUND
输入字符串不是任何已检查的 .winmd 文件中定义的类型。
RO_E_METADATA_NAME_IS_NAMESPACE
输入字符串是现有的命名空间,而不是类型名称。

注解

调用方可以选择传入 RoGetMetaDataFile 函数的元数据分配器,以通过 IMetaDataDispenserEx::OpenScope 方法打开元数据文件。

如果元数据分配器参数设置为 nullptr,则该函数将创建重构的元数据读取器的内部实例,并使用该读取器的 IMetaDataDispenserEx::OpenScope 方法。

如果将 nullptr 传入元数据分配器参数,则保证 RoGetMetaDataFile 函数是线程安全的,因为该函数会创建一个内部只读元数据读取器。 如果将只读元数据读取器(如 RoMetadata)传入函数,则此保证也成立。

所有三个输出参数都是可选的,不需要指定任何参数。 为所有输出参数调用带有 nullptrRoGetMetaDataFile 函数等效于询问是否定义了输入 typename 或命名空间。

元数据读取器对象引用和 TypeDef 标记参数配对,因此两者必须一起设置或设置为 nullptr

有三种可能的类型解析方案:

场景 #1 Typename 输入字符串是在 WinMD 文件中定义的类型。
  • 返回值

    S_OK

  • 元数据文件路径输出参数

    这是可选的输出参数。 如果调用方未设置为 nullptr ,它将保留描述给定类型的 ABI 的 .winmd 文件的绝对路径。 调用方负责通过调用 WindowsDeleteString 释放 HSTRING

  • 对元数据读取器对象输出参数的引用

    这是可选的输出参数。 如果不是 nullptr,它将保留对元数据读取器对象的引用 (IMetaDataImport2) ,调用方负责释放它。 如果调用方为此参数传递 nullptr ,则意味着调用方不需要元数据读取器对象,因此函数会释放内部引用。

  • Typedef 令牌输出参数

    这是可选的输出参数。 如果调用方未设置为 nullptr ,则会将其设置为类型的 typedef 条目的标记。 语言投影可以使用此令牌调用 IMetaDataImport::GetTypeDefProps 来获取有关类型的元数据。

场景 #2 Typename 输入字符串实际上是一个现有的命名空间,而不是 typename。
  • 返回值

    RO_E_METADATA_NAME_IS_NAMESPACE

  • 元数据文件路径输出参数

    这是可选的输出参数。 如果调用方未设置为 nullptr ,则设置为 nullptr

  • 对元数据读取器对象输出参数的引用

    这是可选的输出参数。 如果调用方未设置为 nullptr ,则设置为 nullptr

  • Typedef 令牌输出参数

    这是可选的输出参数。 如果调用方未设置为 nullptr ,它将为 mdTypeDefNil

场景 #3 输入字符串不是任何检查的 WinMD 文件中定义的类型
  • 返回值

    RO_E_METADATA_NAME_NOT_FOUND

  • 元数据文件路径输出参数

    这是可选的输出参数。 如果调用方未设置为 nullptr ,则设置为 nullptr

  • 对元数据读取器对象输出参数的引用

    这是可选的输出参数。 如果调用方未设置为 nullptr ,则设置为 nullptr

  • Typedef 令牌输出参数

    这是可选的输出参数。 如果调用方未设置为 nullptr ,则设置为 mdTypeDefNil

 

RoGetMetaDataFile 函数解析接口组,因为接口组也是命名空间限定的类型名称。 IInspectable::GetRuntimeClassName 方法以点分隔的字符串格式返回字符串,供 RoGetMetaDataFile 使用。

不支持从不在 Windows 应用商店应用中的进程解析第三方类型。 在这种情况下,函数返回错误 HRESULT_FROM_WIN32 (ERROR_NO_PACKAGE) 并将输出参数设置为 nullptr。 但是,Windows 类型是在不在 Windows 应用商店应用中的进程中解析的。

示例

以下 C++ 示例演示如何使用 RoGetMetaDataFile 函数查找指定类型名称的元数据文件。

#include <windows.h>
#include <stdio.h>
#include <WinRTString.h>
#include <TypeResolution.h>
#include <atlbase.h>

HRESULT PrintMetaDataFilePathForTypeName(PCWSTR pszTypename);

int ShowUsage()
{
    wprintf(L"Usage: RoGetMetaDataFileSample TypeName\n");
    return -1;
}

int __cdecl wmain(int argc, WCHAR **argv)
{
    if (argc != 2)
    {
        return ShowUsage();
    }

    HRESULT hr = PrintMetaDataFilePathForTypeName(argv[1]);

    if (SUCCEEDED(hr))
    {
        return 0;
    }
    else
    {
        return -1;
    }
}

HRESULT PrintMetaDataFilePathForTypeName(PCWSTR pszTypename)
{
    HRESULT hr;
    HSTRING hstrTypeName = nullptr;
    HSTRING hstrMetaDataFilePath = nullptr;
    CComPtr<IMetaDataImport2> spMetaDataImport;
    mdTypeDef typeDef;

    hr = WindowsCreateString(
        pszTypename,
        static_cast<UINT32>(wcslen(pszTypename)),
        &hstrTypeName);

    if (SUCCEEDED(hr))
    {
        hr = RoGetMetaDataFile(
            hstrTypeName,
            nullptr,
            &hstrMetaDataFilePath,
            &spMetaDataImport,
            &typeDef);
    }

    if (SUCCEEDED(hr))
    {
        wprintf(L"Type %s was found in %s\n", pszTypename,  WindowsGetStringRawBuffer(hstrMetaDataFilePath, nullptr));
    }
    else if (hr == RO_E_METADATA_NAME_NOT_FOUND)
    {
        wprintf(L"Type %s was not found!\n", pszTypename);
    }
    else
    {
        wprintf(L"Error %x occurred while trying to resolve %s!\n", hr, pszTypename);
    }

    // Clean up resources.
    if (hstrTypeName != nullptr)
    {
        WindowsDeleteString(hstrTypeName);
    }

    if (hstrMetaDataFilePath != nullptr)
    {
        WindowsDeleteString(hstrMetaDataFilePath);
    }

    return hr;
}

要求

要求
最低受支持的客户端 Windows 8 [桌面应用 |UWP 应用]
最低受支持的服务器 Windows Server 2012 [桌面应用 |UWP 应用]
目标平台 Windows
标头 rometadataresolution.h
Library WindowsApp.lib
DLL WinTypes.dll