UWP 应用和传统桌面应用程序之间的主要区别之一是 UWP 游戏驻留在受进程生命周期管理(PLM)约束的应用容器中。 在所有平台上,通过运行时代理服务,UWP 应用可以被挂起、恢复或终止。对于需要测试或调试处理这些转换的代码时,可以使用专用工具来强制执行这些转换。
Visual Studio 2015 中的功能
Visual Studio 2015 中的内置调试器可以帮助你调查使用 UWP 独占功能时的潜在问题。 可以使用 生命周期事件 工具栏强制应用程序进入不同的 PLM 状态,该工具栏在运行和调试游戏时可见。
PLMDebug 工具
PLMDebug.exe 是一种命令行工具,可用于控制应用程序包的 PLM 状态,并作为 Windows SDK 的一部分提供。 安装后,该工具默认驻留在 C:\Program Files (x86)\Windows Kits\10\Debuggers\x64 中。
PLMDebug 还允许为任何已安装的应用包禁用 PLM,这是某些调试器所必需的。 禁用 PLM 可防止运行时代理服务在有机会进行调试之前终止应用。 若要禁用 PLM,请使用 /enableDebug 开关,然后输入 UWP 应用的 完整包名称(包的短名称、程序包系列名称或 AUMID 将不起作用):
plmdebug /enableDebug [PackageFullName]
从 Visual Studio 部署 UWP 应用后,完整包名称将显示在输出窗口中。 或者,还可以通过在 PowerShell 控制台中运行 Get-AppxPackage 来检索完整包名称。
(可选)可以指定调试器的绝对路径,该调试器将在激活应用包时自动启动。 如果要使用 Visual Studio 执行此作,则需要将 VSJITDebugger.exe 指定为调试器。 但是,VSJITDebugger.exe 要求你指定“-p”参数,并提供 UWP 应用程序的进程 ID(PID)。 由于无法事先知道 UWP 应用程序的 PID,因此无法直接实现这种方案。
可以通过编写一个脚本或工具来识别游戏进程,以规避该限制,之后 shell 将运行 VSJITDebugger.exe,并传入 UWP 应用的 PID。 以下 C# 代码示例演示了实现此目的的简单方法。
using System.Diagnostics;
namespace VSJITLauncher
{
class Program
{
static void Main(string[] args)
{
// Name of UWP process, which can be retrieved via Task Manager.
Process[] processes = Process.GetProcessesByName(args[0]);
// Get PID of most recent instance
// Note the highest PID is arbitrary. Windows may recycle or wrap the PID at any time.
int highestId = 0;
foreach (Process detectedProcess in processes)
{
if (detectedProcess.Id > highestId)
highestId = detectedProcess.Id;
}
// Launch VSJITDebugger.exe, which resides in C:\Windows\System32
ProcessStartInfo startInfo = new ProcessStartInfo("vsjitdebugger.exe", "-p " + highestId);
startInfo.UseShellExecute = true;
Process process = new Process();
process.StartInfo = startInfo;
process.Start();
}
}
}
与 PLMDebug 协同使用的示例:
plmdebug /enableDebug 279f7062-ce35-40e8-a69f-cc22c08e0bb8_1.0.0.0_x86__c6sq6kwgxxfcg "\"C:\VSJITLauncher.exe\" Game"
其中 Game
是进程名称, 279f7062-ce35-40e8-a69f-cc22c08e0bb8_1.0.0.0_x86__c6sq6kwgxxfcg
是示例 UWP 应用包的完整包名称。
请注意,每次调用 /enableDebug 之后,都必须与带有 /disableDebug 参数的 PLMDebug 调用相结合。 此外,调试器的路径必须是绝对路径(不支持相对路径)。