RoGetMetaDataFile 函式 (rometadataresolution.h)

找出並擷取描述指定 typename 的應用程式二進位介面 (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

要解析的名稱,可以是 typename 或命名空間。 名稱輸入字串必須是非空白,且不得包含內嵌NUL字元。 如果名稱是點分隔的字串,則最後一個點左邊的子字元串,最後一個點右邊的子字串必須是非空白的。

[in, optional] metaDataDispenser

類型: IMetaDataDispenserEx*

呼叫端可以選擇傳入的元數據分配器, 讓 RoGetMetaDataFile 函式能夠透過提供的 IMetaDataDispenserEx::OpenScope 方法開啟元數據檔案。 如果元數據分配器參數設定為 nullptr,函式會 (RoMetadata.dll) 建立重構元數據讀取器的內部實例,並使用其 IMetaDataDispenserEx::OpenScope 方法。 您可以使用 MetaDataGetDispenser 函式建立元數據分配器。

[out, optional] metaDataFilePath

類型: HSTRING*

除非設定為 nullptr,否則描述 ABI 的元數據 (.winmd 的絕對路徑) 檔案。 呼叫端負責呼叫 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
輸入字串是現有的命名空間,而不是 typename。

備註

呼叫端可以選擇性地傳遞 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 函式會解析介面群組,因為介面群組也是命名空間限定的 typename。 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
程式庫 WindowsApp.lib
Dll WinTypes.dll