2012-07-18 7 views
5

Sto tentando di implementare un file di mapping della memoria all'interno della mia applicazione (in particolare un servizio di Windows), quindi utilizzare un modulo C# per leggere dal MMF al quale scrive il servizio. Sfortunatamente non riesco a ottenere il modulo per leggere nulla dal file MMF, ancora più importante sembra che il modulo non trovi mai il file MMF creato dal servizio. Di seguito sono riportati frammenti di codice che illustrano cosa sto facendo, qualcuno può vedere cosa sto facendo male o essere in grado di indicarmi una direzione migliore?Problemi di lettura dal file di mappatura della memoria

Servizio:

private MemoryMappedFile mmf = MemoryMappedFile.CreateOrOpen("AuditStream", 1024 * 1024); 
private Mutex mutex = new Mutex(false, "MyMutex"); 

byte[] msg = new byte[1]; 
var view = mmf.CreateViewStream(0, 1); 
byte[] rmsg = new byte[1]; 

for (int i = 0; i < 400; i++) 
{ 
    mutex.WaitOne(); 
    for (int j = 0; j < msg.Length; j++) 
    { 
      msg[j] = (byte)i; 
    } 

    view.Position = 0; 
    view.Write(msg, 0, bufferSize); 

    //the next 3 lines verify that i wrote to the mmf and can potentially read from it 
    //These are just for testing 
    view.Position = 0; 
    view.Read(rmsg, 0, 1); 
    Log.Error("Finished MMF", rmsg[0].ToString()); 

    mutex.ReleaseMutex(); 
} 

Forma:

private MemoryMappedFile mmf; 
private Mutex mutex; 
Thread t = new Thread(MmfMonitor); 
t.Start(); 

private void MmfMonitor() 
    { 

     byte[] message = new byte[1]; 
     while(!quit) 
     { 
      try 
      { 
       **mmf = MemoryMappedFile.OpenExisting("AuditStream");** 
       mutex = Mutex.OpenExisting("MyMutex"); 
       var view = mmf.CreateViewStream(0, 1); 

       mutex.WaitOne(); 
       view.Position = 0; 
       view.Read(message, 0, 1); 
       Invoke(new UpdateLabelCallback(UpdateLabel), message[0].ToString()); 
       mutex.ReleaseMutex(); 
      }catch(FileNotFoundException) 
      { 
       **//The AuditStream MMF is never found, and therefore doesnt every see the proper values** 
      } 
     } 
    } 

Inoltre, mentre il servizio è 'esecuzione', il MMF deve sempre avere una maniglia e non dovrebbe ottenere raccolti dal garbage collector;

+0

Così, * non * ottiene il FileNotFoundException? –

+0

Il modulo è in esecuzione nella stessa directory del servizio? A volte la directory predefinita del servizio è c: \ windows \ system32 Vorrei provare a specificare il percorso completo del file, non un percorso relativo come "AuditStream" –

+1

Qual è l'account con cui viene eseguito il servizio? – HABO

risposta

13

Il servizio viene eseguito in una sessione diversa, la famosa "sessione 0". Gli oggetti Windows vivono in uno spazio dei nomi associato alla sessione del processo, pertanto il modulo non può vedere l'oggetto creato nella sessione utilizzata dal servizio.

È necessario anteporre Global\ al nome mmf per creare e accedere all'oggetto nello spazio dei nomi globale.

Così nel servizio:

mmf = MemoryMappedFile.CreateOrOpen(@"Global\AuditStream", ...) 

e nella forma:

mmf = MemoryMappedFile.OpenExisting(@"Global\AuditStream"); 
+0

Grazie a te che l'hai fatto !, ora devo solo lottare con un errore di accesso negato su quello. – Zholen

+0

Voglio aggiungere per gli altri che visualizzano questo post, per non dimenticare di fare lo stesso con il tuo mutex ("Globale"), molto probabilmente incontrerai un problema di accesso una volta che puoi vedere il flusso il seguente è un modo per risolverlo, anche se lo lascia molto 'aperto': – Zholen

+8

var security = new MemoryMappedFileSecurity(); security.AddAccessRule (nuovo AccessRule ("Everyone", MemoryMappedFileRights.FullControl, AccessControlType.Allow)); mmf = MemoryMappedFile.CreateOrOpen (@ "Global \ AmToteAuditStream", 1024 * 1024, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.DelayAllocatePages, security, HandleInheritability.Inheritable); – Zholen