2012-09-24 13 views
6

Ho una libreria che utilizzo su più applicazioni ClickOnce. In caso di errore in questa libreria, vorrei scrivere l'errore su Windows EventLog.Utilizzo di EventLog nell'applicazione ClickOnce

Ho trovato un KB article su come ma sembra che questo richiede autorizzazioni di amministratore per cercare il per la fonte. In particolare soffoca quando cerca di cercare il registro eventi Security.

Esiste comunque una soluzione per aggirare questo problema e scrivere nel registro eventi in un'applicazione ClickOnce? Ho visto una persona trying to write to a known source, ma non sembravano essere in grado di trovare una fonte che fosse sempre disponibile.

EDIT:

Sulla base di risposte qui ho creare un programma che è incluso con la mia applicazione che posso correre alla prima esecuzione per impostare l'origine eventi che può ottenere privilegi di amministratore. Tuttavia, una volta creata la fonte, sembra che non riesca ancora a scriverlo.

/// <summary> 
    /// The main entry point for the application. 
    /// </summary> 
    [STAThread] 
    static void Main() 
    { 
     if (!EventLog.SourceExists("ATE")) 
     { 
      EventLog.CreateEventSource("ATE", "Application"); 
     } 
    } 

Crea correttamente una fonte (che è equivalente alla modifica del Registro di sistema fornita da Yannick Blondeau). Quando scrivo all'origine nella mia applicazione non elevata, ricevo un nuovo errore, ma non funziona ancora. Il nuovo errore è:

Cannot open log for source 'ATE'. You may not have write access.

EDIT 2:

Ora ho cercato di farlo funzionare attraverso il Registro di modifica sul CustomSD key. Ho provato ad aggiungere (A ;; 0x7 ;;; AU) per dare agli utenti autenticati pieno accesso ma non sembrava avere alcun effetto.

risposta

8

Sfortunatamente, la fonte dell'evento richiede la creazione di privilegi amministrativi. Tuttavia, non è necessario disporre dei diritti di amministratore per scrivere nel registro eventi o leggere da esso.

Ci sono due modi per aggirare questo problema.

Si aggiunge la nuova origine evento quando si installa l'applicazione come amministratore.

Si crea una semplice app che si esegue come amministratore per configurare l'applicazione. Questo potrebbe anche essere incluso nell'installer.

Se non si dispone o si desidera un programma di installazione, caricare l'app sul computer come amministratore ed eseguire il programma una volta. L'avvio dell'app dovrebbe configurare l'origine degli eventi se non è già presente comunque, giusto? (Va bene, questo è tre modi.)

Questo snippet di codice proviene da microsoft: http://msdn.microsoft.com/en-us/library/system.diagnostics.eventlog.aspx ed è progettato per essere eseguito come utente amministratore.

So che potrebbe non essere esattamente quello che cercavi, ma penso che sia l'unico modo per farlo.

EDIT 1: Aggiunto un po 'di codice

public class EventLogger 
{ 
    private const string logName = "Application"; 
    private static string appName = ""; 
    private static bool sourceExists = false; 

    public static string AppName 
    { 
     get { return appName; } 
     set { appName = value; } 
    } 

    public static void Init(string appName) 
    { 
     AppName = appName; 
     sourceExists = EventLog.SourceExists(AppName); 

     if (!sourceExists) 
     { 
      EventLog.CreateEventSource(AppName, logName); 
      sourceExists = true; 
     } 
    } 

    private static void Write(string entry, EventLogEntryType logType, int eventID) 
    { 
     if (sourceExists) 
     { 
      EventLog.WriteEntry(AppName, entry, logType, eventID); 
     } 
    } 

    public static void Warning(string entry) { Write(entry, EventLogEntryType.Warning, 200); } 
    public static void Warning(string entry, int eventID) { Write(entry, EventLogEntryType.Warning, eventID); } 
    public static void Error(string entry) { Write(entry, EventLogEntryType.Error, 300); } 
    public static void Error(string entry, int eventID) { Write(entry, EventLogEntryType.Error, eventID); } 
    public static void Info(string entry) { Write(entry, EventLogEntryType.Information, 100); } 
    public static void Info(string entry, int eventID) { Write(entry, EventLogEntryType.Information, eventID); } 
} 

Questo è il modo che ho implementato la mia classe EventLogger che è in uso in un'applicazione di produzione.

Se si potesse pubblicare il tuo codice possiamo fare un confronto.

Una cosa che mi viene in mente è che quando creo la mia fonte, io uso il nome dell'applicazione, ma bastone con il file di log dell'applicazione. Stai anche tentando di creare un nuovo file di registro. In tal caso, verificare che sia stato creato nel Visualizzatore eventi.

EDIT 2: rappresentare l'utente con un valore di token dell'utente zero

Questo è un po 'uno Stumper.

provare questo codice, avvolta intorno al codice di scrittura dell'evento.

System.Security.Principal.WindowsImpersonationContext wic = System.Security.Principal.WindowsIdentity.Impersonate(IntPtr.Zero); 
// your code to write to event log or any to do something which needs elevated permission-- 
wic.Undo(); 

Non ho provato questo, semplicemente perché il mio codice funziona, viene da qui: http://sharenotes.wordpress.com/2008/03/18/cannot-open-log-for-source-you-may-not-have-write-access/

+0

Penso che la tua terza idea di caricare un app e l'esecuzione di una volta dovrà essere la mia soluzione, come l'intero scopo di ClickOnce che gestisce la distribuzione e l'installazione. Tuttavia, anche se creo la fonte dell'evento in tale applicazione, ricevo un errore quando vado a scrivere su di essa. Dice "Impossibile aprire il registro per l'origine" MySource ". Potresti non avere accesso in scrittura." Sembra che mi sto avvicinando, ma non è proprio lì. – Fr33dan

+0

Hai chiuso l'applicazione prima di provare a scrivere? In quel frammento di codice da MS dichiarano esplicitamente che la sorgente log non dovrebbe essere creata e immediatamente utilizzata in quanto vi è un periodo di latenza necessario per abilitare l'origine. –

+0

Sì, al momento ho eseguito manualmente l'applicazione di configurazione per vedere se avrebbe funzionato, quindi c'erano oltre 20 secondi tra la creazione dell'origine e il tentativo di scrivere su di essa. – Fr33dan

0

Nel ClickOnce documentation, si dice che se l'utente che esegue un'applicazione ClickOnce non è un amministratore , l'applicazione non riuscirà a scrivere nel registro eventi.

citazione completa:

Dopo una distribuzione ClickOnce, l'applicazione creerà un sorgente di evento, se non esiste già quando l'applicazione tenta di scrivere un evento nel registro eventi. Se l'utente non è un amministratore, il tentativo è e l'applicazione non registra alcun evento. In questo caso , è possibile creare manualmente l'origine evento.

Per creare l'origine evento manualmente, si dovrà aggiungere una voce nel Registro di sistema come questo durante il processo di distribuzione:

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Application\YourApp] 
"EventMessageFile"="%SystemRoot%\\Microsoft.NET\\Framework\\v2.0.50727\\EventLogMessages.dll" 

Questo approccio sarà limitare la necessità di elevazione alla fase di realizzazione.

+0

Poiché ClickOnce gestisce la distribuzione e l'installazione, dovrei trovare un altro modo per eseguirlo come amministratore. Ho creato un eseguibile pacchetto per eseguire il codice come amministratore. La modifica del registro crea l'origine evento, ma continuo a ricevere l'errore "Impossibile aprire il registro per l'origine" MySource ". Potresti non avere accesso in scrittura." quando provo a scriverlo – Fr33dan

2

Un approccio alternativo a questo è quello di scaricare il file setup.exe ClickOnce, fare clic destro e Esegui come amministratore. Non è molto soddisfacente, ma sembra funzionare.