问题标签 [winmd]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
2 回答
3468 浏览

com - 如何读取 winmd(WinRT 元数据文件)?

WinMD 是一个二进制元数据文件,其中包含您需要了解的有关本地 WinRT dll 中可用的命名空间、类型、类、方法和参数的所有信息。

Windows 运行时设计

Windows 运行时使用 API 元数据(.winmd 文件)公开。这与 .NET 框架 (Ecma-335) 使用的格式相同。底层二进制合约使您可以轻松地以您选择的开发语言直接访问 Windows 运行时 API。

每个 .winmd 文件都公开一个或多个命名空间。这些命名空间按它们提供的功能分组。命名空间包含类、结构和枚举等类型。

伟大的; 我如何访问它?

Winmd 是 COM

引擎盖下的 WinRT 仍然是 COM。WinRT 中的 Winmd(Windows 元数据)是来自 COM 的旧 TLB(类型库)文件的现代版本。

从 COM tlb 读取元数据

给定一个 COM tlb 文件(例如stdole.tlb),您可以使用各种 Windows 函数来解析 tlb 以从中获取信息。

调用LoadTypeLib可以获得一个ITypeLib接口:

然后你可以开始迭代类型库中的所有内容

*.winmd我们如何对 WinRT 世界中的文件做同样的事情?

从拉里奥斯特曼:

我们从 idl 文件生成一个 winmd 文件。winmd 文件是该类型的规范定义。这就是传递给语言预测的内容。语言投影读取 winmd 文件,并且他们知道如何获取该 winmd 文件的内容 - 这是一个二进制文件 - 然后对其进行投影并为该语言生成适当的语言结构。

他们都阅读了那个 winmd 文件。它恰好是一个 ECMA-335 元数据程序集。这就是打包文件格式的技术细节。

生产 winmd 的好处之一是,因为它是常规的,我们现在可以构建工具来对 winmd 文件中的方法和类型进行排序、整理、组合。

从 winmd 加载元数据

我尝试使用RoGetMetaDataFile加载 WinMD。但RoGetMetaDataFile并不意味着让您直接处理 winmd 文件。它旨在让您发现有关您已经知道存在的类型的信息 - 并且您知道它的名称。

如果您将文件名传递给RoGetMetadataFile ,则调用它会失败winmd

对应 AppModel 错误代码:

但是,如果您传递一个类,RoGetMetadataFile确实会成功:

元数据分配器

有人建议使用MetaDataGetDispenser创建IMetaDataDispenser

想必你可以使用OpenScope方法打开一个winmd文件:

打开现有的磁盘文件并将其元数据映射到内存中。
该文件必须包含公共语言运行时 (CLR) 元数据。

其中第一个参数 ( Scope) 是“要打开的文件的名称”。

所以我们尝试:

除了我不知道我应该要求什么界面;文档不会说。它确实指出:

可以使用“import”接口之一的方法查询元数据的内存中副本,或者使用“emit”接口之一的方法添加元数据。

将重点放在“导入”“发出”这两个词上的作者可能试图提供一个线索——而不是直接给出答案。

奖金喋喋不休

  • 我不知道其中的名称空间或类型winmd(这就是我们要弄清楚的)
  • 使用 WinRT,我没有在 CLR 中运行托管代码;这是本机代码

我们可以用于这个问题的假设动机是我们将为一种还没有的语言创建一个投影(例如 ada、bpl、b、c)。另一个假设的动机是允许 IDE 能够显示 winmd 文件的元数据内容。

另外,请记住 WinRT 与 .NET 没有任何关系。

  • 它不是托管代码。
  • 它不存在于程序集中。
  • 它不在 .NET 运行时内运行。
  • 但是由于 .NET 已经为您提供了一种与 COM 互操作的方法(并且鉴于 WinRTCOM)
  • 您可以从托管代码中调用 WinRT 类

许多人似乎认为 WinRT 是 .NET 的另一个名称。WinRT 不使用、不需要或在 .NET、C#、.NET 框架或 .NET 运行时中运行。

  • WinRT 是本机代码
  • 因为 .NET Framework 类库是托管代码

WinRT 是本机代码的类库。.NET 人已经有了自己的类库。

奖金问题

本机 mscore 中有哪些函数可以让您处理 ECMA-335 二进制文件的元数据?

奖金阅读

0 投票
1 回答
189 浏览

com - 使用 IMetadataImport 时如何获取枚举值

精简版

使用IMetadataImport时如何从文件中获取与枚举关联的数值?*.winmd

一个很好的例子是ApplicationHighContrastAdjustment枚举:

大多数枚举是0, 1, 2, .... 但是这个在枚举成员上指定了其他值:

  • 0
  • 4294967295

我如何阅读获取那些UInt32

注意:这个问题不一定只适用于 WinRT。在 C# 世界中使用相同的接口来检查 .NET 托管程序集。WinRT 恰好使用相同的程序集文件格式。

长版

IMetadataImport用来阅读*.winmd(用于 WinRT 应用程序的现代版 TLB)的内容。但这个问题同样适用于阅读有关 .NET 托管程序集的元数据。

如何启动和运行读取 winmd 元数据文件的精简版:

获取有关枚举的信息(自动,无)

我们现在有一个读者。而不是枚举程序集中的类型,我可以直接跳到这个问题的有趣问题0x02000006::

调用EnumMembers返回枚举的三个成员:

  • Windows.UI.Xaml.ApplicationContrastMode (@02000006)
    • 值__(@ 04000439 ,私人)
    • (@0400043A,公开)
    • 自动(@0400043B,公共)

获取每个枚举值的信息

我们实际上是通过调用GetMemberProps来找出他们的名字(以及一个是私有的事实):

注意:GetMemberProps 是一个辅助函数。来自微软:

这是一个简单的辅助方法:如果md是 MethodDef,那么我们调用GetMethodProps;如果md是 FieldDef,那么我们调用GetFieldProps。有关详细信息,请参阅这些其他方法。

GetMemberProps方法返回有关每个枚举值的大量信息 - 但不是它们的实际枚举

我在成员属性中找不到任何指示枚举分配值的内容。并查看其他IMetadataImporter方法:

  • IMetadataImporter
    • GetMemberProps (GetMemberProps 是一个助手,根据类型调用 GetMethodProps 或 GetFieldProps)
      • GetMethodProps
      • 获取FieldProps
    • 获取PropertyProps
    • 获取事件道具
    • 获取参数道具
    • GetInterfaceImplProps
    • GetCustomAttributeProps
    • GetTypeDefProps
    • GetTypeRefProps
    • GetScopeProps
    • GetPermissionSetProps
    • GetModuleRefProps
    • GetNestedClassProps
    • GetMemberRefProps

奖金阅读

  • MSDN 博客:元数据非托管 API (一个旧 Word 文档的初步 PDF 版本,据我所知,它是元数据 API 的唯一 Microsoft 文档) 存档
0 投票
1 回答
1646 浏览

winapi - 导入WinRT winmd时如何获取接口的Interface ID(IID,即GUID)?

精简版

*.winmd使用IMetadataImport时如何从文件中获取接口的接口标识符 (IID) ?

例如Windows.Globalization.ICalendar{CA30221D-86D9-40FB-A26B-D44EB7CF08EA}

更长的版本

一个很好的例子Windows.Globalization.ICalendar接口。它的 IID 是CA30221D-86D9-40FB-A26B-D44EB7CF08EA.

它在 IDL 中

您可以在源Windows.Globalization.idl文件中找到它:

提醒:您不应该解析这些文件。它被编译成一个*.winmd程序集,而那个数据库就是事实。

它在标题中

您可以在使用导入工具windows.globalization.h生成的文件中找到它:*.winmd

它甚至在winmd中

您甚至可以在生成的已编译*.winmd程序集数据库中找到 InterfaceID:

在此处输入图像描述

但是在使用文档化API如何获取它?IMetadataImporter

代码

如何启动和运行读取元数据文件的精简版:winmd

奖金阅读

  • MSDN 博客:元数据非托管 API (一个旧 Word 文档的初步 PDF 版本,据我所知,它是元数据 API 的唯一 Microsoft 文档) 存档
0 投票
0 回答
336 浏览

vba - 我如何在 VBA 中调用 WebView2 和其他现代 winmd 功能

我想在旧式 VBA 用户窗体中嵌入一个现代 WebView2 组件(Edge Chromium 浏览器控件)。

我推测我需要在系统上安装以下内容:

  • 边缘铬浏览器
  • Webview2 SDK

虽然我安装了 Edge Chromium 浏览器,但我不确定如何在特定 Visual Studio 项目的上下文之外安装 Webview2 SDK。要在 VBA 解决方案中使用它,它需要引用某种全局系统范围的文件吗?

然后,显然包含我们需要嵌入 Edge 浏览器的功能的类型库是Windows.Web.winmd. 我想我需要以某种方式“引用”它,但我不确定如何......

0 投票
1 回答
74 浏览

c++ - 如何从 C++/WinRT 库中导出数据、函数、类

通常我们对 c++ 库使用 dllexport/dllimport 方法。然后测试应用程序可以隐式/显式地使用 dll 来访问 dll 函数。我们还可以利用 c++/winRT 中的 .winmd 文件来访问使用测试应用程序的类和函数。

那么这两个概念有什么区别呢?哪个更适合 c++/WinRT 库(dll)。