Как я запускаю свое приложение, в то время как диалоговое окно UAC показывает?

У меня есть приложение, которое я записал в.NET. Это должно остаться работать и иметь доступ рабочий стол, на котором диалоговые окна UAC открываются и взаимодействуют с тем настольным использованием события клавиатуры и события от нажатия мыши.

Это - вид подобных программа VNC. Предположите, что Вы запускаете программу VNC, и окно UAC открывается, Вы хотите, чтобы Ваша программа VNC все еще смогла управлять рабочим столом с окном UAC в нем так, чтобы пользователь мог переместить мышь и нажать кнопку OK на диалоговое окно контроля учётных записей. Кто-либо может сказать мне, как я пошел бы о выполнении этого?

Спасибо

8
задан Daniel Imms 1 May 2012 в 09:59
поделиться

5 ответов

Я считаю, что все, что вы видите на экране во время запроса UAC, является снимком экрана (кроме самого диалога)

0
ответ дан 5 December 2019 в 18:57
поделиться

Проблема в том, что приглашение UAC открывается не на текущем рабочем столе, а на совершенно новом Secure Desktop , который приостанавливает работу всех открытых в данный момент рабочих столов.

Это сделано намеренно, поскольку программам не разрешено взаимодействовать с этим диалоговым окном.

Есть одно исключение: «доверенные процессы СИСТЕМЫ могут выполняться на Secure Desktop», согласно этой записи в блоге .

4
ответ дан 5 December 2019 в 18:57
поделиться

Вы не можете этого сделать. По умолчанию, когда появляется запрос UAC, он фактически работает на изолированной WinStation, отличной от той, которая запускает «обычные» приложения. Эта WinStation изолирована специально для предотвращения взаимодействия пользовательских приложений с подсказкой UAC. Это похоже на ваш рабочий стол, потому что фон этой WinStation на самом деле является статическим растровым изображением вашего рабочего стола, каким он был непосредственно перед отображением приглашения UAC.

Я подозреваю, что это может быть проблемой в используемой вами версии VNC, поскольку я вполне уверен, что удаленный рабочий стол обеспечивает правильное поведение и позволяет пользователю по-прежнему взаимодействовать с подсказкой UAC через клиент удаленного рабочего стола. Имейте в виду, что при запуске любого удаленного клиента (удаленный рабочий стол, VNC и т. Д.) Идея заключается в том, что клиент должен позволять вам делать все, что вы обычно могли бы делать, если бы физически сидели за клавиатурой.

-1
ответ дан 5 December 2019 в 18:57
поделиться

Я бы посоветовал вам начать с чтения документации. Я бы предположил, что вы можете открыть оконную станцию и прикрепить к ней свой процесс, но я не очень хорошо знаком с этой областью 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 будет готов к отображению, вы можете подготовиться к нажатию кнопки "Да". Однако я не стал заходить так далеко.

6
ответ дан 5 December 2019 в 18:57
поделиться

Я могу предположить, что вам, вероятно, нужно работать в качестве службы Windows, чтобы разрешить выполнение, пока активен UAC.

0
ответ дан 5 December 2019 в 18:57
поделиться
Другие вопросы по тегам:

Похожие вопросы: