delphi - Why the screenshot doesn't work (black screen)? -


service "allow service interact desktop".

unit unit1;  interface  uses windows, messages, sysutils, classes, graphics, controls, svcmgr, dialogs;  type   tcopydesk = class(tservice)   procedure servicecontinue(sender: tservice; var continued: boolean);   procedure serviceexecute(sender: tservice);   procedure servicepause(sender: tservice; var paused: boolean);   procedure serviceshutdown(sender: tservice);   procedure servicestart(sender: tservice; var started: boolean);   procedure servicestop(sender: tservice; var stopped: boolean);   private     procedure copyscreen(const index: integer);   public     function getservicecontroller: tservicecontroller; override;   end;  var   copydesk: tcopydesk;  implementation  {$r *.dfm}  procedure servicecontroller(ctrlcode: dword); stdcall; begin   copydesk.controller(ctrlcode); end;  procedure tcopydesk.copyscreen(const index: integer); const   defaultwindowstation = 'winsta0';   defaultdesktop = 'default';   captureblt = $40000000;   winsta_all_access = $0000037f; var   bmp: tbitmap;   hwinstasave: hwinsta;   hdesksave: hdesk;   hwinstauser: hwinsta;   hdeskuser: hdesk;   dwthreadid: dword;   hdcscreen : hdc;   hdccompatible : hdc;   hbmscreen : hbitmap; begin   hwinstauser:= openwindowstation(defaultwindowstation, false, winsta_all_access);    hwinstasave:= getprocesswindowstation;   if hwinstauser = 0   begin     outputdebugstring(pchar('openwindowstation failed' + syserrormessage       (getlasterror)));     exit;   end;    if not setprocesswindowstation(hwinstauser)   begin     outputdebugstring('setprocesswindowstation failed');     exit;   end;  //  hdeskuser:= opendesktop(defaultdesktop, 0, false, maximum_allowed);   hdeskuser:= openinputdesktop(0, false, maximum_allowed);   if hdeskuser = 0   begin     outputdebugstring('opendesktop failed');     setprocesswindowstation (hwinstasave);     closewindowstation (hwinstauser);     exit;   end;   dwthreadid:= getcurrentthreadid;    hdesksave:= getthreaddesktop(dwthreadid);    if not setthreaddesktop(hdeskuser)   begin     outputdebugstring(pchar('setthreaddesktop' + syserrormessage(getlasterror)));     exit;   end;    try     hdcscreen := getdc(0);//getdc(getdesktopwindow);//createdc('display', nil, nil, nil);     hdccompatible := createcompatibledc(hdcscreen);     hbmscreen := createcompatiblebitmap(hdcscreen,                      getdevicecaps(hdcscreen, horzres),                      getdevicecaps(hdcscreen, vertres));     selectobject(hdccompatible, hbmscreen);     bmp:= tbitmap.create;     bmp.handle:= hbmscreen;     bitblt(hdccompatible, 0,0, bmp.width, bmp.height, hdcscreen, 0,0, srccopy or captureblt);     bmp.savetofile('c:\users\public\screenshot\' + inttostr(index) + '.bmp');       deletedc(hdcscreen);     deletedc(hdccompatible);     bmp.free;     bmp:= nil;   end;   setthreaddesktop(hdesksave);   setprocesswindowstation(hwinstasave);   if hwinstauser <> 0     closewindowstation(hwinstauser);   if hdeskuser <> 0     closedesktop(hdeskuser); end;  function tcopydesk.getservicecontroller: tservicecontroller; begin   result := servicecontroller; end;  procedure tcopydesk.servicecontinue(sender: tservice;   var continued: boolean); begin   while not terminated   begin     sleep(10);     servicethread.processrequests(false);   end; end;  procedure tcopydesk.serviceexecute(sender: tservice); var   index: integer; begin   index:= 0;   while not terminated   begin     copyscreen(index);     inc(index);     servicethread.processrequests(false); //    sleep(1000); //    if index = 4       dostop;   end; end;  procedure tcopydesk.servicepause(sender: tservice; var paused: boolean); begin   paused:= true; end;  procedure tcopydesk.serviceshutdown(sender: tservice); begin   status:= csstopped;   reportstatus(); end;  procedure tcopydesk.servicestart(sender: tservice; var started: boolean); begin   started:= true; end;  procedure tcopydesk.servicestop(sender: tservice; var stopped: boolean); begin   stopped:= true; end; end. 

in vista , later, service won't able take screenshot, or otherwise interact desktop -- "allow service interact desktop" no longer supported. services run in isolated session can't interact desktop. more details, read on "session 0 isolation".

for more background why, this thread explains:

as multiples sessions running because of terminal services or remote desktop connections there no 1 one relationship between service , interactive window station 1 desktop. can have 1 per interactive session. 1 should service talk to? if nobody looks @ desktop of machine service runs on - nobody notices messagebox or whatever ui stuff.

relying on "feature" not adequate anymore. rid of it, there no alternative.


Comments

Popular posts from this blog

linux - Using a Cron Job to check if my mod_wsgi / apache server is running and restart -

actionscript 3 - TweenLite does not work with object -

jQuery Ajax Render Fragments OR Whole Page -