Снимок экрана процесса под Windows Service - PullRequest
5 голосов
/ 18 сентября 2009

Мы должны запустить процесс из службы Windows и получить от него скриншот.

Мы пробовали вызовы BitBlt и PrintWindow Win32, но оба дают пустые (черные) растровые изображения.

Если мы запускаем наш код из обычного пользовательского процесса, он работает просто отлично.

Это даже возможно? Или может быть другой способ попробовать?

То, что мы пробовали:

  1. Служба Windows работает как локальная система, процесс запускается как локальная система -> сбой скриншота
  2. Служба Windows, работающая от имени администратора, запускает процесс от имени администратора -> Снимок экрана не выполняется.
  3. Приложение Windows, работающее как пользователь XYZ, запускает процесс как XYZ -> снимок экрана работает как с BitBlt, так и с PrintWindow.
  4. Пробная проверка «Разрешить службе взаимодействовать с рабочим столом» из локальной системы

Мы также заметили, что PrintWindow лучше работает в нашем случае, если оно находится за другим окном.

Для других требований родительский и дочерний процессы должны находиться под одним и тем же пользователем. Мы не можем использовать олицетворение от одного процесса к другому.

Ответы [ 4 ]

6 голосов
/ 19 мая 2010

В настоящее время я не могу найти соответствующие ссылки, но проблема в том, что служба Windows работает в другом сеансе, чем обычное пользовательское приложение.

В XP это было не совсем так. Вот все службы, запущенные в сеансе 0, и первый пользователь, который войдет в систему, также запустится в сеансе 0. Так что в этом случае приемы типа Разрешить службе взаимодействовать с рабочим столом работают. Но если вы быстро переключаетесь на другого пользователя, он получает сессию 1 и не имеет возможности напрямую взаимодействовать с сервисом. Это также верно, если вы подключаетесь через RDP к версии сервера (например, 2003 или 2008). Эти входы также начнутся в сеансе выше 0.

Наконец, что не менее важно, есть еще один недостаток, связанный с использованием рабочего стола:
Если вы включите эту опцию и ваша служба будет работать под учетной записью (по умолчанию) SYSTEM, она больше не сможет создавать сетевое соединение.

Правильный способ получить пользовательский графический интерфейс, который работает со службой, состоит в том, чтобы разделить их на два процесса и выполнить своего рода IPC (межпроцессное взаимодействие). Таким образом, служба запустится, когда машина включится, и приложение GUI будет запущено в пользовательском сеансе. В этом случае графический пользовательский интерфейс может создать снимок экрана, отправить его в службу, а служба может делать с ним все что угодно.

3 голосов
/ 23 сентября 2009

Я не думаю, что это возможно.

Нам пришлось изменить наш сценарий, когда наше приложение не запускалось из службы, а представляло собой стандартную программу Windows с NotifyIcon в углу.

Если кто-то все еще находит реальный ответ, дайте мне знать.

3 голосов
/ 18 сентября 2009

Вы пытались работать как локальная система с установленным флажком «Разрешить службе взаимодействовать с рабочим столом»?

0 голосов
/ 19 мая 2010

Работает с использованием локальной системы с «Разрешить сервис взаимодействовать с рабочим столом»

Вы можете установить его программно, используя этот пример кода:

http://www.vbforums.com/showthread.php?t=367177 (это vb.net, но очень просто)

...