是什么让用户解锁会话后,SwitchDesktop无法正常工作?

我有一个程序可以切换桌面,并启动一个新的进程。 当进程退出时,父进程恢复原始桌面。

出于testing目的,我把一个button放在一个简单的win32应用程序,触发开关。 它的工作原理,closures已启动的进程(记事本),我回到原来的桌面。

在同一个程序中,当会话被解锁时(WTS_SESSION_UNLOCK),我调用WTSRegisterSessionNotification来接收通知。 我收到它。

但是,当我尝试在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; 

设置一个定时器(退出消息循环)也是可行的,但这只是一个更复杂的循环forms,关于这个问题。 SwitchDesktop将在WM_TIMER消息完成后继续工作。 它看起来像不变的时间,虽然我没有测量它。

SwitchDesktop的MSDN文档提到,这将会失败,并使用自定义的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通知之前安全桌面已经消失。

我知道我无法在屏幕locking的情况下切换桌面,但是桌面被解锁后,我无法拨打SwitchDesktop,是否有“宽限期”?

当桌面被锁定时,它切换到为此目的而保留的另一个桌面。 当您收到消息时,很可能该桌面仍在控制之中,因为您没有在当前桌面上运行,所以不允许切换。

我现在不能测试它,但是我不会在WTS_SESSION_UNLOCK上调用WTS_SESSION_UNLOCK而是在WTS_CONSOLE_CONNECT 。 从我收集的WTS_SESSION_UNLOCK首先出现,然后你得到WTS_CONSOLE_CONNECT这将对应于你看到的“constand时间”…