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
Post a Comment