У меня есть программа, которая переключает рабочий стол и запускает новый процесс. Когда процесс завершается, родительский процесс восстанавливает исходный рабочий стол.Что делает SwitchDesktop не работать сразу после того, как пользователь разблокирует сеанс?
Для тестирования я положил кнопку в обычное приложение 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?
+1 для хорошей идеи, но не совсем ответ ... Вызов SwitchDesktop на WTS_CONSOLE_CONNECT работает в первый раз, каждый раз. Но WTS_CONSOLE_CONNECT не вызывается, когда пользователь блокирует и разблокирует свой сеанс. Чтобы вызвать WTS_CONSOLE_CONNECT, я должен выбрать «Switch user» в меню CTRL-ALT-DEL.Я возвращаюсь к защищенному рабочему столу со всеми плитами пользователя. Я могу войти в систему с одним и тем же пользователем, и я получу WTS_CONSOLE_CONNECT. – ixe013
@ ixe013 Просто интересно, вы когда-нибудь находили решение этого? Я каким-то образом столкнулся с той же проблемой. –
Я сделал что-то, что работало на всех компьютерах, на которых я тестировался, но это квалифицируется как взлом, а не решение. Я в основном делал две вещи. 1. Я добавил 'WTS_CONSOLE_CONNECT' в выражении' switch' моего вопроса, руководствуясь Yahia. 2. После переключения (независимо от результата) я запускаю процесс на рабочем столе * new *. Этот новый процесс также пытается переключить рабочий стол. Другими словами, первый процесс пытается «подтолкнуть» пользователя к новому рабочему столу, а второй пытается «потянуть» его. Переключение всегда выполняется в петле. + Вопрос все еще остается без ответа, @CCInc! – ixe013