Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Получение снимка экрана в сервисе


Автор: nda 15.2.2016, 15:23
Добрый день. Народ подскажите пожалуйста.
Пишу сервис для винды, суть его очень просто через определенное время делает снимок экрана. Но проблема в следующем когда запускаю сервис мне вместо снимков экрана сохраняется белый фон, а когда тот же код запускаю с переложения все нормально. 
Вот код
Код

procedure TService1.Timer1Timer(Sender: TObject);
var
 Bmp:TBitmap;
 Screen:TCanvas;
 R:TRect;
 WinSta:HWINSTA;
 Desk:HDESK;
begin
 GetDesktopWindow;
 WinSta:=OpenWindowStation('WinSta0',False,WINSTA_READSCREEN);
 SetProcessWindowStation(WinSta);
 Desk:=OpenDesktop('Default',0,False,DESKTOP_SWITCHDESKTOP);
 SetThreadDesktop(Desk);
 Bmp:=TBitmap.Create;
 Bmp.Width:=1024;
 Bmp.Height:=768;
 Screen:=TCanvas.Create;
 Screen.Handle:=GetDC(0);
 R:=Rect(0,0,1023,767);
 Bmp.Canvas.CopyRect(R,Screen,R);
 ReleaseDC(0,Screen.Handle);
 Screen.Free;
 Bmp.SaveToFile('d:\'+inttostr(kol)+'.bmp');
 Bmp.Free;
 kol:=kol+1;
end;


и еще вот такой использовал

Код

var bmp: TBitmap;
    jpg: TJpegImage;
begin
  bmp := TBitmap.Create;
  jpg:=TJpegImage.Create;
  try
    bmp.Width := Screen.Width;
    bmp.Height := Screen.Height;
    BitBlt(bmp.Canvas.Handle, 0, 0, Screen.Width, Screen.Height, GetDC(GetDesktopWindow), 0, 0, SRCCopy);
//    Clipboard.Assign(bmp);
    bmp.SaveToFile('D:\2.bmp');
      {создаем экземпляр объекта}

    {присваиваем ему изображение}
     jpg.Assign(bmp);
     {устанавливаем степень сжатия (качество) 1..100}
     jpg.CompressionQuality:=50;
    {Упаковываем графику}
     jpg.Compress;
    {и сохраняем ее куда вам захочется}
     jpg.SaveToFile('D:\1.jpg');
    {уничтожаем экземпляр объекта}


  finally
    bmp.Free;
    jpg.free;
  end;


Подскажите как сделать так чтобы с сервиса (службы) тоже снимок экрана делался нормально.

Автор: kami 15.2.2016, 22:01
если коротко - то никак.

А теперь немножко подробнее:
у каждого пользователя в Windows - своя сессия, свой рабочий стол, свой экран. Это же относится и к сервисам - у них свой рабочий стол под учетной записью LOCAL SYSTEM (или другой - в зависимости от типа логина). Времена, когда сервис мог подключиться к активной сессии пользователя минули с окончанием эры Windows XP. Начиная с Vista разделение жесткое, без права на амнистию. Разные сессии не могут получить доступ к объектам друг друга. Это относится в том числе к Inter-process communications - самый распространенный механизм (Send и PostMessage) не работает между сессиями. Остаются другие способы (MMF, NamedPipes, TCP/IP...), но у них нужно явно указывать права доступа.

К чему я это все? Непосредственно из сервиса сделать снимок активного рабочего стола нельзя - у него другая сессия. Для того, чтобы совершить подобное сервису нужно:
1. Запустить новый "обычный" процесс от имени активной учетки.
2. Соединиться с ним через любой вид межпроцессного взаимодействия, позволяющий работать из разных сессий
3. Отправить команду в приложение "дай мне снимок экрана" и получить от нее данные.

На форуме есть темы, как сделать это всё. Емнип, в основном - в разделе WinAPI. Поищите...

Автор: nda 25.2.2016, 17:21
спасибо за помощь kami.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)