问题
I have written a service in VC++. I followed the tutorial here. Now, I am trying to find out how to receive messages like DBT_DEVICEARRIVAL, DBT_DEVICEREMOVECOMPLETE, WM_COPYDATA etc., just like a regular application that has a top level window. When searching for it, I came across this MSDN article
In the "Broadcasting Messages" section, in the final paragraphs:
Applications receive messages through the window procedure of their top-level windows. Messages are not sent to child windows. Services can receive messages through a window procedure or their service control handlers.
But it is almost impossible to find any example of how to do it.
How can I associate a WndProc with my service so that it receives messages?
Or, how can I make my service control handler function to receive windows messages? My service control handler has only one DWORD parameter and not the UINT, WPARAM, LPARAM etc of a WndProc.
I have read about 1) using a hidden window and 2) a message only window etc., but I don't think I can use them in a service; don't want to. It'd be happy if I can accomplish it in either of those two ways which MSDN mentions.
Description of service:
The service will detect USB device insertion and copy some files to it. It also has to keep track of changes to some directories and files so that it knows which ones to copy.
This basic functionality may be extended to include other things, in the future. So, I may have to be able to receive many other windows messages which I am not aware of now.
The example messages mentioned above are simply taken from what I am used to, when developing a regular windows app. I understand if they are not suitable or safe, when writing a service.
回答1:
Uhm you simply create an ordinary message loop as you would if you wrote a pure C implementation of a Win32 windowed application - without any frameworks involved.
Example:
while(GetMessage(...)) ...
You can either use PeekMessage
or GetMessage (see the linked docs). But the latter is more conventional and removes it from the queue of messages.
I.e. you don't even need a window. Every thread can have a message loop. So it will be blocking, but only the current thread. You gotta figure out on your own how to relay the information to the other thread requiring it.
The big however
But instead of working on compromising something that MS put up for you not to shoot yourself your lower body off, you should read about Shatter Attacks over on Wikipedia and use a proper IPC technique for a service (there are plenty available, from MMF to pipes to combinations with semaphores, mutexes and events).
This part is relevant if you intend to receive window messages on a user desktop but with your privileged context (which session separation should prevent anyway).
回答2:
Use RegisterServiceCtrlHandlerEx function with HandlerEx callback function.
Yes, as pointed by 0xC0000022L is better use IPC technique, for example named pipes - my favourite. :)
来源:https://stackoverflow.com/questions/15141529/receive-windows-messages-in-a-service