![]() |
|
Модераторы: Snowy, bartram, MetalFan, bems, Poseidon, Riply |
![]()
|
|
| yogin |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 88 Регистрация: 23.12.2007 Репутация: нет Всего: нет |
Есть приложение, делает скрины каждые 10 секунд и сохраняет их на диске(регистратор визуальных действий). Недавно заметил, что окно "Контроль учётных записей пользователей" совсем не фоткается - его нет на скринах.
А оно так часто появляется... почти при запуске каждой проги. Как его запечатлить? Скрин делается обычным способом:
Может нужно скринить как-то по другому? Или ещё есть мысль - может быть нужно проматывать все существующие окна, смотреть на их какие-нибудь идентификаторы и определять UAC это окно или нет и если да, то скринить само окно через его дескриптор? И следующий вопрос, а даст ли система свободу на все эти действия или тоже увильнёт как и от скрина?... |
|||
|
||||
| kami |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1806 Регистрация: 25.8.2007 Где: Санкт-Петербург Репутация: 15 Всего: 72 |
UAC "выскакивает" на отдельном десктопе.
Порядок действия его, afair, следующий: - скрин десктопа - переключение на специфический десктоп - отображение скрина - создание окна "запустить/не запустить" Соответственно, если скриншотящее приложение запущено под пользовательской терминальной сессией (и т.д.), то нужно пробовать SetThreadDektop, чтобы суметь сделать скрин этого специфического десктопа. Afair, читал это в статьях Руссиновича. Это сообщение отредактировал(а) kami - 9.4.2012, 22:28 |
|||
|
||||
| kami |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1806 Регистрация: 25.8.2007 Где: Санкт-Петербург Репутация: 15 Всего: 72 |
Это сообщение отредактировал(а) kami - 9.4.2012, 22:47 |
|||
|
||||
| yogin |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 88 Регистрация: 23.12.2007 Репутация: нет Всего: нет |
Так... правильно ли я понял,
что мне надо запомнить Handle текущего десктопа методом GetThreadDesktop(GetCurrentThreadId), затем как-то узнать Handle десктопа, созданного UAC'ом, потом переключиться на него командой SwitchDesktop(), сделать скрин обычным методом через GetDC(0), а потом переключиться обратно тем же методом SwitchDesktop(OldDT) ? Тогда вопрос, а как узнать хэндл окна UAC'а? Или второй вариант: мне надо не GetDC(0) делать, а постоянно вызывать сначало GetThreadDesktop(GetCurrentThreadId), и уже относительно результата получать дескриптор? Тогда вопрос, как получать дескриптор в этом случае? так: GetDC(GetThreadDesktop(GetCurrentThreadId)) ? |
|||
|
||||
| kami |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1806 Регистрация: 25.8.2007 Где: Санкт-Петербург Репутация: 15 Всего: 72 |
не совсем так.
Есть ряд проблем с этой задачей. 1. Я не нашел функцию, позволяющую отследить смену десктопа, наподобие WTSRegisterSessionNotification, без этого имхо придется постоянно отслеживать через OpenInputDesktop 2. C учетом того, что UAC показывается на Winlogon -десктопе. последний абзац по ссылке. Это печально. Вообще - читать Thread connection to desktop. Могу посоветовать обратиться к Eraser-у на форуме delphimaster.ru, он при создании своего RemoteOfficeManager как-то обошел это. Если отбросить все сложности, то (имхо) должно выглядеть так: 1. Запоминаем текущий десктоп потока. 2. OpenInputDesktop 3. SetThreadDesktop 4. Снимок экрана 5. SetThreadDesktop(старый десктоп) 6. Освободить все полученные хендлы. Кстати, не стоит забывать, что Winlogon - не единственный десктоп, отличный от winsta0\default. Есть куча программ (например, Марка Руссиновича), которые создают дополнительные десктопы и позволяют оперативно переключаться между ними. Иногда - очень полезная штука Вечером еще пошукаю MSDN, но думаю нечего нового не скажу. |
|||
|
||||
| yogin |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 88 Регистрация: 23.12.2007 Репутация: нет Всего: нет |
В ROM'е используется драйвер стандартного MS'овского удалённого рабочего стола. Так что это не то... |
|||
|
||||
| yogin |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 88 Регистрация: 23.12.2007 Репутация: нет Всего: нет |
Правильно ли я понял, что перед каждым снимком мне надо создавать новый десктоп(OpenInputDesktop), потом фоткать обычным методом(GetDC(0)), а потом возвращаться к предыдущему десктопу.
При этом фоткаться будет всё, т.к. мой новый десктоп будет как бы поверх всех существующих?... |
|||
|
||||
| kami |
|
||||||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1806 Регистрация: 25.8.2007 Где: Санкт-Петербург Репутация: 15 Всего: 72 |
Ну, OpenInputDesktop - это не создание нового десктопа, а попытка "подключения" к существующему. Емнип(было дело - разрабатывал программу удаленного администрирования), нет. Достаточно один раз открыть и потом делать снимки. Опять-таки емнип, если делать снимки через BitBlt, то когда десктоп, DC которого получен, становится неактивным, то BitBlt начинает возвращать ошибку. Вот тогда и понадобится повторение всей последовательности от OpenInputDesktop и далее. Хотя... снимок раз в 10 секунд... можно каждый раз и полную последовательность, это не куча снимков за секунду.
Вряд ли. хочу еще раз обратить внимание на:
Имхо - получить доступ к UAC-окну, даже если использовать запуск "из-под админа" у десктопного приложения не получится. |
||||||
|
|||||||
| yogin |
|
||||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 88 Регистрация: 23.12.2007 Репутация: нет Всего: нет |
Кароч делаю так:
SetThreadDesktop всегда False, т.к.: <<MSDN - function SetThreadDesktop - Remarks>>
Поэтому сдаётся мне процесс скрининга надо реализовывать сервисным приложением... И видимо надо интерактивный сервис, чтобы скрин как-то передават "нормальному" приложению с формой, которое уже будет выполнять сохранение куда надо или отображение на форме... |
||||
|
|||||
| kami |
|
||||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1806 Регистрация: 25.8.2007 Где: Санкт-Петербург Репутация: 15 Всего: 72 |
к потоку в сервисе ведь точно такие же требования - отсутствие окон и хуков при переключении. Причем окно ведь не обязательно визуальное, хватит и таймера, в котором используется AllocateHwnd. В ОС, в которых появился UAC, интерактивные сервисы запрещены. В Vista была специализированная служба, которая отлавливала попытку отображения чего-то визуального интерактивным сервисом и предлагала показать "это" на специализированном десктопе, не имеющем никакого отношения к Winlogon-у. А вообще, интерактивные службы в Vista и 7 не являются такими, какими они задумывались изначально - они не имеют доступа даже к обычному десктопу обычного пользователя, так как находятся в отличной от пользовательской терминальной сессии. То есть - не являются интерактивными.
Обычно делают наоборот |
||||
|
|||||
| CodeMonkey |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1839 Регистрация: 24.6.2008 Где: Россия, Тверь Репутация: 16 Всего: 89 |
-------------------- Опытный программист на C++ легко решает любые не существующие в Паскале проблемы. |
|||
|
||||
| yogin |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 88 Регистрация: 23.12.2007 Репутация: нет Всего: нет |
Хорошо, тогда обычный сервис, но порядок действий-то будет в нём таким же? Тогда просто самим сервисом сохранять файлы? CodeMonkey, я сделал так как там написано(вручную отключил), но обычные методы скрининга всё равно не запечатлили окно UAC, лишь тень от него. |
|||
|
||||
| yogin |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 88 Регистрация: 23.12.2007 Репутация: нет Всего: нет |
Опытным путём метода тыка выяснено:
1) что фотки UAC'а получаются в нормальном приложении, если это приложение запустить от имени системы... 2) а служба не может ничего сфоткать потому что ей в нормальном режиме десктопы не доступны(в 7-ке)... Вытекающие вопросы: 1) как можно службой запустить приложение, чтобы у него были её права(или права системы), но при этом оно имело доступ к едсктопам? 2) можно ли как-то в винде назначить, чтобы прога автоматом запускалась с правами системы? |
|||
|
||||
| kami |
|
||||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1806 Регистрация: 25.8.2007 Где: Санкт-Петербург Репутация: 15 Всего: 72 |
Ага, у пользователя своя терминальная сессия, а у сервисов - своя. И у каждой своя WinSta и свой десктоп...
Единственное, что нашел - это Starting an interactive process. Но, хоть в community пишут, что она работает (только acl-ы нужно потом удалить, даже код есть как) у меня не получилось портировать это хозяйство на Delphi. Вернее, получилось (отрабатывает без ошибок), но процесс запускается не интерактивный, а непойми в какой WinSta... До того, как увидел этот код, получалось запустить из сервиса десктопное приложение, но так как токену сессии, от которой запускался процесс, не давали права админа (было Deny), то ни о каких дополнительных плюшках речи не шло. К сожалению, Deny ни на что другое поменять нельзя... На последний вопрос ничего не скажу - не знаю... Добавлено @ 13:20 Кстати, не пробовал еще получать токен не через LogonUser, а через GetActiveConsoleSessionID и далее... Это сообщение отредактировал(а) kami - 1.6.2012, 13:20 |
||||
|
|||||
| drkot |
|
|||
![]() Ищущий ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1042 Регистрация: 5.5.2006 Репутация: нет Всего: 8 |
Сразу оговорюсь... то что напишу не есть "правильно" с точки зрения системного подхода ОС, но значительно проще и гуманнее относительно программиста. Принцип прост: любое приложение может посылать (создавать) записи в системном журнале событий. В системном планировщике есть возможность привязки задачи к журналу событий. Для реализации такого механизма не нужно ковырять права и переключаться между сессиями... что значительно упростит задачу для начинающего. Права на запуск задаются в том же планировщике -------------------- Ошибка не становится истиной по причине широкого распространения, как и Истина не становится Ошибкой из-за того, что никто её не видит. |
|||
|
||||
![]()
|
| Правила форума "Delphi: WinAPI и системное программирование" | |
|
|
Запрещено: 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, bartram, MetalFan, bems, Poseidon, Rrader, Riply. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Delphi: WinAPI и системное программирование | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |