Использование EventLog в приложении ClickOnce

у меня есть библиотека, которую я использую в нескольких приложениях ClickOnce. В случае ошибки в этой библиотеке я хотел бы написать ошибку в windows EventLog.

нашел KB статья о том, как, но кажется,что для этого требуются разрешения администратора для поиска источника. В частности, он задыхается при попытке поиска Security журнал событий.

есть ли в любом случае, чтобы обойти это и записать в журнал событий в ClickOnce заявление? Я видел одного человека попытка написать известному источнику, но они, похоже, не смогли найти источник, который был бы постоянно доступен.

EDIT:

на основе ответов здесь я создаю программу, которая входит в мое приложение, которое я могу запустить при первом запуске, чтобы настроить источник событий, который может получить права администратора. Однако, как только источник создан, кажется, я все еще не могу написать ему.

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

Is правильно создает источник (что эквивалентно редактированию реестра, предоставленному Yannick Blondeau). Когда я пишу источнику в своем приложении без повышенных прав, я получаю новую ошибку, но она все равно не работает. Новая ошибка:

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

EDIT 2:

теперь я пытаюсь заставить его работать через изменения реестра на ключ CustomSD. Я попытался добавить (A;; 0x7;;; AU), чтобы предоставить аутентифицированным пользователям полный доступ, но это не кажется, есть какой-то эффект.

3 ответов


к сожалению, источник событий требует создания административных priveledges. Однако, вам не нужны права администратора для записи в журнал событий, или читать из него.

есть два способа обойти это.

вы добавляете новый источник событий при установке приложения в качестве администратора.

вы создаете простое приложение, которое вы запускаете в качестве администратора для настройки приложения. Это может быть даже включено в программу установки.

Если вы не или установщика, то загрузите приложение на компьютер как администратор и запустить программу. Ваш запуск приложения должен настроить источник событий, если он еще не существует, верно? (Хорошо, это три способа.)

этот фрагмент кода от microsoft:http://msdn.microsoft.com/en-us/library/system.diagnostics.eventlog.aspx и предназначен для запуска от имени администратора.

using System;
using System.Diagnostics;
using System.Threading;

class MySample
{
    public static void Main()
    {
        // Create the source, if it does not already exist. 
        if (!EventLog.SourceExists("MySource"))
        {
             //An event log source should not be created and immediately used. 
             //There is a latency time to enable the source, it should be created 
             //prior to executing the application that uses the source. 
             //Execute this sample a second time to use the new source.
             EventLog.CreateEventSource("MySource", "MyNewLog");
             Console.WriteLine("CreatedEventSource");
             Console.WriteLine("Exiting, execute the application a second time to use the source.");
            // The source is created.  Exit the application to allow it to be registered. 
            return;
        }
        // Create an EventLog instance and assign its source.
        EventLog myLog = new EventLog();
        myLog.Source = "MySource";

        // Write an informational entry to the event log.    
        myLog.WriteEntry("Writing to event log.");
    }
}

Я знаю, что это может быть не совсем то, что вы хотели, но я считаю это единственный способ сделать это.

EDIT 1: добавлен дополнительный код

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); }
}

таким образом я реализовал класс EventLogger, который используется в производственном приложении.

Если вы могли бы опубликовать свой код, мы можем сделать сравнение.

мне приходит в голову, что при создании источника я использую имя приложения, но придерживаюсь файла журнала приложения. Вы также пытаетесь создать новый файл журнала. Если так убедитесь, что он создан в средстве просмотра событий.

EDIT 2: олицетворение Пользователя со значением токена пользователя ноль

Это немного сложно.

попробуйте этот код, обернутый вокруг события написания кода.

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();

Я не пробовал это, просто потому, что мой код работает, он исходит отсюда: http://sharenotes.wordpress.com/2008/03/18/cannot-open-log-for-source-you-may-not-have-write-access/


альтернативным подходом к этому является загрузка установки ClickOnce.exe-файл, щелкните правой кнопкой мыши и запустите от имени администратора. Не очень удовлетворительно, но, кажется, работает.


на документация ClickOnce, говорится, что если пользователь, запускающий приложение ClickOnce, не является администратором, приложение не сможет записать в журнал событий.

полная цитата:

после развертывания ClickOnce приложение создаст событие источник, если он еще не существует, когда приложение пытается запись события в журнал событий. Если пользователь не является администратором, попытка не удалась, и приложение не будет регистрировать события. В этом случае, вы можете создать источник событий вручную.

чтобы создать источник событий вручную, вам нужно будет добавить такую запись в реестр во время процесса развертывания:

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

этот подход ограничит потребность в высоте на этапе развертывания.