Windows Phone 7 Emulator有一个很好的控制台窗口功能,可以通过注册表设置(EnableConsole)或通过XDE.exe的decfg参数启用
即使没有附加调试器也能正常工作。它有助于查找运行时绑定问题,例外。
有没有办法在Windos 8 Phone模拟器中启用控制台窗口?
答案 0 :(得分:12)
WP8模拟器是对WP7模拟器的完全重写,因此它不太可能支持相同的未记录的调试消息。在一天结束时,问题是:你想记录什么?
记录特定于应用的消息
假设您的应用中发生了一些有趣的事情,例如重要的按钮点击。您需要在应用程序中记录该消息并将该消息写入IsoStore(或发送到自定义Web服务)。我使用MetroLog作为我的WP8& Win8日志记录,但只要文件写入IsoStore,您就可以使用任何您想要的内容。查看MetroLog @ https://github.com/mbrit/MetroLog
然后,您可以使用CoreCon API来读取文件。我已经上传了WP8 @ https://stackoverflow.com/a/13429709/81687
这些API的代码示例记录仿真器特定消息
假设您有兴趣查看模拟器何时被激活,何时设置了缩放,屏幕截图是否失败或是否发生了触摸事件。 WP8仿真器使用ETW提供程序 ff86852d-541c-4f7e-98c5-5761e8cb7074 来记录其他事件。您可以在这里阅读有关ETW的更多信息@ http://msdn.microsoft.com/en-us/magazine/cc163437.aspx
首先,下载PerfView以启动XDE.exe模拟器并开始捕获ETW输出。
现在从PerfView运行模拟器,做一些事情,关闭模拟器并停止收集信息。完成后,您可以看到模拟器中所有内容的日志。一旦您在提供者ID下过滤它,有趣的东西就在“事件”日志下。
在上面的打印屏幕中,您可以查看事件以及它们何时出现在模拟器中。例如,事件76是模拟器的MicrophoneCaptureThreadStarted,它发生在分析会话中27秒。有关事件代码的完整列表,请参阅XDE.exe程序集中的Microsoft.Xde.Etw.WindowsPhoneEmulatorProvider c'tor。这是复制粘贴在这里为你说服:
public WindowsPhoneEmulatorProvider()
{
this.m_provider = new EventProviderVersionTwo(new Guid("ff86852d-541c-4f7e-98c5-5761e8cb7074"));
this.XdeStarted = new EventDescriptor(0, 0, 9, 4, 0, 0, -9223372036854775808L);
this.XdeStopped = new EventDescriptor(1, 0, 0, 4, 0, 0, 0L);
this.DesktopResolutionChanged = new EventDescriptor(2, 0, 0, 4, 0, 0, 0L);
this.InvalidLanguageSpecified = new EventDescriptor(3, 0, 0, 2, 0, 0, 0L);
this.CantFindVhd = new EventDescriptor(5, 0, 0, 2, 0, 0, 0L);
this.DiffDiskVhdRequiresVhdPath = new EventDescriptor(6, 0, 0, 2, 0, 0, 0L);
this.InvalidVideoParam = new EventDescriptor(7, 0, 0, 2, 0, 0, 0L);
this.InvalidMemorySize = new EventDescriptor(8, 0, 0, 2, 0, 0, 0L);
this.CantFindVM = new EventDescriptor(9, 0, 0, 2, 0, 0, 0L);
this.UnableToSendKeyToVM = new EventDescriptor(10, 0, 0, 2, 0, 0, 0L);
this.FailedToCreateDiffVhd = new EventDescriptor(11, 0, 0, 2, 0, 0, 0L);
this.FailedToCreateVM = new EventDescriptor(12, 0, 0, 2, 0, 0, 0L);
this.FailedVMStop = new EventDescriptor(13, 0, 0, 2, 0, 0, 0L);
this.FailedStartVM = new EventDescriptor(14, 0, 0, 2, 0, 0, 0L);
this.UnableToConnectToGuest = new EventDescriptor(15, 0, 0, 2, 0, 0, 0L);
this.ConnectedToGuest = new EventDescriptor(0x10, 0, 0, 4, 0, 0, 0L);
this.GuestIndicatedResolution = new EventDescriptor(0x11, 0, 0, 4, 0, 0, 0L);
this.LoadedSkin = new EventDescriptor(0x12, 0, 0, 4, 0, 0, 0L);
this.ButtonPressed = new EventDescriptor(0x13, 0, 0, 4, 0, 0, 0L);
this.VirtualMachineStateChanged = new EventDescriptor(20, 0, 0, 4, 0, 0, 0L);
this.ProxyInitialized = new EventDescriptor(4, 0, 0, 4, 0, 0, 0L);
this.UsageShown = new EventDescriptor(0x16, 0, 0, 4, 0, 0, 0L);
this.DisplayOrientationSet = new EventDescriptor(0x17, 0, 0, 4, 0, 0, 0L);
this.ZoomSet = new EventDescriptor(0x18, 0, 0, 4, 0, 0, 0L);
this.ScreenshotSavedToFile = new EventDescriptor(0x19, 0, 0, 4, 0, 0, 0L);
this.KeySentToVM = new EventDescriptor(0x1a, 0, 0, 4, 0, 0, 0L);
this.MouseEventSentToVM = new EventDescriptor(0x1b, 0, 0, 4, 0, 0, 0L);
this.UnableToSendMouseEventToVM = new EventDescriptor(0x1c, 0, 0, 0, 0, 0, 0L);
this.BringToFrontExecuted = new EventDescriptor(0x1d, 0, 0, 4, 0, 0, 0L);
this.ConnectedToAccelerometer = new EventDescriptor(30, 0, 0, 4, 0, 0, 0L);
this.UnableToConnectToAccelermometer = new EventDescriptor(0x1f, 0, 0, 0, 0, 0, 0L);
this.InvalidWindowsDetected = new EventDescriptor(0x20, 0, 0, 2, 0, 0, 0L);
this.HyperVNotEnabled = new EventDescriptor(0x21, 0, 0, 2, 0, 0, 0L);
this.AskedToConnectExternalSwitches = new EventDescriptor(0x22, 0, 0, 4, 0, 0, 0L);
this.ConnectedToGuestNotifications = new EventDescriptor(0x23, 0, 0, 4, 0, 0, 0L);
this.UnableToConnectToGuestNotifications = new EventDescriptor(0x24, 0, 0, 2, 0, 0, 0L);
this.FailedToSetVmProperties = new EventDescriptor(0x25, 0, 0, 2, 0, 0, 0L);
this.FailedToInitializeSnapshots = new EventDescriptor(0x26, 0, 0, 2, 0, 0, 0L);
this.FailedToSetVhd = new EventDescriptor(0x27, 0, 0, 2, 0, 0, 0L);
this.RdpServerDisconnected = new EventDescriptor(40, 0, 0, 4, 0, 0, 0L);
this.ScreenshotFailed = new EventDescriptor(0x29, 0, 0, 2, 0, 0, 0L);
this.AccelerometerSendFailed = new EventDescriptor(0x2a, 0, 0, 2, 0, 0, 0L);
this.LocationSendFailed = new EventDescriptor(0x2b, 0, 0, 2, 0, 0, 0L);
this.SnapshotStarted = new EventDescriptor(0x2c, 0, 0, 0, 0, 0, 0L);
this.SnapshotSucceeded = new EventDescriptor(0x2d, 0, 0, 0, 0, 0, 0L);
this.SnapshotFailed = new EventDescriptor(0x2e, 0, 0, 2, 0, 0, 0L);
this.CloseAfterSilentSnapshot = new EventDescriptor(0x2f, 0, 0, 0, 0, 0, 0L);
this.ApplySnapshotFailed = new EventDescriptor(0x30, 0, 0, 2, 0, 0, 0L);
this.RemovingSnapshotAfterFailedConnect = new EventDescriptor(50, 0, 0, 0, 0, 0, 0L);
this.RemovingSnapshotAfterSettingsDidntMatch = new EventDescriptor(0x33, 0, 0, 0, 0, 0, 0L);
this.ConnectedToShellReadyPipe = new EventDescriptor(0x34, 0, 0, 4, 0, 0, 0L);
this.UnableToConnectToShellReadyPipe = new EventDescriptor(0x35, 0, 0, 2, 0, 0, 0L);
this.ConnectedToTouch = new EventDescriptor(0x36, 0, 0, 4, 0, 0, 0L);
this.UnableToConnectToTouch = new EventDescriptor(0x37, 0, 0, 2, 0, 0, 0L);
this.TouchSendFailed = new EventDescriptor(0x38, 0, 0, 2, 0, 0, 0L);
this.SendTextFailed = new EventDescriptor(0x39, 0, 0, 2, 0, 0, 0L);
this.ReceiveAudioFromGuestWithSpinFailed = new EventDescriptor(0x3a, 0, 0, 2, 0, 0, 0L);
this.SendMicrophoneDataToGuestFailed = new EventDescriptor(0x3b, 0, 0, 2, 0, 0, 0L);
this.LoadUserSettingsFailed = new EventDescriptor(60, 0, 0, 0, 0, 0, 0L);
this.SetGuestSystemTimeAndZoneFailed = new EventDescriptor(0x3d, 0, 0, 2, 0, 0, 0L);
this.HypervisorNotRunning = new EventDescriptor(0x3e, 0, 0, 2, 0, 0, 0L);
this.HyperVManagementServiceNotRunning = new EventDescriptor(0x3f, 0, 0, 2, 0, 0, 0L);
this.UserAlreadyInHyperVAdmin = new EventDescriptor(0x40, 0, 0, 4, 0, 0, 0L);
this.UserAddedToHyperVAdmins = new EventDescriptor(0x41, 0, 0, 4, 0, 0, 0L);
this.FailedToAddUserToHyperVAdmins = new EventDescriptor(0x42, 0, 0, 0, 0, 0, 0L);
this.SendKeyboardEvent = new EventDescriptor(0x43, 0, 0, 4, 0, 0, 0L);
this.SendKeyboardEventFailed = new EventDescriptor(0x44, 0, 0, 2, 0, 0, 0L);
this.AudioPlayThreadStarted = new EventDescriptor(0x45, 0, 0, 0, 0, 0, 0L);
this.AudioPlayThreadExited = new EventDescriptor(70, 0, 0, 0, 0, 0, 0L);
this.AudioDataReceivedFromGuest = new EventDescriptor(0x47, 0, 0, 0, 0, 0, 0L);
this.AudioGlitch = new EventDescriptor(0x48, 0, 0, 0, 0, 0, 0L);
this.AudioPaused = new EventDescriptor(0x49, 0, 0, 0, 0, 0, 0L);
this.AudioResumed = new EventDescriptor(0x4a, 0, 0, 0, 0, 0, 0L);
this.AudioDeviceChange = new EventDescriptor(0x4b, 0, 0, 0, 0, 0, 0L);
this.MicrophoneCaptureThreadStarted = new EventDescriptor(0x4c, 0, 0, 0, 0, 0, 0L);
this.MicrophoneCaptureThreadExited = new EventDescriptor(0x4d, 0, 0, 0, 0, 0, 0L);
this.MicrophoneDataSentToGuest = new EventDescriptor(0x4e, 0, 0, 0, 0, 0, 0L);
this.MicrophoneDeviceChange = new EventDescriptor(0x4f, 0, 0, 0, 0, 0, 0L);
this.GetNetworkInfoFailed = new EventDescriptor(90, 0, 0, 2, 0, 0, 0L);
this.IPRenewalInitiated = new EventDescriptor(0x5b, 0, 0, 4, 0, 0, 0L);
}
从Hyper-V托管操作系统记录事件
假设您想了解更多有关WP8 JITs程序集或何时执行垃圾收集的信息。 VS2012附带分析工具,可分析,存储和显示该信息。例如,以下是如何开始分析会话:
分析会话完成后,您可以看到应用程序下的“PerfLogs”文件夹中包含分析会话的数据。如果您已经分析了CPU /执行,那么您可以在该文件夹中看到VSPX文件。将VSPX文件重命名为ZIP并提取其包含的文件。在该ZIP中,您将找到一个ETL文件。那个ETL文件是另一个我们可以检查PerfView的ETW日志。
当我们在PerfView中打开这样一个ETL文件时,我们可以看到每个类都是JITTed,花了多长时间以及IL&原始尺寸。例如,我们的应用程序的App类是JITTed为123.461ms,为1.2ms,IL大小为105,原始大小为289。
您也可以直接使用性能分析API,而不是使用VS2012来捕获该数据。如果这是你想要做的事情,你将不得不对VS2012的SilverlightProfiler。*。dll程序集进行逆向工程,以便了解他们正在做什么并在VS2012之外重新创建它。
答案 1 :(得分:1)
我一直在寻找一个控制台或任何其他方式来跟踪WP8模拟器上的应用程序执行,而无需附加调试器一段时间。看起来,因为它在hyper-v VM上运行,控制台不再可用。
但是我找到了一些解决方法。您可以创建一个简单的类,将您的消息记录到应用程序的独立存储(更多关于隔离存储here)。运行应用程序后,您可以使用Windows Phone Power Tools检查隔离存储的内容(通常它具有“刷新”选项,因此您可以在模拟器上执行某些操作,然后只修改隔离存储)。