ServiceApplication With Visiable Form
window station 和desktop。它们主要是用于服务程序,一般的应用程序不必使用它们。它们可以用来对服务进行保护。运行在不同的window station 或不同的desktop下的应用程序,不能互相发送消息、挂钩、使用同一个clipboard等等。主要是出于安全的目的。
服务程序一般使用的是LocalSystem帐户,拥有自己的window station,和Default桌面,这个window station是不能于用户交互的,也就是说,你不能在上面显示窗口,它也不接受用户的鼠标、键盘等输入。
当使用用户帐户登录以后,看到的桌面,是WinSta0(window station)下的Default(desktop).
WinSta0下有3个桌面:
WinLogon :以Logon对话框的形式出现.当用户登录以后,WinLogon.exe切换到Default desktop.
Default :这是Explorer.exe和所有用户程序窗口出现的地方,也就是我们通常使用windows看见的地方.应用程序就运行在这个桌面上
Screen saver :系统空闲的时候,运行屏保的桌面.
可以用下面的方法解决你的问题,使你的服务运行在WinSta0(window station)下的Default(desktop):
桌面-->我的电脑-->右键,在弹出的菜单中选择"管理"-->在左面的一栏中找到"服务和应用程序"-->点击"服务"-->到右面找到你的服务,双击,在弹出的对话框中修改属性,选择“登录”标签页的“允许服务与桌面交互”,那么该服务就使用的是WinSta0(window station)下的Default(desktop). 你也就可以与你的服务进行交互操作了。
但是,做这些之前要考虑清楚。因为,这样你的服务就有安全问题了,任何其他的程序都可以向它发送消息.比如普通程序因为跟你的服务在同一个desktop下,就可以给你发送窗口的关闭消息,迫使退出消息循环,结束服务.或者对你的服务进行键盘、鼠标挂钩(hook)。
以上内容转载自互联网,明白了原理,接下来贴一下自己写的代码备忘,备忘
program ServiceDemo;
uses
SvcMgr,
SysUtils,
Windows,
ServiceUnit in 'ServiceUnit.pas' {DelphiServiceDemo: TService},
FormUnit in 'FormUnit.pas' {DelphiServiceForm};
{$R *.RES}
var
hwinsta, hwinsta_current: Integer;
hdesk, hdesk_current: Integer;
begin
hwinsta_current := GetProcessWindowStation;
hdesk_current := GetThreadDesktop(GetCurrentProcessId);
hwinsta := OpenWindowStation('winsta0', False, WINSTA_ENUMDESKTOPS or WINSTA_READATTRIBUTES or
WINSTA_ACCESSCLIPBOARD or WINSTA_CREATEDESKTOP or WINSTA_WRITEATTRIBUTES or WINSTA_ACCESSGLOBALATOMS or
WINSTA_EXITWINDOWS or WINSTA_ENUMERATE or WINSTA_READSCREEN);
SetProcessWindowStation(hwinsta);
hdesk := OpenDesktop('default', 0, False, DESKTOP_READOBJECTS or DESKTOP_CREATEWINDOW or DESKTOP_CREATEMENU or DESKTOP_HOOKCONTROL or
DESKTOP_JOURNALRECORD or DESKTOP_JOURNALPLAYBACK or DESKTOP_ENUMERATE or DESKTOP_WRITEOBJECTS or
DESKTOP_SWITCHDESKTOP);
SetThreadDesktop(hdesk);
SetProcessWindowStation(hwinsta_current);
SetThreadDesktop(hdesk_current);
Application.Initialize;
Application.CreateForm(TDelphiServiceDemo, DelphiServiceDemo);
Application.CreateForm(TDelphiServiceForm, DelphiServiceForm);
Application.Run;
CloseWindowStation(hwinsta);
CloseDesktop(hdesk);
end.