Delphi的TService的輸入桌面切換(服务程序)(windows登录界面如何截图)(使用了OpenDesktop和GetThreadDesktop等API)

摘要:
dfm:objectCopyDeskService:TCopyDeskServiceOldCreateOrder=FalseOnCreate=ServiceCreateOnDestroy=ServiceDestroyAllowPause=FalseDisplayName='CopyDeskService'Interactive=TrueLeft=192Top=107Height=150Width=

dfm:

object CopyDeskService: TCopyDeskService
OldCreateOrder = False
OnCreate = ServiceCreate
OnDestroy = ServiceDestroy
AllowPause = False
DisplayName = 'Copy Desk Service'
Interactive = True
Left = 192
Top = 107
Height = 150
Width = 215
end

pas:

unit Main;

interface

uses
Windows, SysUtils, Classes, Graphics, SvcMgr;

type
TCopyThread = class(TThread)
private
FIndex: DWORD;
FScrBmp: TBitmap;
protected
procedure Execute; override;
public
constructor Create; reintroduce;
destructor Destroy; override;
end;

TCopyDeskService = class(TService)
procedure ServiceCreate(Sender: TObject);
procedure ServiceDestroy(Sender: TObject);
private
FCopyThread: TCopyThread;
public
function GetServiceController: TServiceController; override;
end;

var
CopyDeskService: TCopyDeskService;

implementation

{$R *.DFM}

procedure ServiceController(CtrlCode: DWord); stdcall;
begin
CopyDeskService.Controller(CtrlCode);
end;

function TCopyDeskService.GetServiceController: TServiceController;
begin
Result := ServiceController;
end;

procedure TCopyDeskService.ServiceCreate(Sender: TObject);
begin
FCopyThread := TCopyThread.Create;
end;

procedure TCopyDeskService.ServiceDestroy(Sender: TObject);
begin
FCopyThread.Terminate;
end;

function SelectHDESK(HNewDesk: HDESK): Boolean; stdcall;
var
HOldDesk: HDESK;
dwDummy: DWORD;
sName: array[0..255] of Char;
begin
Result := False;
HOldDesk := GetThreadDesktop(GetCurrentThreadId);
if (not GetUserObjectInformation(HNewDesk, UOI_NAME, @sName[0], 256, dwDummy)) then
begin
OutputDebugString('GetUserObjectInformation Failed.');
Exit;
end;
if (not SetThreadDesktop(HNewDesk)) then
begin
OutputDebugString('SetThreadDesktop Failed.');
Exit;
end;
if (not CloseDesktop(HOldDesk)) then
begin
OutputDebugString('CloseDesktop Failed.');
Exit;
end;
Result := True;
end;

function SelectDesktop(pName: PChar): Boolean; stdcall;
var
HDesktop: HDESK;
begin
Result := False;
if Assigned(pName) then
HDesktop := OpenDesktop(pName, 0, False,
DESKTOP_CREATEMENU or DESKTOP_CREATEWINDOW or
DESKTOP_ENUMERATE or DESKTOP_HOOKCONTROL or
DESKTOP_WRITEOBJECTS or DESKTOP_READOBJECTS or
DESKTOP_SWITCHDESKTOP or GENERIC_WRITE)
else
HDesktop := OpenInputDesktop(0, False,
DESKTOP_CREATEMENU or DESKTOP_CREATEWINDOW or
DESKTOP_ENUMERATE or DESKTOP_HOOKCONTROL or
DESKTOP_WRITEOBJECTS or DESKTOP_READOBJECTS or
DESKTOP_SWITCHDESKTOP or GENERIC_WRITE);
if (HDesktop = 0) then
begin
OutputDebugString(PChar('Get Desktop Failed: ' + IntToStr(GetLastError)));
Exit;
end;
Result := SelectHDESK(HDesktop);
end;

function InputDesktopSelected: Boolean; stdcall;
var
HThdDesk: HDESK;
HInpDesk: HDESK;
dwError: DWORD;
dwDummy: DWORD;
sThdName: array[0..255] of Char;
sInpName: array[0..255] of Char;
begin
Result := False;
HThdDesk := GetThreadDesktop(GetCurrentThreadId);
HInpDesk := OpenInputDesktop(0, False,
DESKTOP_CREATEMENU or DESKTOP_CREATEWINDOW or
DESKTOP_ENUMERATE or DESKTOP_HOOKCONTROL or
DESKTOP_WRITEOBJECTS or DESKTOP_READOBJECTS or
DESKTOP_SWITCHDESKTOP);
if (HInpDesk = 0) then
begin
OutputDebugString('OpenInputDesktop Failed.');
dwError := GetLastError;
Result := (dwError = 170);
Exit;
end;
if (not GetUserObjectInformation(HThdDesk, UOI_NAME, @sThdName[0], 256, dwDummy)) then
begin
OutputDebugString('GetUserObjectInformation HThdDesk Failed.');
CloseDesktop(HInpDesk);
Exit;
end;
if (not GetUserObjectInformation(HInpDesk, UOI_NAME, @sInpName[0], 256, dwDummy)) then
begin
OutputDebugString('GetUserObjectInformation HInpDesk Failed.');
CloseDesktop(HInpDesk);
Exit;
end;
CloseDesktop(HInpDesk);
Result := (lstrcmp(sThdName, sInpName) = 0);
end;

procedure CopyScreen(Bmp: TBitmap; out Index: DWORD);
var
DC: HDC;
begin
DC := GetDC(0);
Bmp.Width := GetSystemMetrics(SM_CXSCREEN);
Bmp.Height := GetSystemMetrics(SM_CYSCREEN);
Bmp.Canvas.Lock;
try
BitBlt(Bmp.Canvas.Handle, 0, 0, Bmp.Width, Bmp.Height, DC, 0, 0, SRCCOPY);
Bmp.SaveToFile('j:/p' + IntToStr(Index) + '.bmp');
Inc(Index);
finally
Bmp.Canvas.Unlock;
ReleaseDC(0, DC);
end;
end;

constructor TCopyThread.Create;
begin
FreeOnTerminate := True;
FScrBmp := TBitmap.Create;
FScrBmp.PixelFormat := pf8bit;
FIndex := 0;
inherited Create(False);
end;

destructor TCopyThread.Destroy;
begin
FScrBmp.Free;
FScrBmp := nil;
inherited;
end;

procedure TCopyThread.Execute;
begin
while (not Terminated) do
begin
if InputDesktopSelected then CopyScreen(FScrBmp, FIndex)
else if SelectDesktop(nil) then CopyScreen(FScrBmp, FIndex);
Sleep(3000);
end;
end;

end.

http://blog.csdn.net/cdlff/article/details/3489941

因为锁定界面后Windows切换到Session0去了,而你的程序运行在当前用户Session.

WTS系API可以帮你,去Sesson0重新运行一个进程截好图后通过IPC返回当前进程就好了.

对了,Session0隔离从Windows Vista开始引入.另外2ccc应该有一个WSDT的单元,可惜2ccc不支持内容搜索

http://bbs.2ccc.com/topic.asp?topicid=506628

免责声明:文章转载自《Delphi的TService的輸入桌面切換(服务程序)(windows登录界面如何截图)(使用了OpenDesktop和GetThreadDesktop等API)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇JavaScript打印杨辉三角Jmeter从数据库中读取数据下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Delphi 编译程序乱码(非中文系统)的处理

Delphi 编译程序乱码(非中文系统)的处理 Delphi7 编译的程序是 非unicode程序,在非中文系统环境下,会出现乱码 方法一: 1、在控制面板,区域-格式:  2、区域,管理,设置:  3、在主界面程序里面加 initialization SetThreadLocale($0804); //2052 setconsoleoutpu...

Delphi 条件判断那些事

技术交流,DH讲解. 之前照着天书夜读,用Delphi来弄了下循环体,现在就来弄一下条件判断吧.首先肯定是我们经常看见的IF语句咯. Var I: Integer; Begin I:= 99; If (I> 0)And (I< 0) Then Writeln('I>0') Else If (I> 10)...

delphi各种用法

调用外部程序,等待外部程序运行完成,相当于Showmodal功能,呵呵 delphi代码1.function WinExecAndWait32(FileName: string; Visibility: Boolean): integer;   2.var  3.  zAppName: array[0..512] of char; //存放应用程序名  4...

delphi 安卓配置教程

本教程以 delphi 10.2.2.2004 为例,演示 delphi 安卓配置步骤 1.打开 Android Tools 2. 选择合适的版本。比如:我的小米4 LTE 是 andorid 6.0 ,我就选 android 6.0 (API23) 和 23.0.1 ,其它可以一律不选。 明白了吧,更多详细步骤,请自动搜索 android 工具配置方法...

Delphi:RzPageControl(pagecontrol)实现多标签的动态添加,切换,关闭

使用RzPageControl来实现多标签页使用菜单来打开标签页,通过标签页的caption来判断将标签页是否已经被打开过了. 1.创建标签页,并判断是否是已经打开过的页面   procedure TFmain.Page1Click(Sender: TObject);varnewpage:TRzTabSheet;index:integer;beginnew...

Delphi 发送邮件 通过Office Outlook

   Delphi 发送邮件 通过Office Outlook        网上搜到的Delphi邮件发送系统,绝大多数是使用SMTP协议来发送。 但是事实上它们已经过时了,大多数邮件服务器已经屏蔽了Delphi Indy的邮件发送,从而导致Delphi发送不成功。 事实上,让Delphi通过Outlook.Application来发送邮件,也是非常方...