我有一个可以切换桌面并在其上启动新进程的程序。当该进程退出时,父进程将还原原始桌面。

为了进行测试,我在一个简单的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/

10-10 14:14