.NET Framework 对 Windows 应用商店应用程序和 Windows 运行时的支持情况.NET Framework Support for Windows Store Apps and Windows Runtime

.NET Framework 4.5 使用 Windows 运行时支持许多软件开发方案。The .NET Framework 4.5 supports a number of software development scenarios with the Windows Runtime. 这些方案分为三类:These scenarios fall into three categories:

本主题概述 .NET Framework 为所有三个类别提供的支持,并介绍 Windows 运行时组件的方案。This topic outlines the support that the .NET Framework provides for all three categories, and describes the scenarios for Windows Runtime Components. 第一部分包含有关 .NET Framework 与 Windows 运行时之间的关系的基本信息,并说明了在帮助系统和 IDE 中可能会遇到的一些问题。The first section includes basic information about the relationship between the .NET Framework and the Windows Runtime, and explains some oddities you might encounter in the Help system and the IDE. 第二部分讨论用于开发 Windows 运行时组件的方案。The second section discusses scenarios for developing Windows Runtime Components.

基本知识The Basics

.NET Framework 通过提供适用于 Windows 8.x 应用商店应用的 .NET,并支持 Windows 运行时本身,来支持前面列出的三种开发方案。The .NET Framework supports the three development scenarios listed earlier by providing .NET for Windows 8.x Store apps, and by supporting the Windows Runtime itself.

  • .NET Framework 和 Windows 运行时命名空间提供了 .NET Framework 类库的简化视图,并只包含可用于创建 Windows 8.X 应用商店应用和 Windows 运行时组件的类型和成员。.NET Framework and Windows Runtime namespaces provides a streamlined view of the .NET Framework class libraries and include only the types and members you can use to create Windows 8.x Store apps and Windows Runtime Components.

    • 当你使用 Visual Studio (Visual Studio 2012 或更高版本)开发 Windows 8.x 应用商店应用或 Windows 运行时组件时,一组引用程序集可确保你只看到相关类型和成员。When you use Visual Studio (Visual Studio 2012 or later) to develop a Windows 8.x Store app or a Windows Runtime component, a set of reference assemblies ensures that you see only the relevant types and members.

    • 此简化的 API 集通过删除在 .NET Framework 中重复的功能或复制 Windows 运行时功能来进一步简化。This streamlined API set is simplified further by the removal of features that are duplicated within the .NET Framework or that duplicate Windows Runtime features. 例如,它仅包含集合类型的泛型版本,并消除 XML 文档对象模型,以支持 Windows 运行时 XML API 集。For example, it contains only the generic versions of collection types, and the XML document object model is eliminated in favor of the Windows Runtime XML API set.

    • 还会删除简单包装操作系统 API 的功能,因为 Windows 运行时可以从托管代码调用。Features that simply wrap the operating system API are also removed, because the Windows Runtime is easy to call from managed code.

    若要了解有关适用于 Windows 8.x 应用商店应用的 .NET 的详细信息,请参阅适用于 Windows 应用商店应用的 .net 概述To read more about the .NET for Windows 8.x Store apps, see the .NET for Windows Store apps overview. 若要阅读有关 API 选择过程的信息,请参阅 .NET 博客中的用于 Metro 风格的应用程序条目。To read about the API selection process, see the .NET for Metro style apps entry in the .NET blog.

  • Windows 运行时提供用于生成 Windows 8.X 应用商店应用的用户界面元素,并提供对操作系统功能的访问权限。The Windows Runtime provides the user interface elements for building Windows 8.x Store apps, and provides access to operating system features. 与 .NET Framework 一样,Windows 运行时具有元数据,使C#和 Visual Basic 编译器可以使用 Windows 运行时使用 .NET Framework 类库的方式。Like the .NET Framework, the Windows Runtime has metadata that enables the C# and Visual Basic compilers to use the Windows Runtime the way they use the .NET Framework class libraries. 通过隐藏一些差异,.NET Framework 可以更轻松地使用 Windows 运行时:The .NET Framework makes it easier to use the Windows Runtime by hiding some differences:

    • .NET Framework 和 Windows 运行时之间编程模式的某些差异(如添加和移除事件处理程序的模式)是隐藏的。Some differences in programming patterns between the .NET Framework and the Windows Runtime, such as the pattern for adding and removing event handlers, are hidden. 只需使用 .NET Framework 模式即可。You simply use the .NET Framework pattern.

    • 隐藏在常用类型上存在一些差异(例如,基元类型和集合)。Some differences in commonly used types (for example, primitive types and collections) are hidden. 你只需使用 .NET Framework 类型,如本文后面的IDE 中显示的差异中所述。You simply use the .NET Framework type, as discussed in Differences That Are Visible in the IDE, later in this article.

大多数情况下,对 Windows 运行时 .NET Framework 支持是透明的。Most of the time, .NET Framework support for the Windows Runtime is transparent. 下一节将讨论托管代码与 Windows 运行时之间的一些明显差异。The next section discusses some of the apparent differences between managed code and the Windows Runtime.

.NET Framework 和 Windows 运行时参考文档The .NET Framework and the Windows Runtime Reference Documentation

Windows 运行时和 .NET Framework 文档集是独立的。The Windows Runtime and the .NET Framework documentation sets are separate. 如果按 F1 显示关于类型或成员的帮助,将显示相应集合中的参考文档。If you press F1 to display Help on a type or member, reference documentation from the appropriate set is displayed. 但是,如果浏览Windows 运行时引用,则可能会遇到似乎令困惑的示例:However, if you browse through the Windows Runtime reference you might encounter examples that seem puzzling:

  • IIterable<T> 接口等主题没有 Visual Basic 或C#的声明语法。Topics such as the IIterable<T> interface don't have declaration syntax for Visual Basic or C#. 相反,注释出现在语法节的上方(在本例中,".NET:此接口显示为 System.object<T >")。Instead, a note appears above the syntax section (in this case, ".NET: This interface appears as System.Collections.Generic.IEnumerable<T>"). 这是因为 .NET Framework 和 Windows 运行时提供与不同接口相同的功能。This is because the .NET Framework and the Windows Runtime provide similar functionality with different interfaces. 此外,它们还有下列行为差异:IIterable 有一个 First 方法,而没有返回枚举器的 GetEnumerator 方法。In addition, there are behavioral differences: IIterable has a First method instead of a GetEnumerator method to return the enumerator. Windows 运行时 .NET Framework 通过使托管代码显示为使用熟悉的类型,而不是强制您了解执行常见任务的其他方式。Instead of forcing you to learn a different way of performing a common task, the .NET Framework supports the Windows Runtime by making your managed code appear to use the type you're familiar with. 你不会在 IDE 中看到 IIterable 接口,因此,在 Windows 运行时参考文档中,只需直接浏览该文档即可。You won't see the IIterable interface in the IDE, and therefore the only way you'll encounter it in the Windows Runtime reference documentation is by browsing through that documentation directly.

  • SyndicationFeed(String, String, Uri) 文档说明了一个紧密相关的问题:不同语言的参数类型似乎不同。The SyndicationFeed(String, String, Uri) documentation illustrates a closely related issue: Its parameter types appear to be different for different languages. 对于 C# 和 Visual Basic,参数类型为 System.StringSystem.UriFor C# and Visual Basic, the parameter types are System.String and System.Uri. 同样,这是因为 .NET Framework 具有自己的 StringUri 类型,并且,对于这种常用的类型,不宜强制 .NET Framework 用户了解执行操作的不同方式。Again, this is because the .NET Framework has its own String and Uri types, and for such commonly used types it doesn't make sense to force .NET Framework users to learn a different way of doing things. 在 IDE 中,.NET Framework 隐藏相应的 Windows 运行时类型。In the IDE, the .NET Framework hides the corresponding Windows Runtime types.

  • 在少数情况下(例如 GridLength 结构),.NET Framework 提供同名但功能更多的类型。In a few cases, such as the GridLength structure, the .NET Framework provides a type with the same name but more functionality. 例如,有些构造函数和属性主题与 GridLength 相关,但是其语法部分仅适用于 Visual Basic 和 C#,因为成员仅在托管代码时是可用的。For example, a set of constructor and property topics are associated with GridLength, but they have syntax blocks only for Visual Basic and C# because the members are available only in managed code. 在 Windows 运行时中,结构只有字段。In the Windows Runtime, structures have only fields. Windows 运行时结构要求使用 helper 类 GridLengthHelper来提供等效功能。The Windows Runtime structure requires a helper class, GridLengthHelper, to provide equivalent functionality. 当你在编写托管代码时,不会在 IDE 中看到该帮助器类。You won't see that helper class in the IDE when you're writing managed code.

  • 在 IDE 中,Windows 运行时类型显示为从 System.Object派生。In the IDE, Windows Runtime types appear to derive from System.Object. 它们看上去拥有从 Object 继承的成员,例如 Object.ToStringThey appear to have members inherited from Object, such as Object.ToString. 如果从 Object中实际继承了类型,并且 Windows 运行时类型可以强制转换为 Object,则这些成员的操作方式与此相同。These members operate as they would if the types actually inherited from Object, and Windows Runtime types can be cast to Object. 此功能是 .NET Framework 为 Windows 运行时提供的支持的一部分。This functionality is part of the support that the .NET Framework provides for the Windows Runtime. 但是,如果您查看 Windows 运行时参考文档中的类型,则不会显示此类成员。However, if you view the types in the Windows Runtime reference documentation, no such members appear. System.Object 参考文档为这些明显继承的成员提供了文档。The documentation for these apparent inherited members is provided by the System.Object reference documentation.

可在 IDE 中看到的差异Differences That Are Visible in the IDE

在更高级的编程方案中,如使用编写的 Windows 运行时组件C#为使用 JavaScript 为 windows 构建的 windows 8.X 应用商店应用程序提供应用程序逻辑,这些差异在 IDE 和文档中都明显。In more advanced programming scenarios, such as using a Windows Runtime component written in C# to provide the application logic for a Windows 8.x Store app built for Windows using JavaScript, such differences are apparent in the IDE as well as in the documentation. 当组件向 JavaScript 返回 IDictionary<int, string>,并在 JavaScript 调试器中查看该组件时,将看到 IMap<int, string> 的方法,因为 JavaScript 使用 Windows 运行时类型。When your component returns an IDictionary<int, string> to JavaScript, and you look at it in the JavaScript debugger, you'll see the methods of IMap<int, string> because JavaScript uses the Windows Runtime type. 下表显示了这两种语言中以不同方式显示的一些常用的集合类型:Some commonly used collection types that appear differently in the two languages are shown in the following table:

Windows 运行时类型Windows Runtime type 对应的 .NET Framework 类型Corresponding .NET Framework type
IIterable<T> IEnumerable<T>
IIterator<T> IEnumerator<T>
IVector<T> IList<T>
IVectorView<T> IReadOnlyList<T>
IMap<K, V> IDictionary<TKey, TValue>
IMapView<K, V> IReadOnlyDictionary<TKey, TValue>
IBindableIterable IEnumerable
IBindableVector IList
Windows.UI.Xaml.Data.INotifyPropertyChanged System.ComponentModel.INotifyPropertyChanged
Windows.UI.Xaml.Data.PropertyChangedEventHandler System.ComponentModel.PropertyChangedEventHandler
Windows.UI.Xaml.Data.PropertyChangedEventArgs System.ComponentModel.PropertyChangedEventArgs

在 Windows 运行时中,使用 IKeyValuePair来循环访问 IMap<K, V>IMapView<K, V>In the Windows Runtime, IMap<K, V> and IMapView<K, V> are iterated using IKeyValuePair. 在将它们传递给托管代码时,它们显示为 IDictionary<TKey, TValue>IReadOnlyDictionary<TKey, TValue>,因此自然要使用 System.Collections.Generic.KeyValuePair<TKey, TValue> 来枚举它们。When you pass them to managed code, they appear as IDictionary<TKey, TValue> and IReadOnlyDictionary<TKey, TValue>, so naturally you use System.Collections.Generic.KeyValuePair<TKey, TValue> to enumerate them.

接口在托管代码中的显示方式会影响实现这些接口的类型的显示方式。The way interfaces appear in managed code affects the way types that implement these interfaces appear. 例如, PropertySet 类实现 IMap<K, V>,后者在托管代码中显示为 IDictionary<TKey, TValue>For example, the PropertySet class implements IMap<K, V>, which appears in managed code as IDictionary<TKey, TValue>. PropertySet 显示为已实现 IDictionary<TKey, TValue> 而不是 IMap<K, V>,因此在托管代码中,它显示为具有 Add 方法,其行为类似于 .NET Framework 字典中的 Add 方法。PropertySet appears as if it implemented IDictionary<TKey, TValue> instead of IMap<K, V>, so in managed code it appears to have an Add method, which behaves like the Add method on .NET Framework dictionaries. 它不会显示为具有 Insert 方法。It doesn't appear to have an Insert method.

有关使用 .NET Framework 创建 Windows 运行时组件的详细信息,以及演示如何将此类组件与 JavaScript 一起使用的演练,请参阅在和 Visual Basic 中C#创建 Windows 运行时组件For more information about using the .NET Framework to create a Windows Runtime component, and a walkthrough that shows how to use such a component with JavaScript, see Creating Windows Runtime Components in C# and Visual Basic.

基元类型Primitive Types

为了能够在托管代码中自然地使用 Windows 运行时,.NET Framework 基元类型在代码中显示,而不是 Windows 运行时基元类型。To enable the natural use of the Windows Runtime in managed code, .NET Framework primitive types appear instead of Windows Runtime primitive types in your code. 在 .NET Framework 中,基元类型(如 Int32 结构)具有许多有用的属性和方法,如 Int32.TryParse 方法。In the .NET Framework, primitive types like the Int32 structure have many useful properties and methods, such as the Int32.TryParse method. 相比之下,Windows 运行时中的基元类型和结构只有字段。By contrast, primitive types and structures in the Windows Runtime have only fields. 在托管代码中使用基元时,它们将显示为 .NET Framework 类型,您可以如往常一样使用 .NET Framework 类型的属性和方法。When you use primitives in managed code, they appear to be .NET Framework types, and you can use the properties and methods of the .NET Framework types as you normally would. 以下列表提供了一个摘要:The following list provides a summary:

  • 对于 Windows 运行时基元 Int32Int64SingleDoubleBooleanString (Unicode 字符的不可变集合)、EnumUInt32UInt64Guid,请使用 System 命名空间中具有相同名称的类型。For the Windows Runtime primitives Int32, Int64, Single, Double, Boolean, String (an immutable collection of Unicode characters), Enum, UInt32, UInt64, and Guid, use the type of the same name in the System namespace.

  • 对于 UInt8,使用 System.ByteFor UInt8, use System.Byte.

  • 对于 Char16,使用 System.CharFor Char16, use System.Char.

  • 对于 IInspectable 接口,使用 System.ObjectFor the IInspectable interface, use System.Object.

  • 对于 HRESULT,使用包含一个 System.Int32 成员的结构。For HRESULT, use a structure with one System.Int32 member.

与接口类型一样,仅当 .NET Framework 项目是使用 JavaScript 生成的 Windows 8.x 应用商店应用使用的 Windows 运行时组件时,才会看到此表示形式的证据。As with interface types, the only time you might see evidence of this representation is when your .NET Framework project is a Windows Runtime component that is used by a Windows 8.x Store app built using JavaScript.

在托管代码中显示为其 .NET Framework 等效项的其他基本的常用 Windows 运行时类型包括 Windows.Foundation.DateTime 结构(在托管代码中显示为 System.DateTimeOffset 结构)以及 Windows.Foundation.TimeSpan 结构(显示为 System.TimeSpan 结构)。Other basic, commonly used Windows Runtime types that appear in managed code as their .NET Framework equivalents include the Windows.Foundation.DateTime structure, which appears in managed code as the System.DateTimeOffset structure, and the Windows.Foundation.TimeSpan structure, which appears as the System.TimeSpan structure.

其他差异Other Differences

在少数情况下,.NET Framework 类型会显示在代码中,而不是 Windows 运行时类型需要对你的操作。In a few cases, the fact that .NET Framework types appear in your code instead of Windows Runtime types requires action on your part. 例如,Windows.Foundation.Uri 类在 .NET Framework 代码中显示为 System.UriFor example, the Windows.Foundation.Uri class appears as System.Uri in .NET Framework code. System.Uri 允许使用相对 URI,但 Windows.Foundation.Uri 需要绝对 URI。System.Uri allows a relative URI, but Windows.Foundation.Uri requires an absolute URI. 因此,当您将 URI 传递到 Windows 运行时方法时,必须确保它是绝对的。Therefore, when you pass a URI to a Windows Runtime method, you must ensure that it's absolute. 请参阅 将 URI 传递给 Windows 运行时See Passing a URI to the Windows Runtime.

开发的 Windows 运行时组件的方案Scenarios for Developing Windows Runtime Components

托管 Windows 运行时组件支持的方案取决于以下一般原则:The scenarios that are supported for managed Windows Runtime Components depend on the following general principles:

  • Windows 运行时使用 .NET Framework 生成的组件与其他 Windows Runtimelibraries 没有明显的区别。Windows Runtime Components that are built using the .NET Framework have no apparent differences from other Windows Runtimelibraries. 例如,如果使用托管代码重新实现本机 Windows 运行时组件,则这两个组件表面不区分。For example, if you re-implement a native Windows Runtime component by using managed code, the two components are outwardly indistinguishable. 在托管代码中编写的组件对使用它的代码来说是不可见的,即使该代码本身是托管代码。The fact that your component is written in managed code is invisible to the code that uses it, even if that code is itself managed code. 但是,在内部,组件是真正的托管代码并运行在公共语言运行时 (CLR) 上。However, internally, your component is true managed code and runs on the common language runtime (CLR).

  • 组件可以包含实现应用程序逻辑、Windows 8.x 存储 UI 控件或二者的类型。Components can contain types that implement application logic, Windows 8.x Store UI controls, or both.

    备注

    最好将 UI 元素与应用程序逻辑分离开来。It's good practice to separate UI elements from application logic. 此外,在使用 JavaScript 和 HTML 为 Windows 构建的 Windows 8.x 应用商店应用中,不能使用 Windows 8.x 应用商店 UI 控件。Also, you can't use Windows 8.x Store UI controls in a Windows 8.x Store app built for Windows using JavaScript and HTML.

  • 组件可以是适用于 Windows 8.x 应用商店应用程序的 Visual Studio 解决方案中的项目,也可以是可添加到多个解决方案中的可重用组件。A component can be a project within a Visual Studio solution for a Windows 8.x Store app, or a reusable component that you can add to multiple solutions.

    备注

    如果组件仅用于C#或 Visual Basic,则无需将其作为 Windows 运行时组件。If your component will be used only with C# or Visual Basic, there's no reason to make it a Windows Runtime component. 如果改为使用普通 .NET Framework 类库,则无需将其公共 API 图面限制为 Windows 运行时类型。If you make it an ordinary .NET Framework class library instead, you don't have to restrict its public API surface to Windows Runtime types.

  • 可以通过使用 Windows 运行时 VersionAttribute 属性来确定在不同版本中添加了哪些类型(以及类型中的哪些成员),以释放可重用组件的版本。You can release versions of reusable components by using the Windows Runtime VersionAttribute attribute to identify which types (and which members within a type) were added in different versions.

  • 组件中的类型可以派生自 Windows 运行时类型。The types in your component can derive from Windows Runtime types. 控件可以从 Windows.UI.Xaml.Controls.Primitives 命名空间中的基元控件类型或更多已完成的控件(如 Button)派生。Controls can derive from the primitive control types in the Windows.UI.Xaml.Controls.Primitives namespace or from more finished controls such as Button.

    重要

    从 Windows 8 和 .NET Framework 4.5 开始,托管 Windows 运行时组件中的所有公共类型都必须是密封的。Starting with Windows 8 and the .NET Framework 4.5, all public types in a managed Windows Runtime component must be sealed. 其他 Windows 运行时组件中的类型不能从它们派生。A type in another Windows Runtime component can't derive from them. 如果要在组件中提供多态行为,可以创建一个接口并在多态类型中实现它。If you want to provide polymorphic behavior in your component, you can create an interface and implement it in the polymorphic types.

  • 组件中所有公共类型的参数和返回类型都必须是 Windows 运行时类型(包括组件所定义的 Windows 运行时类型)。All parameter and return types on the public types in your component must be Windows Runtime types (including the Windows Runtime types that your component defines).

以下部分提供常见方案的示例。The following sections provide examples of common scenarios.

使用 JavaScript 的 Windows 8.x 应用商店应用的应用程序逻辑Application Logic for a Windows 8.x Store App with JavaScript

当你使用 JavaScript 开发适用于 Windows 的 Windows 8.x 应用商店应用时,你可能会发现应用程序逻辑的某些部分在托管代码中性能更佳或更易于开发。When you develop a Windows 8.x Store app for Windows using JavaScript, you might find that some parts of the application logic perform better in managed code, or are easier to develop. JavaScript 不能直接使用 .NET Framework 类库,但是,您可以使将类库包装为 .WinMD 文件。JavaScript can't use .NET Framework class libraries directly, but you can make the class library a .WinMD file. 在此方案中,Windows 运行时组件是应用程序不可或缺的一部分,因此提供版本特性并无意义。In this scenario, the Windows Runtime component is an integral part of the app, so it doesn't make sense to provide version attributes.

可重用的 Windows 8.x 应用商店 UI 控件Reusable Windows 8.x Store UI Controls

可以在可重用的 Windows 运行时组件中打包一组相关的 UI 控件。You can package a set of related UI controls in a reusable Windows Runtime component. 该组件可以独立销售,或作为您创建的应用元素使用。The component can be marketed on its own or used as an element in the apps you create. 在这种情况下,可以使用 Windows 运行时 VersionAttribute 特性来改善兼容性。In this scenario, it makes sense to use the Windows Runtime VersionAttribute attribute to improve compatibility.

来自现有 .NET Framework 应用的可重用的应用程序逻辑Reusable Application Logic from Existing .NET Framework Apps

可以将现有的桌面应用程序中的托管代码作为独立的 Windows 运行时组件进行打包。You can package managed code from your existing desktop apps as a standalone Windows Runtime component. 这使你可以使用 Windows 8.x 应用商店应用中使用C++或 JavaScript 生成的组件,也可以在使用C#或 Visual Basic 生成的 windows 8.x 应用商店应用中使用该组件。This enables you to use the component in Windows 8.x Store apps built using C++ or JavaScript, as well as in Windows 8.x Store apps built using C# or Visual Basic. 如果代码有多个可重用的方案,可选择进行版本控制。Versioning is an option if there are multiple reuse scenarios for the code.

职务Title 描述Description
适用于 Microsoft Store 应用的 .NET 概述.NET for Windows Store apps overview 描述可用于创建 Windows 8.x 应用商店应用和 Windows RuntimeComponents 的 .NET Framework 类型和成员。Describes the .NET Framework types and members that you can use to create Windows 8.x Store apps and Windows RuntimeComponents. (位于 Windows 开发中心。)(In the Windows Dev Center.)
使用C#或 Visual Basic 的 Windows 应用商店应用的路线图Roadmap for Windows Store apps using C# or Visual Basic 提供了一些关键资源来帮助您开始使用C#或 Visual Basic 开发 Windows 8.X 应用商店应用程序,其中包括许多快速入门主题、指导原则和最佳实践。Provides key resources to help you get started developing Windows 8.x Store apps by using C# or Visual Basic, including many Quickstart topics, guidelines, and best practices. (位于 Windows 开发中心。)(In the Windows Dev Center.)
操作指南(XAML)How tos (XAML) 提供了一些关键资源来帮助您开始使用C#或 Visual Basic 开发 Windows 8.X 应用商店应用程序,其中包括许多快速入门主题、指导原则和最佳实践。Provides key resources to help you get started developing Windows 8.x Store apps by using C# or Visual Basic, including many Quickstart topics, guidelines, and best practices. (位于 Windows 开发中心。)(In the Windows Dev Center.)
用 C# 和 Visual Basic 创建 Windows 运行时组件Creating Windows Runtime Components in C# and Visual Basic 描述如何使用 .NET Framework 创建 Windows 运行时组件,并说明如何使用它作为使用 JavaScript 为 Windows 构建的 Windows 8.x 应用商店应用的一部分,并介绍如何使用 Visual Studio 调试此组合。Describes how to create a Windows Runtime component using the .NET Framework, explains how to use it as part of a Windows 8.x Store app built for Windows using JavaScript, and describes how to debug the combination with Visual Studio. (位于 Windows 开发中心。)(In the Windows Dev Center.)
Windows 运行时引用Windows Runtime reference Windows 运行时的参考文档。The reference documentation for the Windows Runtime. (位于 Windows 开发中心。)(In the Windows Dev Center.)
向 Windows 运行时传递 URIPassing a URI to the Windows Runtime 描述将 URI 从托管代码传递到 Windows 运行时时可能出现的问题,以及如何避免此问题。Describes an issue that can arise when you pass a URI from managed code to the Windows Runtime, and how to avoid it.