У меня есть приложение, которое я записал в.NET. Это должно остаться работать и иметь доступ рабочий стол, на котором диалоговые окна UAC открываются и взаимодействуют с тем настольным использованием события клавиатуры и события от нажатия мыши.
Это - вид подобных программа VNC. Предположите, что Вы запускаете программу VNC, и окно UAC открывается, Вы хотите, чтобы Ваша программа VNC все еще смогла управлять рабочим столом с окном UAC в нем так, чтобы пользователь мог переместить мышь и нажать кнопку OK на диалоговое окно контроля учётных записей. Кто-либо может сказать мне, как я пошел бы о выполнении этого?
Спасибо
Я считаю, что все, что вы видите на экране во время запроса UAC, является снимком экрана (кроме самого диалога)
Проблема в том, что приглашение UAC открывается не на текущем рабочем столе, а на совершенно новом Secure Desktop , который приостанавливает работу всех открытых в данный момент рабочих столов.
Это сделано намеренно, поскольку программам не разрешено взаимодействовать с этим диалоговым окном.
Есть одно исключение: «доверенные процессы СИСТЕМЫ могут выполняться на Secure Desktop», согласно этой записи в блоге .
Вы не можете этого сделать. По умолчанию, когда появляется запрос UAC, он фактически работает на изолированной WinStation, отличной от той, которая запускает «обычные» приложения. Эта WinStation изолирована специально для предотвращения взаимодействия пользовательских приложений с подсказкой UAC. Это похоже на ваш рабочий стол, потому что фон этой WinStation на самом деле является статическим растровым изображением вашего рабочего стола, каким он был непосредственно перед отображением приглашения UAC.
Я подозреваю, что это может быть проблемой в используемой вами версии VNC, поскольку я вполне уверен, что удаленный рабочий стол обеспечивает правильное поведение и позволяет пользователю по-прежнему взаимодействовать с подсказкой UAC через клиент удаленного рабочего стола. Имейте в виду, что при запуске любого удаленного клиента (удаленный рабочий стол, VNC и т. Д.) Идея заключается в том, что клиент должен позволять вам делать все, что вы обычно могли бы делать, если бы физически сидели за клавиатурой.
Я бы посоветовал вам начать с чтения документации. Я бы предположил, что вы можете открыть оконную станцию и прикрепить к ней свой процесс, но я не очень хорошо знаком с этой областью Windows.
Edit 1:
В Windows XP я смог получить доступ к защищенному рабочему столу ("winlogon") через OpenDesktop при запуске от имени SYSTEM; ACL на защищенном рабочем столе разрешает доступ только учетной записи SYSTEM. Открыв его, я смог перечислить окна на нем, хотя их было всего несколько. Возможно, вы могли бы установить крючок окна и прослушивать создание определенного диалога. Я не уверен, изменила ли Vista эту модель, так что, возможно, это не сработает; у меня нет перед глазами машины Vista для тестирования.
Edit 2:
Итак, у меня получилось то, что в основном работает (проверено на Windows 7). Сначала вам нужно запустить службу под именем SYSTEM. Из этой службы вам нужно запустить отдельное приложение в сессии пользователя. Для этого перечислите все процессы в поисках winlogon.exe, откройте его токен и CreateProcessAsUser. Укажите "WinSta0\Winlogon" для параметра lpDesktop в STARTUPINFO. Теперь у вас есть процесс, запущенный от имени SYSTEM в сессии пользователя на рабочем столе "Winlogon". В новом процессе вы можете делать все, что захотите; я провел быстрый тест с EnumDesktopWindows и смог получить класс окна и текст для различных окон, связанных с UAC ("$$$Secure UAP Background Window", "$$$Secure UAP Background Fake Client Window" и т.д.). Я не уверен, как определить, когда отображается приглашение UAC; в качестве быстрого хака вы можете просто запускать цикл каждые 100 мс для поиска окон UAC или что-то в этом роде. Я могу вставить некоторый код, если это поможет.
Edit 3:
Итак, я написал службу Win32, которая принимает следующие параметры:
/install - устанавливает службу
/uninstall - удаляет службу
/service - запускается как служба; вызывается через SCM
/client - запускается как клиент; вызывается через CreateProcessAsUser
Единственный интересный код находится в режимах /service и /client.
В режиме /service он перечисляет запущенные процессы через EnumProcesses и GetModuleFileNameEx в поисках "winlogon.exe". Когда он его находит, он открывает свой токен и запускает себя в режиме /client через CreateProcessAsUser:
HANDLE hProcess = ...;
// winlogon.exe runs as SYSTEM in user's session; we need to run the same way
HANDLE hToken = NULL;
if(OpenProcessToken(hProcess, TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY, &hToken))
{
TCHAR szCommandLine[MAX_PATH];
GetModuleFileName(NULL, szCommandLine, MAX_PATH);
PathQuoteSpaces(szCommandLine);
// run in /client mode
_tcscat_s(szCommandLine, MAX_PATH, _T(" /client"));
STARTUPINFO StartupInfo;
ZeroMemory(&StartupInfo, sizeof(STARTUPINFO));
StartupInfo.cb = sizeof(STARTUPINFO);
// run on the Winlogon desktop
StartupInfo.lpDesktop = _T("WinSta0\\Winlogon");
PROCESS_INFORMATION ProcessInformation;
ZeroMemory(&ProcessInformation, sizeof(PROCESS_INFORMATION));
if(CreateProcessAsUser(hToken, NULL, szCommandLine, NULL, NULL, FALSE, 0, NULL, NULL, &StartupInfo, &ProcessInformation))
{
CloseHandle(ProcessInformation.hThread);
ProcessInformation.hThread = NULL;
CloseHandle(ProcessInformation.hProcess);
ProcessInformation.hProcess = NULL;
}
CloseHandle(hToken);
hToken = NULL;
}
В режиме /client он нажимает кнопку "Yes" на приглашении UAC через кучу вызовов FindWindow и FindWindowEx. Вы можете использовать Spy++, чтобы выяснить иерархию окон.
HWND hWnd = ...;
HWND hWndButton = FindWindowEx(hWnd, NULL, _T("Button"), NULL);
if(hWndButton != NULL)
{
// see if this is the "Yes" button
TCHAR szText[32];
if(GetWindowText(hWndButton, szText, 32) && _tcsicmp(szText, _T("&Yes")) == 0)
{
// click it
SendMessage(hWndButton, BM_CLICK, 0, 0);
}
}
Я проверяю это следующим образом: вставляю Sleep(5000); в код /client. Затем я запускаю службу и сразу же делаю что-то, что вызывает приглашение UAC (например, запускаю regedit). Через 5 секунд код /client проснется, найдет и нажмет кнопку "Да". Вы можете запускать другие процессы на рабочем столе Winlogon; cmd.exe и spyxx.exe (Spy++) наиболее полезны. К сожалению, explorer.exe проявляет много проблем при запуске на рабочем столе Winlogon и не очень полезен. Чтобы попасть на рабочий стол Winlogon, вы можете запустить regedit, а затем Alt+Tab для переключения на другое приложение. Если вы хотите проявить фантазию, вы можете написать собственную утилиту переключения рабочего стола (используя функцию SwitchDesktop), чтобы не вызывать приглашение UAC для перехода на рабочий стол Winlogon. Если вы хотите проявить фантазию, вы можете установить глобальный крючок окна для отслеживания создания окна; когда диалог UAC будет готов к отображению, вы можете подготовиться к нажатию кнопки "Да". Однако я не стал заходить так далеко.
Я могу предположить, что вам, вероятно, нужно работать в качестве службы Windows, чтобы разрешить выполнение, пока активен UAC.