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.

 

 

posted on 2011-07-29 11:48  Lojon  阅读(403)  评论(0编辑  收藏  举报

导航