是否可以使用非Windows Store App中的RoGetMetaDataFile

时间:2012-10-15 19:56:57

标签: c# winapi reflection windows-runtime pinvoke

在我正在尝试解决的同一问题上阅读Larry Osterman's response后,我以为我找到了问题的答案。

为了记录,问题是:我如何从.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)该函数是从a调用的   不属于Windows应用商店应用的流程。

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

2 个答案:

答案 0 :(得分:2)

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

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

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

答案 1 :(得分:1)

可以在应用程序包外部使用

RoGetMetaDataFile,但它只能解析系统窗口运行时类型。

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