0

在阅读了拉里奥斯特曼对我目前正在尝试解决的同一问题的回复后,我认为我已经找到了问题的答案。

作为记录,问题是:我如何从 .Net(非 WinRT)列出 WinRT 程序集中的类型(我的显然是 .dll 文件,而不是 .Winmd)

因此,我使用了以下代码片段:

//note, this wrapper function returns the metadata file name and token
// it immediately releases the importer pointer


static Tuple<string, UInt32> ResolveTypeName(string typename)
{
    string path;
    object importer = null;
    UInt32 token;

    try
    {
        var hr = RoGetMetaDataFile(typename, IntPtr.Zero, out path, out importer, out token);


        //TODO: check HR for error


        return Tuple.Create(path, token);
    }
    finally
    {
        Marshal.ReleaseComObject(importer);
    }
}


[DllImport("WinTypes.dll")]
static extern UInt32 RoGetMetaDataFile(
    [MarshalAs(UnmanagedType.HString)] string name,
    IntPtr metaDataDispenser,
    [MarshalAs(UnmanagedType.HString)] out string metaDataFilePath,
    [MarshalAs(UnmanagedType.Interface)] out object metaDataImport,
    out UInt32 typeDefToken);

(在https://gist.github.com/2920743上找到)

不幸的是,我得到一个非零的 HResult。

我参考了文档并发现了这一点:

HR_RESULT_FROM_WIN32(ERROR_NO_PACKAGE) 该函数是从不在 Windows 应用商店应用程序中的进程调用的。

这是否意味着根本无法列出 .Net(非 WinRT)中的类型?

4

2 回答 2

2

RoGetMetaDataFile用于从应用程序包中加载元数据文件。它定位定义了命名类型的元数据文件,加载该元数据文件,并返回一个IMetaDataImport表示该元数据文件的接口指针。

从普通的 .NET 代码中,您可以调用RuntimeEnvironment.GetRuntimeInterfaceAsIntPtr(或GetRuntimeInterfaceAsObject)来获取当前运行时的IMetaDataDispenser接口指针,该指针可用于加载任意模块以进行检查。

从本机代码中,您可以调用ICLRMetaHost::GetRuntime以加载运行时,然后从该对象调用ICLRRuntimeInfo::GetInterface以获取其IMetaDataDispenser接口指针。

于 2012-10-15T20:06:55.720 回答
1

RoGetMetaDataFile可以从应用程序包外部使用,但它只会解析系统 Windows 运行时类型。

为了解析应用程序特定类型,您需要使用“包标识”运行 - 换句话说,在正在运行的应用程序的上下文中。

于 2012-10-16T02:09:59.620 回答