Service服务程序如何接收消息,帮我看看代码应如何写。(300分)

  • 主题发起人 主题发起人 K
  • 开始时间 开始时间
K

K

Unregistered / Unconfirmed
GUEST, unregistred user!
在DFW BBS上查了很资料,自己理解成下面的写法,可是收不到消息,请各位帮帮我,谢谢。<br>type<br>&nbsp; TsvcSQLServerBackup = class(TService)<br>&nbsp; &nbsp; procedure ServiceStart(Sender: TService; var Started: Boolean);<br>&nbsp; private<br>&nbsp; &nbsp; FHandle:THandle;<br>&nbsp; &nbsp;<br>&nbsp; &nbsp; procedure WndProc(var Msg:TMessage);<br>&nbsp; &nbsp; <br>&nbsp; &nbsp; function WriteEvents(ALogName: string; AEvent: string): Boolean;<br>&nbsp; public<br>&nbsp; &nbsp; Constructor Create;<br>&nbsp; &nbsp; Destructor Destroy; override;<br>&nbsp; &nbsp; property Handle: THandle read FHandle;<br>&nbsp; &nbsp; function GetServiceController: TServiceController; override;<br>&nbsp; &nbsp; { Public declarations }<br>&nbsp; end;<br><br><br>constructor TsvcSQLServerBackup.Create;<br>begin<br>&nbsp; FHandle := AllocateHwnd(WndProc);<br>end;<br><br>destructor TsvcSQLServerBackup.Destroy;<br>begin<br>&nbsp; DeallocateHWnd(FHandle);<br>&nbsp; inherited;<br>end;<br><br>procedure TsvcSQLServerBackup.WndProc(var Msg: TMessage);<br>begin<br>&nbsp; if Msg.Msg = RegisterWindowMessage(WM_WindowMessage) then<br>&nbsp; &nbsp; showmessage('ok');<br>end;<br><br>//在另一个程序中发消息<br>SendMessage(HWND_BROADCAST,RegisterWindowMessage(WM_WindowMessage),0,0);
 
服务是以什么帐户启动的?<br>消息注册没有?<br><br>要使服务收到消息,必须让服务与发消息的程序以同一个用户身份启动,并位于同一个桌面<br>要接收自定义消息,必须注册消息<br><br>参考:Win32 Programmer's Reference中的<br>Window Station and Desktop Functions<br>RegisterWindowMessage
 
消息注册了,在服务程序的:<br>procedure TsvcSQLServerBackup.WndProc(var Msg: TMessage);<br>begin<br>&nbsp; if Msg.Msg = RegisterWindowMessage(WM_WindowMessage) then<br>&nbsp; &nbsp; showmessage('ok');<br>end;<br><br>发送也是调用的RegisterWindowMessage(WM_WindowMessage)<br>其中WM_WindowMessage的字符串相同,不知这样是不是消息注册了。<br>我第一次接触消息,请教教我,谢谢。
 
另外服务运行是正常的,是以Administrator账户运行的。
 
操作系统可能登录有多个用户,每个用户都可以有多个桌面<br>一般GDI对象是每个桌面独立的,即如果你的服务程序与你发消息的程序不在同一个桌面,那么它们是没办法进行消息通讯的<br><br>参考:Win32 Programmer's Reference中的<br>Window Station and Desktop Functions
 
谢谢您的回复,我查了一下服务属性都是以本地用户登陆的,我将允许与桌面交互选项也勾上了,还是没反应!
 
你得试试用FindWindow找不找得到服务的窗口<br>如果找不到,发消息是肯定不行的了,得想其它方法通讯<br>如果找到了,那就是你的接收消息方法有问题
 
Service是没窗口句柄的!所以要想办法创建一个隐藏窗口,这样才能接收并处理消息,但不知我写的代码对不对,另外我发消息是发的广播加RegisterWindowMessage(WM_WindowMessage) 号,我在有窗体的2个程序上试过没问题的,服务类程序就不知如何办了。
 
创建时(启动)注册你的消息<br>FMyHandel:=AllocateHWnd(YourMessage);
 
在服务加个窗口,这个窗口来处理小心怎么样?
 
znj_326:<br>&nbsp; 我将代码移到创建时可还是没反应!你能帮我看看上面的代码错误吗,谢谢。<br><br>private<br>&nbsp; &nbsp; FHandle:THandle;<br>&nbsp; &nbsp;<br>&nbsp; &nbsp; procedure WndProc(var Msg:TMessage);<br><br>procedure TsvcSQLServerBackup.ServiceCreate(Sender: TObject);<br>begin<br>&nbsp; FHandle := AllocateHwnd(WndProc);<br>end;<br><br>procedure TsvcSQLServerBackup.WndProc(var Msg: TMessage);<br>begin<br>&nbsp; if Msg.Msg = RegisterWindowMessage(WM_WindowMessage) then<br>&nbsp; &nbsp; showmessage('ok');<br>end;
 
还是给你个例子吧<br>unit Transmit;<br><br>interface<br><br>uses<br>&nbsp; Windows, Messages, SysUtils, Classes, Graphics, Controls, SvcMgr, Dialogs,<br>&nbsp; ScktComp,winsock;<br><br>&nbsp; const<br>&nbsp; &nbsp; WMDeviceChange = WM_USER+1001;<br><br>type<br>&nbsp; TTranServices = class(TService)<br>&nbsp; &nbsp; procedure ServiceStart(Sender: TService; var Started: Boolean);<br>&nbsp; &nbsp; procedure ServiceStop(Sender: TService; var Stopped: Boolean);<br>&nbsp; private<br>&nbsp; &nbsp; &nbsp;procedure RefMainForm(var Msg:TMessage);<br>&nbsp; &nbsp; { Private declarations }<br>&nbsp; public<br>&nbsp; &nbsp; fHandle:HWND;<br>&nbsp; &nbsp; function GetServiceController: TServiceController; override;<br>&nbsp; &nbsp; { Public declarations } <br>&nbsp; end;<br><br>var<br>&nbsp; TranServices: TTranServices;<br><br>implementation<br><br>{$R *.DFM}<br><br>procedure ServiceController(CtrlCode: DWord); stdcall;<br>begin<br>&nbsp; TranServices.Controller(CtrlCode);<br>end;<br><br>function TTranServices.GetServiceController: TServiceController;<br>begin<br>&nbsp; Result := ServiceController;<br>end;<br><br>procedure TTranServices.ServiceStart(Sender: TService; var Started: Boolean);<br>begin<br>&nbsp; fHandle:=AllocateHWnd(RefMainForm);<br>&nbsp; showmessage(IntToStr(fHandle));<br>end;<br><br>procedure TTranServices.ServiceStop(Sender: TService; var Stopped: Boolean);<br>begin<br>&nbsp; DeallocateHWnd(fHandle);<br>end;<br><br>procedure TTranServices.RefMainForm(var Msg: TMessage);<br>begin<br>&nbsp; if msg.Msg=WMDeviceChange then<br>&nbsp; &nbsp; showmessage('我收到消息了');<br>end;<br><br>end.<br><br><br>TestProgram<br><br>procedure TForm1.Button1Click(Sender: TObject);<br>begin<br>&nbsp; PostMessage(fHandle,WM_USER+1001,0,0);//怎么得到这个fhandle,自己想办法<br>end;
 
谢谢znj_326<br>得到这个fhandle我有办法,难到用RegisterWindowMessage('SQLSERVER')加上SendMessage(HWND_BROADCAST,RegisterWindowMessage('SQLSERVER'),0,0)发广播消息,服务类程序是接收不到的吗?只能知道服务的句柄才可以!<br><br>普通的程序我试过是可以的!
 
经多次试验还是不成功,暂时放弃,如果那位大侠有成功的范例给寄一份,在此多谢了,我的邮件地址:songdl75@126.com
 

Similar threads

后退
顶部