2009-07-15 8 views
54

J'essaie d'écrire dans l'afficheur d'événements dans mon code C#, mais je reçois le merveilleux message "Référence d'objet non définie sur une instance d'un objet". J'apprécierais de l'aide avec ce code, soit ce qui ne va pas ou même une meilleure façon de le faire. Voici ce que j'ai pour écrire dans le journal des événements:C# écrire dans l'afficheur d'événements

private void WriteToEventLog(string message) 
{ 
    string cs = "QualityDocHandler"; 
    EventLog elog = new EventLog(); 
    if (!EventLog.SourceExists(cs)) 
    { 
     EventLog.CreateEventSource(cs, cs); 
    } 
    elog.Source = cs; 
    elog.EnableRaisingEvents = true; 
    elog.WriteEntry(message); 
} 

Et voici où je suis en train de l'appeler:

private readonly Random _rng = new Random(); 
private const string _chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; 
private string RandomString(int size) 
{ 
    try 
    { 
     char[] buffer = new char[size]; 
     for (int i = 0; i < size; i++) 
     { 
      buffer[i] = _chars[_rng.Next(_chars.Length)]; 
     } 
     return new string(buffer); 
    } 
    catch (Exception e) 
    { 
     WriteToEventLog(e.ToString()); 
     return null; 
    } 
} 
+0

sur quelle ligne est l'erreur? – NikolaiDante

+0

s'il vous plaît fournir une trace de la pile –

+1

"Référence de l'objet non défini à une instance d'un objet" - signifie que vous faites référence à une valeur nulle, il est beaucoup plus utile de connaître la ligne de code où cela se produit est-ce que c'est NULL que vous référencez. –

Répondre

87

Le problème est probablement que vous essayez de créer une source d'événement dans un journal qui n'existe pas. Vous devez spécifier le journal "Application".

Essayez de changer à:

if (!EventLog.SourceExists(cs)) 
    EventLog.CreateEventSource(cs, "Application");  

EventLog.WriteEntry(cs, message, EventLogEntryType.Error); 

aussi: A l'intérieur de sharepoint, si l'application est en cours d'exécution en tant que utilisateur connecté (via Windows auth ou délégation), l'utilisateur ne sera pas avoir accès à créer l'événement la source. Si tel est le cas, une astuce consiste à créer l'événement à l'aide d'un thread ThreadPool qui, une fois créé, aura le contexte de sécurité de l'utilisateur que l'App Pool exécute.

22

Voici comment je mis en œuvre la consignation des événements. J'ai créé une interface générique ILogger donc je peux SWAP différents mécanismes de journalisation:

interface ILogger 
{ 
    void Debug(string text); 

    void Warn(string text); 

    void Error(string text); 
    void Error(string text, Exception ex); 
} 

Ma classe de mise en œuvre est très simple:

class EventLogger : ILogger 
{ 
    public void Debug(string text) 
    { 
     EventLog.WriteEntry("MyAppName", text, EventLogEntryType.Information); 
    } 

    public void Warn(string text) 
    { 
     EventLog.WriteEntry("MyAppName", text, EventLogEntryType.Warning); 
    } 

    public void Error(string text) 
    { 
     EventLog.WriteEntry("MyAppName", text, EventLogEntryType.Error); 
    } 

    public void Error(string text, Exception ex) 
    { 
     Error(text); 
     Error(ex.StackTrace); 
    } 
} 

Notez que je ne suis pas instancier EventLog. Pour utiliser je viens de la référence suivante ma classe d'enregistreur (vous pourriez avoir ce retour par une méthode de fabrication statique):

private static readonly ILogger log = new EventLogger(); 

Et l'utilisation réelle est comme ceci:

try 
{ 
    // business logic 
} 
catch (Exception ex) 
{ 
    log.Error("Exception in MyMethodName()", ex); 
} 
+11

c'est bon, mais ça n'a rien à voir avec sa vraie question o.O –

+8

C'est vrai, mais je n'ai pas de stacktrace à partir duquel travailler. – Nelson

+0

Cela aurait effectivement répondu à la question, si vous avez ajouté dans le constructeur par défaut 'if (! EventLog.SourceExists (source))' pour vérifier qu'il existe, et une 'source chaîne const» que vous définissez dans le code (ou via le prop ou le constructeur supplante) et réutiliser à travers la classe.Ensuite, à chaque fois que vous instanciez la classe EventLogger, vous vous assurez que l'erreur réelle rencontrée par l'OP ne se produira pas. J'ai utilisé ce code combiné avec la réponse acceptée. +1 – ppumkin

1
private void WriteEventLogToFile() 
    { 
     try 
     { 
      using (EventLog eventLog = new EventLog("Application")) 
      { 
      // source for your event 
       eventLog.Source = "IAStorDataMgrSvc"; 

      // Syntax details 
      // eventLog.WriteEntry("details",type of event,event id); 
      eventLog.WriteEntry("Hard disk Failure details", EventLogEntryType.Information, 11); 
      } 
     } 
     catch (Exception) 
     { 
      throw; 
     } 
    }