是什么导致 SwitchDesktop 在用户解锁会话后无法立即工作?

发布于 2024-12-23 21:50:32 字数 1613 浏览 1 评论 0原文

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

出于测试目的,我在普通的 win32 应用程序中放置了一个按钮来触发开关。它有效,并关闭启动的进程(记事本),我回到原来的桌面。

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

但是,当我尝试在 WTS_SESSION_UNLOCK 消息处理程序中切换桌面时,SwitchDesktop 失败并且 GetLastError 为 0。文档称最后一个错误通常不是由 SwitchDesktop 设置的。

有趣的是,如果我将切换桌面的调用放入 for 循环中,它会在第五次迭代中起作用。

简而言之,这不起作用:

    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 消息后继续运行。它看起来像是常数时间,尽管我没有测量它。

SwitchDesktop 的 MSDN 文档 提到这将因我使用的自定义 Userinit 进程而失败。但是在切换之前获取当前桌面的名称:

wchar_t name[512];
GetUserObjectInformation(GetThreadDesktop(GetCurrentThreadId()), UOI_NAME, name, sizeof(name)/sizeof(*name), 0);
OutputDebugString(name);

始终为我提供默认值。由于 GetLastError 是 0,而不是 5(访问被拒绝),我非常确定在收到 WTS_SESSION_UNLOCK 通知之前,安全桌面已经消失。

我知道屏幕锁定时无法切换桌面,但是桌面解锁后是否有一个“宽限期”,在此期间我无法调用 SwitchDesktop ?

I have a program that switches desktop and start a new process on it. When the process exits, the parent process restores the original desktop.

For testing purposes, I put a button in a plain win32 app that triggers the switch. It works, and closing the launched process (notepad), I go back to the original desktop.

In that same program, I have called WTSRegisterSessionNotification to receive a notification when a session is unlocked (WTS_SESSION_UNLOCK). I receive it.

But when I try to switch desktops in WTS_SESSION_UNLOCK message handler, SwitchDesktop fails and GetLastError is 0. The documentation says that last error is usually not set by SwitchDesktop.

Funny enough, if I put my call to switch desktop in a for loop, it works on the 5th iteration.

In short, this does not work :

    case WM_WTSSESSION_CHANGE:
      if(wParam == WTS_SESSION_UNLOCK)          
      {
          SwitchDesktop(a_valid_desktop_handle);
      }
    break;

But this ugly hack works :

    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;

Setting a timer (to exit the message loop) also works, but it is just a more convoluted form of loop with regards to this problem. SwitchDesktop will work on after a handfull of WM_TIMER messages. It looks like constant time, although I did not measure it.

MSDN documentation for SwitchDesktop mentions that this will fail with a custom Userinit process, which I use. But getting the name of the current desktop just before the switch :

wchar_t name[512];
GetUserObjectInformation(GetThreadDesktop(GetCurrentThreadId()), UOI_NAME, name, sizeof(name)/sizeof(*name), 0);
OutputDebugString(name);

Gives me default all the time. And since GetLastError is 0, not 5 (access denied) I am pretty sure the secure desktop is gone before I receive the WTS_SESSION_UNLOCK notification.

I known I can't switch desktop while the screen is locked, but is there a "grace period" after the desktop is unlocked in which I can't call SwitchDesktop ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

桃扇骨 2024-12-30 21:50:32

当桌面被锁定时,它会切换到为此目的保留的另一个桌面。当您收到该消息时,很可能该桌面仍处于控制状态,并且不允许您进行切换,因为您没有在当前桌面中运行。

When the desktop gets locked, it switches to another desktop which is reserved for this purpose. It is quite possible that when you receive the message, that desktop is still in control and you're not allowed to switch because you're not running in the current desktop.

听,心雨的声音 2024-12-30 21:50:32

我现在无法测试它,但我会将对 SwitchDesktop 的调用不在 WTS_SESSION_UNLOCK 上,而是在 WTS_CONSOLE_CONNECT 上。据我所知,WTS_SESSION_UNLOCK 首先发生,然后您得到 WTS_CONSOLE_CONNECT ,这将与您在“恒定时间”中看到的内容相对应......

I can't test it right now but I would put the call to SwitchDesktop not on WTS_SESSION_UNLOCK but on WTS_CONSOLE_CONNECT. From what I gather WTS_SESSION_UNLOCK occurs first and then your get WTS_CONSOLE_CONNECT which would correspond to what you see with the "constand time"...

×纯※雪 2024-12-30 21:50:32

SwitchDesktop 失败(错误为 0),因为(根据 MSDN)它属于(尚)不可见的窗口站。据我所知,没有任何用户通知显示“HWINSTA 变得可见”。

SwitchDesktop fails (with error 0) because (accordingly to MSDN) it belongs to a window station not (yet) visible. There is no user notification I know of that says "the HWINSTA become visible".

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文