How to use named mutex and shared memory between a windows service and a process?
I'm have a code written in C++\MFC that开发者_开发百科 is run as a Windows Service and a (normal) C++\MFC Windows process - now I wish to communicate between the two using named Mutex and Shared memory (File mapping).
How is that possible ?
It depends on your communication requirements. Generally the service creates the mutex and shared memory and the clients open them and do stuff. OutputDebugString() is a classic example of IPC using a mutex and shared memory (and some events). Here is a detailed examination of how OutputDebugString() works; you could do something similar.
I suggest the following
service creates a mutex, 2 events and a memory mapped file(m.m.f), all named
when the service has to send data to the other process
a. takes ownership of the mutex
b. writes data to m.m.f.
c. signals event#1 which means that the service has new information for the program
d. releases the mutex
when the program want to send data to the service
a. takes ownership of the mutex
b. writes data to m.m.f.
c. signals event#2 which means that the program has new info for the service
d. releases the mutex
the service checks to see if event#2 is on. If not goes on doing its stuff, else it:
a. takes ownership of the m.m.f
b. reads data
c. resets event#2
d. releases mutex
the program checks to see if event#1 is on. If not goes on doing its stuff, else it:
a. takes ownership of the m.m.f
b. reads data
c. resets event#1
d. releases mutext
The problem with this approach is that messages could be lost (when for example the service manages to write 2 messages in a row, before the program can read the first) AND only 1 process can attach itself to the service (you have to make sure about it)
I suggest a socket based solution, if that is possible, where neighter of these problems occur.
P.S. you can use the m.m.f to make some kind of queue to avoid the first problem
Main problem in that mechanism of synchronization(Service <-> Process), you should open named mutex/semaphore or ect. from Process when Service and Process ran under diffrent user names in the OS. Necessary use 'Global' prefix before any name of object synchronization. But before that, you must reset Dacl for your synchronize objects. This example is works:
// Service code (LocalSystem account)
PSECURITY_DESCRIPTOR pSessionSD = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH);
if (!pSessionSD)
{
ERR(TEXT("LocalAlloc error."));
}
if (!InitializeSecurityDescriptor(pSessionSD, SECURITY_DESCRIPTOR_REVISION))
{
ERR(TEXT("InitializeSecurityDescriptor error."));
}
if (!SetSecurityDescriptorDacl(pSessionSD, TRUE, NULL, FALSE))
{
ERR(TEXT("SetSecurityDescriptorDacl error"));
}
SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(sa);
sa.lpSecurityDescriptor = pSessionSD;
sa.bInheritHandle = FALSE;
const TCHAR sz_global_prefix[] = TEXT("Global\\");
const TCHAR sz_krnl_mutex_name[] = TEXT("MyKernelMutex");
TCHAR sz_global_kernel_name[MAX_PATH]{};
_tcscpy_s(sz_global_kernel_name, sz_global_prefix);
_tcscpy_s(sz_global_kernel_name, sz_krnl_mutex_name);
CreateMutex(&sa, false, krnl_mutex_name);
.........
// Process code (User account)
OpenMutex(MUTEX_ALL_ACCESS, false, TEXT("Global\\MyKernelMutex"));
....
精彩评论