我有一个程序可以切换桌面并在其上启动新进程。进程退出时,父进程将恢复原始桌面。
出于测试目的,我在一个触发切换的普通win32应用程序中放了一个按钮。它工作正常,关闭启动的进程(记事本),我回到原来的桌面。
在同一个程序中,我调用了WTSRegisterSessionNotification以在会话解锁时接收通知(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;
设置一个计时器(退出消息循环)也有效,但对于这个问题,它只是一个更复杂的循环形式。 SwitchDesktop将在完成一系列WM_TIMER消息后继续工作。它看起来像是不变的时间,虽然我没有测量它。
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?
答案 0 :(得分:3)
当桌面被锁定时,它会切换到为此目的保留的另一个桌面。很可能当您收到消息时,该桌面仍然处于控制状态,并且您不允许切换,因为您没有在当前桌面上运行。
答案 1 :(得分:2)
我现在无法对其进行测试,但我会将SwitchDesktop
的来电置于WTS_SESSION_UNLOCK
而不是WTS_CONSOLE_CONNECT
上。从我收集的内容WTS_SESSION_UNLOCK
首先出现,然后得到WTS_CONSOLE_CONNECT
,这与您在“constand time”中看到的内容相对应...
答案 2 :(得分:0)
SwitchDesktop失败(错误0),因为(因此对MSDN)它属于一个尚未可见的窗口站。我知道没有用户通知说“HWINSTA变得可见”。