排查将 Windows Phone Silverlight 移植到 UWP 的问题

上一主题是 移植项目

强烈建议阅读完整的移植指南,但我们也明白你渴望向前推进并到达项目成功构建和运行的阶段。 为此,可以通过注释或暂时屏蔽任何非基本代码,从而暂时取得进展,稍后再偿还技术债务。 本主题中的故障排除症状和补救措施表可能对你在此阶段有所帮助,尽管这不是阅读接下来几个主题的替代方法。 在学习后续主题时,您可以随时参考这张表。

寻找问题

XAML 分析异常可能很难诊断,尤其是在异常中没有有意义的错误消息时。 确保调试器配置为捕获首次异常(以便尝试及早捕获解析异常)。 您可以在调试器中检查异常变量,以确定 HRESULT 或消息是否包含任何有用的信息。 此外,请检查 Visual Studio 的输出窗口,了解 XAML 分析器输出的错误消息。

如果你的应用终止,并且你所知道的只是,在 XAML 标记解析期间出现了未经处理的异常,那么这可能是由于引用了缺失资源所导致的(即一个在 Windows Phone Silverlight 应用中存在但在 Windows 10 应用中不存在的资源,比如某些系统的 TextBlock Style 键)。 或者,这可能是在UserControl、自定义控件或自定义布局面板中抛出的异常。

最后的手段是二进制拆分。 从页面中删除大约一半的标记,然后重新运行应用。 然后,你将知道错误是否位于你删除的一半(现在应该还原),或在一半中,你 没有 删除。 通过拆分出包含错误的部分,重复这个过程,直到找到具体的问题。

目标平台版本

本部分介绍如何在 Visual Studio 中打开 Windows 10 项目时看到消息“需要 Visual Studio 更新”。 一个或多个项目需要平台 SDK <版本>,该版本要么未安装,要么将包括在 Visual Studio 的未来更新中。

  • 首先,确定已安装的适用于 Windows 10 的 SDK 的版本号。 导航到 C:\Program Files (x86)\Windows Kits\10\Include\<versionfoldername>,并记下 <versionfoldername>,该名称将以“四段式表示法,如‘Major.Minor.Build.Revision’”。
  • 打开项目文件进行编辑并查找 TargetPlatformVersionTargetPlatformMinVersion 元素。 编辑它们,使其格式如下所示,将你在磁盘上找到的版本文件名 <versionfoldername> 替换为四元表示法的版本号:
   <TargetPlatformVersion><versionfoldername></TargetPlatformVersion>
   <TargetPlatformMinVersion><versionfoldername></TargetPlatformMinVersion>

排查症状和补救措施

表中的补救措施信息旨在为你提供足够的信息来帮助你排除障碍。 阅读后续主题时,你将找到有关这些问题的更多详细信息。

症状 补救
XAML 解析器或编译器会给出错误“名称“<typename>”在命名空间中不存在。[...] 如果 <typename> 是自定义类型,则在 XAML 标记中声明命名空间前缀时,将“clr-namespace”更改为“using”,并删除所有程序集标记。 对于平台类型,这意味着该类型不适用于通用 Windows 平台(UWP),因此找到等效项并更新标记。 你可能会马上遇到的示例是 phone:PhoneApplicationPageshell:SystemTray.IsVisible
XAML 分析程序或编译器给出错误“成员“<membername>”不被识别或无法访问。”或“属性“<propertyname>”在类型 [...] 中没有找到。”。 在移植某些类型名称后,这些错误将开始出现,例如根页 页面。 成员或属性不适用于 UWP,因此请查找合适的替代项并更新您的标记。 你可能会马上遇到的示例是 SupportedOrientationsOrientation
XAML 分析程序或编译器提供错误“可附加属性 ...”找不到 “.”或“未知的可附加成员 \.”。 在这种情况下,这可能是由类型而不是附加属性引起的;如果已有该类型的错误,修复后,此错误将消失。 你可能会马上遇到的示例是 phone:PhoneApplicationPage.Resourcesphone:PhoneApplicationPage.DataContext
XAML 解析器、编译器或运行时异常会给出错误信息:“资源“<resourcekey>”无法解析。”。 资源密钥不适用于通用 Windows 平台(UWP)应用。 找到正确的等效资源并更新标记。 你可能会立即遇到的示例是系统 TextBlock 样式键,例如 PhoneTextNormalStyle
C# 编译器显示错误“找不到类型或命名空间名称‘<>’”或“类型或命名空间名称‘<>’在命名空间中不存在”或“类型或命名空间名称‘<>’在当前上下文中不存在”。 这可能意味着编译器尚不知道类型的正确 UWP 命名空间。 使用 Visual Studio 的 Resolve 命令修复此问题。
如果 API 不在称为通用设备系列的 API 集中(换句话说,API 在扩展 SDK 中实现),请使用 扩展 SDK。
在其他情况下,端口可能不太简单。 你可能会马上遇到的示例是 DesignerPropertiesBitmapImage
在设备上运行时,应用将终止或从 Visual Studio 启动时,会看到错误“无法激活 Windows 运行时 8.x 应用 ...”。 激活请求失败,出现错误“Windows 无法与目标应用程序通信。 这通常表示目标应用程序的进程已中止。 [...] 问题可能是初始化期间在您自己的 Pages 或绑定属性(或其他类型)中运行的命令式代码。 或者,在分析即将在应用终止时显示的 XAML 文件(如果从 Visual Studio 启动,这将是启动页面)时可能发生此情况。 查找无效的资源密钥,并/或尝试本主题中 跟踪问题 部分中的一些指导。
XamlCompiler 错误 WMC0055:无法将文本值“<your stream geometry>”分配给类型为“RectangleGeometry”的属性“Clip” 在 UWP 中,Microsoft DirectX 和 XAML C++ UWP 应用的 类型。
XamlCompiler 错误 WMC0001:XML 命名空间中的未知类型 “RadialGradientBrush” ~ UWP 不具有 RadialGradientBrush 类型。 从代码标记中删除 RadialGradientBrush,并使用另一种类型的 Microsoft DirectX 和 XAML C++ UWP 应用。
XamlCompiler 错误 WMC0011:在元素“<UIElement 类型>” 上找不到成员“OpacityMask” UWP Microsoft DirectX 和 XAML C++ UWP 应用。
SYSTEM.NI.DLL 中出现类型为“System.Runtime.InteropServices.COMException”的第一个机会异常。 其他信息:应用程序调用了一个已经为其他线程封送的接口。 (HRESULT 例外:0x8001010E(RPC_E_WRONG_THREAD))。 你正在进行的工作需要在 UI 线程上完成。 调用 CoreWindow.GetForCurrentThread)。
动画正在运行,但它对其目标属性没有影响。 可以让动画独立运行,或者为其设置 EnableDependentAnimation="True"。 请参阅 动画
在 Visual Studio 中打开 Windows 10 项目时,会看到消息“需要 Visual Studio 更新。 一个或多个项目需要平台 SDK <版本>,该版本要么未安装,要么将包括在 Visual Studio 的未来更新中。 请参阅本主题中的 TargetPlatformVersion 部分。
在xaml.cs文件中调用 InitializeComponent 时,将引发 System.InvalidCastException。 如果您有多个 xaml 文件(其中至少一个是 MRT 限定的),这些文件共享同一个 xaml.cs 文件,并且元素的 x:Name 属性在两个 xaml 文件之间存在不一致时,就可能会发生这种情况。 尝试将相同的名称添加到两个 xaml 文件中的相同元素,或完全省略名称。

下一主题是 移植 XAML 和 UI