Ars Technica的这篇文章Turning to the past to power Windows’ future: An in-depth look at WinRT从历史的角度对WinRT进行了长篇介绍。简单地说WinRT基于COM,但是目的没有COM那么通用。COM的目的是为了提供接口规范;而WinRT的目的虽然也是在于提供接口规范,但这个接口规范主要用来用于规范操作系统对外提供的接口。

和COM相比,WinRT从.Net借鉴了不少东西,比较明显的是XAML这套UI描述语言,不那么明显的则是COM的Metadata格式。WinRT的MIDL生成的WinMD元数据,基本上就采用了.Net的元数据格式。

Windows Runtime is not a Runtime一文提到WinMD其实就是不包含代码的.Net PE文件,基于ECMA 335。使用相同的元数据有利于促进不同编程语言之间的互操作性。和COM不同,使用.Net也可以编写WinRT的组件。

Windows Runtime is not a Runtime一文还提到WinRT和COM的不同之处

  • WinRT的基本接口时IInspectable而不是IUnknown,虽然前者也是后者派生出来的
  • WinRT是强类型的COM,从IInspectable可以获得runtimeclass的名字以及成员列表
  • WinRT还定义了一套公共的接口,比如IVector, IIterable等
  • WinRT还像.Net一样支持boxing

Understanding Windows Runtime Threading in the Windows Runtime: Part 1 Threading in the Windows Runtime: Part 2 Deep Dive into WinRT

API对比

Win32是纯粹基于C/C++接口的API。而WinRT是基于MIDL(也就是DotNet元数据格式)的API。WinRT的接口天生与语言无关,虽然WinRT大部分是使用C/C++编写的,甚至有可能调用了Win32的API。

不管是Win32还是WinRT,软件模块都是以DLL形式存在的。差别在于:Win32的DLL是原始的DLL,而WinRT的DLL带有接口元数据,用于描述接口。这些元数据可以投射到不同的语言中,供不同的语言调用。投射到C++中,便可以让Win32程序调用WinRT的API。

对于DotNet,由于其代码是托管的,需要把Win32或者WinRT的API嫁接到托管代码中。不同的框架嫁接的API不同。WinForms,WPF嫁接的是Win32的API。用于UWP的DotNet嫁接的是WinRT的API。

Calling Windows 10 APIs From a Desktop Application一问说明了如何在Win32(托管或者原生应用)中调用WinRT的API。很大一部分WinRT的API都是可以直接调用的。少数依赖于Package identity的API,不能直接调用。这些应用通常用于Microsoft Store,解决办法是通过Desktop Bridge来包装一下,提供所需的Package identity

还有一些API依赖于CoreWindow,这玩意儿是UWP专属的,不能直接调用。但是可以通过WinRT Component的方式,让其在单独的App Container进程内运行。

winmd

winmd是WinRT的MIDL编译生成的元数据。Ildasm.exe可以直接用来解码winmd文件。

其他DUMP工具

其他参考

(完)

2020-11-22更新

(更新完)