Windows Службы выполняются изолированно, в сеансе 0
, в то время как ваше консольное приложение выполняется в сеансе пользователя, поэтому для их взаимодействия друг с другом необходимо создать файл сопоставления памяти в пространстве имен Global\
, сделать его доступным для других сессий. например,
var file = MemoryMappedFile.CreateOrOpen(@"Global\MyMemoryMappedFile", ...
Вы также должны установить соответствующие разрешения для файла, чтобы все пользователи могли получить к нему доступ.
Я бы порекомендовал прочитать это сообщение Реализация Файлы, сопоставленные с непостоянной памятью, раскрывающие связь в стиле IP C со Windows службами , которая более подробно объясняет вышеизложенное и содержит примеры по настройке разрешений, например, c.
Исходный код скопирован с поста, указанного выше:
Создание политики безопасности Mutex, Mutex Security и MMF
bool mutexCreated;
Mutex mutex;
MutexSecurity mutexSecurity = new MutexSecurity();
MemoryMappedFileSecurity mmfSecurity = new MemoryMappedFileSecurity();
mutexSecurity.AddAccessRule(new MutexAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, null),
MutexRights.Synchronize | MutexRights.Modify, AccessControlType.Allow));
mmfSecurity.AddAccessRule(new AccessRule<MemoryMappedFileRights>("everyone", MemoryMappedFileRights.FullControl,
AccessControlType.Allow));
mutex = new Mutex(false, @"Global\MyMutex", out mutexCreated, mutexSecurity);
if (mutexCreated == false) log.DebugFormat("There has been an error creating the mutex");
else log.DebugFormat("mutex created successfully");
Создать & Запись в MMF
MemoryMappedFile file = MemoryMappedFile.CreateOrOpen(@"Global\MyMemoryMappedFile", 4096,
MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.DelayAllocatePages, mmfSecurity,
HandleInheritability.Inheritable);
using (MemoryMappedViewAccessor accessor = file.CreateViewAccessor()) {
string xmlData = SerializeToXml(CurrentJobQueue) + "\0"; // \0 terminates the XML to stop badly formed
issues when the next string written is shorter than the current
byte[] buffer = ConvertStringToByteArray(xmlData);
mutex.WaitOne();
accessor.WriteArray<byte>(0, buffer, 0, buffer.Length);
mutex.ReleaseMutex();
}
Чтение из MMF
using (MemoryMappedFile file = MemoryMappedFile.OpenExisting(
@"Global\MyMemoryMappedFile", MemoryMappedFileRights.Read)) {
using (MemoryMappedViewAccessor accessor =
file.CreateViewAccessor(0, 0, MemoryMappedFileAccess.Read)) {
byte[] buffer = new byte[accessor.Capacity];
Mutex mutex = Mutex.OpenExisting(@"Global\MyMutex");
mutex.WaitOne();
accessor.ReadArray<byte>(0, buffer, 0, buffer.Length);
mutex.ReleaseMutex();
string xmlData = ConvertByteArrayToString(buffer);
data = DeserializeFromXML(xmlData);
}