如何向Windows服务发送自定义消息?

时间:2010-10-08 10:19:57

标签: windows multithreading delphi service message

我已经实现了一个启动几个工作线程的Windows XP服务应用程序。 从其中一个线程我需要将自定义消息发送回服务。 我该怎么做?

4 个答案:

答案 0 :(得分:1)

一种选择是使用OmniThreadLibrary(例如,阅读this blog post。)

答案 1 :(得分:1)

感谢您的帮助。以下是我解决问题的方法:

在Service类定义中:

  WHandle: HWND;
protected
  procedure HandleServiceMessage(var Msg: TMessage); virtual;

在ServiceExecute方法中:

  WHandle := AllocateHWnd(HandleServiceMessage);
  MyThread := TMyThread.Create(true);
  MyThread.HndMain := WHandle;
  MyThread.Resume;
  while not Terminated do ServiceThread.ProcessRequests(True);
  DeallocateHWnd(WHandle);
end;

在ServiceStop方法中:

  MyThread.Terminate;

处理消息的方法:

procedure TMessageService.HandleServiceMessage(var Msg : TMessage);
var
  Handled: Boolean;
begin
  Handled := True;
  if Msg.Msg = WM_MYMESSAGE then
    Beep
  else
    Handled := False;
  if Handled then
    Msg.Result := 0
  else
    Msg.Result := DefWindowProc(WHandle, Msg.Msg, Msg.WParam, Msg.LParam);
end;

在MyThread.Execute方法中:

  PostMessage(HndMain,WM_MYMESSAGE,0,0);

它的工作正常。

答案 2 :(得分:0)

我同意TOndrej认为共享对象应该足够了。

另一方面,您可以使用我的IPC(Cromis IPC),它在内部服务中运行良好。它易于使用,面向消息,因此您无需知道命名管道如何工作且速度非常快。服务器部分也使用线程池,因此无需等待处理。您可以使用即发即弃的场景。

或者,如果你认为一点点重新设计是可以的,你可以尝试OmniThreadLibrary,它已经内置了所有的消息,并且是为这样的任务而做的。

修改

好吧可能最简洁的方法,没有任何重新设置就是拥有一个受关键部分保护的公共对象列表。工作线程正在添加需要在列表中处理的对象。当添加和对象时,工作线程发出一个事件信号。然后你有一个对象处理线程,它等待WaitForSingleObject用于此事件。一旦将某些内容添加到列表中,就会发出事件信号,处理线程只处理它在列表中找到的所有对象。然后它再次等待。您需要做的就是保护对公共列表的访问。

简化代码如下所示:

WORKER THREAD

ObjectList.Add(MessageObject);
SetEvent(FEvent);

处理线程

while not Terminated do
begin
  WaitForSingleObjest(FEvent, INFINITE);
  // process all the objects
end;

答案 3 :(得分:0)

创建仅限消息的窗口:

procedure TMyService.MessageQueueDispatch(var Message: TMessage);
begin
  Dispatch(Message); //Delphi default dispatcher for TMyService
end;

procedure TMyService.SomeKindOfOnCreate;
begin
  MessageQueue := AllocateHWnd(MessageQueueDispatch);
end;

毁:

procedure TMyService.SomeKindOfDestroy;
begin
  CloseHandle(MessageQueue);
end;

现在您可以像处理表单消息一样处理消息:

TMyService = class(TService)
...
protected
  procedure HandleMyMessage(var msg: TMsg); message WM_MY_MESSAGE;
end;

Delphi Dispatch()处理程序将负责调用该函数。