C# 如何模拟Windows关机进行调试?
当Windows关闭时,我的应用程序出现问题-我的应用程序无法正常退出,导致显示“结束任务”窗口。如何使用调试器查看发生了什么C# 如何模拟Windows关机进行调试?,c#,.net,winforms,shutdown,C#,.net,Winforms,Shutdown,当Windows关闭时,我的应用程序出现问题-我的应用程序无法正常退出,导致显示“结束任务”窗口。如何使用调试器查看发生了什么 是否有方法将Windows关闭消息发送到我的应用程序,使其认为Windows正在关闭,以便我可以确切地看到它的行为?我相信当Windows关闭时,它会向所有应用程序发送“WM\u QueryEndSession”。要模拟Windows关闭,您可以创建一个小应用程序,只需将此消息发送给您的应用程序,然后查看发生了什么。Windows可能会发送比实际关闭应用程序更多的消息(
是否有方法将Windows关闭消息发送到我的应用程序,使其认为Windows正在关闭,以便我可以确切地看到它的行为?我相信当Windows关闭时,它会向所有应用程序发送“WM\u QueryEndSession”。要模拟Windows关闭,您可以创建一个小应用程序,只需将此消息发送给您的应用程序,然后查看发生了什么。Windows可能会发送比实际关闭应用程序更多的消息(如WM_close),但每当应用程序收到“WM_QueryEndSession”消息时,就意味着您的应用程序即将从下面拉出地毯。您可以使用该事件,当用户注销或关闭时会触发该事件。但是在使用它时要小心,有些资源不能保证可用。例如,我的应用程序需要在服务器关闭时点击服务器以给用户打卡(一个时钟应用程序),但有时在发生此事件时网卡已经被禁用。由于您只是在进行清理,这应该可以正常工作。Microsoft的Windows徽标测试工具中有一个名为Restart Manager(rmtool.exe)的工具,可用于向进程发送关闭和重新启动消息。徽标测试工具可在此处下载: 然后,您可以模拟流程的关闭:
rmtool.exe -p [PID] -S
其中[PID]是过程ID。根据Vista徽标认证测试用例文档
重新启动管理器关闭消息包括:
a。WM_QUERYENDSESSION with LPARAM=ENDSESSION_CLOSEAPP(0x1):GUI应用程序必须立即响应(TRUE)以准备重新启动
b。WM_ENDSESSION with LPARAM=ENDSESSION_CLOSEAPP(0x1):应用程序必须在5秒内关闭(服务为20秒)
c。CTRL\u SHUTDOWN\u事件:控制台应用程序必须立即关闭
可用于向窗口发送带有任何参数的窗口消息
对调试和测试非常有用
LPARAM
=ENDSESSION\u CLOSEAPP
发送消息WM\u QUERYENDSESSION
。
应用程序必须返回1(TRUE)以指示它准备关闭并重新启动ENDSESSION\u CLOSEAPP
应用程序必须在指定的超时时间内关闭这可以使用
rmlogotest.exe
工具完成。请参阅以下链接:
如果您正在使用WPF,则可以处理其他事件:
Application.SessionEnding += Application_SessionEnding;
您可以在其中设置e.Cancel=true代码>可以中止应用程序关闭
我认为rmlogotest.exe
使用了5秒的超时,然后它会告诉您
徽标验证失败
如果您在应用程序中放入某种消息框确认,最终用户可能会失败,响应可能需要5秒钟以上
我猜从windows的角度来看,如果5秒钟过去了,它无论如何都要重新启动——如果最终用户还没有保存他的文档/工作——那么windows可能会将其复制到其他地方
从我(作为应用程序开发人员)的角度来看,失败是可以接受的
徽标验证失败
,用户可以自行决定是否在5秒后关闭我的应用程序并释放文档,或者保存文档并手动关闭我的应用程序
如果您需要广播WM_QUERYENDSESSION
消息,则需要通过
向当前进程中的所有窗口发送消息
。可以从以下位置找到起始示例代码:
但是它只发送WM\u ENDSESSION
消息,您需要使用WM\u QUERYENDSESSION
来代替,并添加给定进程的windows枚举
相关链接:
此外,WM_QueryEndSession之后是WM_EndSession(接收它的应用程序给出了all OK)。非常好-感谢JMD的澄清。我认为必须有一条额外的消息,但我不确定它是什么。我可以使用任何有用的UTIL来发送此类消息,而不是自己制作一条消息吗?我不知道有任何应用程序,但您可以这样做:[DllImport(“user32.dll”)][return:MarshalAs(UnmanagedType.Bool)]static extern Bool PostMessage(HandleRef hWnd、uint Msg、IntPtr wParam、IntPtr lParam);然后只需调用PostMessage(handle、WM_which、IntPtr.Zero、IntPtr.Zero);哦,要从应用程序外部获取窗口句柄,可以使用Visual Studio附带的Spy++或免费提供且易于使用的优秀“Winspector Spy”。太棒了!(我还没有试过——如果有人使用它并能提供反馈,那就太好了)您的链接已断开。徽标测试工具是旧的Windows 7客户端软件徽标程序的一部分。这些工具不再位于Microsoft网站上。这些工具似乎已被Windows应用程序认证工具包取代,该工具包是Windows 10桌面应用程序认证程序的一部分。该工具包仅包含rmtool.exe
yrmlogotest.exe
。我在其他地方写了一点关于rmlogotest.exe
的内容;要阅读我写的内容,请遵循。rmlogotest.exe
确实会向你的应用程序发送一些消息,我怀疑它们与rmtool.exe
用来发送的消息相同,但我没有进行确认。该链接在指示文件不再存在。要打开链接,您可以使用Wayback Machine网站:如何模拟关机来尝试您编写的内容?