在ClickOnce应用程序中使用EventLog

Fr3*_*dan 6 c# clickonce eventlog-source event-log

我有一个我在多个ClickOnce应用程序中使用的库.如果这个库出错,我想把错误写入windows EventLog.

我发现了一篇知识库文章,但似乎需要管理员权限来搜索源代码.特别是在尝试搜索Security事件日志时会发生窒息.

有没有办法解决这个问题并在ClickOnce应用程序中写入事件日志?我看到一个人试图写一个已知来源,但他们似乎无法找到一直可用的来源.

编辑:

根据这里的答案,我创建了一个程序,该程序包含在我的应用程序中,我可以在第一次运行时运行以设置可以获得管理员权限的事件源.但是一旦创建了源代码,我似乎仍然无法写入它.

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

是否正确创建了一个源(相当于Yannick Blondeau提供的注册表编辑).当我在非提升的应用程序中写入源时,我收到一个新的错误,但它仍然无法正常工作.新错误是:

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

编辑2:

我现在一直试图让它通过CustomSD键上的注册表编辑工作.我尝试添加(A ;; 0x7 ;;; AU)为经过身份验证的用户提供完全访问权限,但似乎没有任何效果.

Joh*_*udd 8

不幸的是,事件源需要创建管理权限.但是,您无需管理员权限即可写入事件日志或从中读取事件日志.

有两种方法可以解决这个问题.

以管理员身份安装应用程序时添加新事件源.

您创建一个简单的应用程序,您作为管理员运行以配置您的应用程序.这甚至可以包含在安装程序中.

如果您没有或不想要安装程序,请将应用程序作为管理员加载到计算机上并运行一次程序.您的应用启动应该配置事件源,如果它还没有,对吧?(好的,这有三种方式.)

此代码段来自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.");
    }
}
Run Code Online (Sandbox Code Playgroud)

我知道它可能不完全是你所追求的,但我认为这是唯一的方法.

编辑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); }
}
Run Code Online (Sandbox Code Playgroud)

这是我实现在生产应用程序中使用的EventLogger类的方式.

如果您可以发布您的代码,我们可以进行比较.

我发生的一件事是,当我创建我的源代码时,我使用应用程序名称,但坚持使用应用程序日志文件.您是否还尝试创建新的日志文件.如果是,请检查它是否在事件查看器中创建.

编辑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();
Run Code Online (Sandbox Code Playgroud)

我没有试过这个,只是因为我的代码正在运行,它来自这里:http://sharenotes.wordpress.com/2008/03/18/cannot-open-log-for-source-you-may-not -具备写访问/