我有一个可以切换桌面并在其上启动新进程的程序。当该进程退出时,父进程将还原原始桌面。
为了进行测试,我在一个简单的win32应用程序中放置了一个按钮来触发切换。它可以正常工作,并关闭启动的进程(记事本),然后回到原始桌面。
在同一程序中,我调用了WTSRegisterSessionNotification来在 session 解锁时接收通知(WTS_SESSION_UNLOCK)。我收到了
但是,当我尝试在WTS_SESSION_UNLOCK消息处理程序中切换桌面时,SwitchDesktop失败,并且GetLastError为0。文档说,最后一个错误通常不是由SwitchDesktop设置的。
有趣的是,如果我将调用切换到for循环中,它将在第5次迭代中起作用。
简而言之,这是行不通的:
case WM_WTSSESSION_CHANGE:
if(wParam == WTS_SESSION_UNLOCK)
{
SwitchDesktop(a_valid_desktop_handle);
}
break;
但这丑陋的黑客作品:
case WM_WTSSESSION_CHANGE:
if(wParam == WTS_SESSION_UNLOCK)
{
for(int i=0; i<10; ++i)
{
if(SwitchDesktop(a_valid_desktop_handle))
{
//This will work when i == 5, maybe 6.
break;
}
}
}
break;
设置计时器(退出消息循环)也可以,但是就此问题而言,它只是一种更复杂的循环形式。一小撮WM_TIMER消息后,SwitchDesktop将继续工作。它看起来像是固定时间,尽管我没有测量它。
MSDN documentation for SwitchDesktop提到使用自定义Userinit进程将失败。但是在开关之前获取当前桌面的名称:
wchar_t name[512];
GetUserObjectInformation(GetThreadDesktop(GetCurrentThreadId()), UOI_NAME, name, sizeof(name)/sizeof(*name), 0);
OutputDebugString(name);
一直给我
default
。而且因为GetLastError
是0,而不是5(访问被拒绝),所以我很确定在收到WTS_SESSION_UNLOCK通知之前安全桌面已消失。我知道屏幕锁定时无法切换桌面,但是解锁桌面后是否有一个“宽限期”,在该时间内我不能调用SwitchDesktop?
最佳答案
当桌面被锁定时,它将切换到为此目的保留的另一个桌面。很有可能,当您收到该消息时,该桌面仍处于控制状态,并且由于您不在当前桌面上运行,因此不允许切换。
关于windows - 是什么让SwitchDesktop在用户解锁 session 后无法立即工作?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/8686123/