是否有一种方法可以写入这个事件日志:

或者至少是其他一些Windows默认日志,其中我不需要注册事件源?


当前回答

是的,有一种方法可以写入您正在寻找的事件日志。您不需要创建一个新的源,只需简单地使用现有的源,它通常与事件日志的名称相同,并且在某些情况下,如事件日志应用程序,可以在没有管理权限的情况下访问*。

*其他情况下,你不能直接访问它,是安全事件日志,例如,它只能被操作系统访问。

我使用这段代码直接写入事件日志

using (EventLog eventLog = new EventLog("Application")) 
{
    eventLog.Source = "Application"; 
    eventLog.WriteEntry("Log message example", EventLogEntryType.Information, 101, 1); 
}

如您所见,EventLog源与EventLog的名称相同。原因可以在事件源@ Windows Dev Center中找到(我加粗了引用源名称的部分):

Eventlog键中的每个日志都包含称为事件源的子键。事件源是记录该事件的软件的名称。它通常是应用程序的名称,如果应用程序比较大,则是应用程序的子组件的名称。最多可以向注册中心添加16,384个事件源。

其他回答

try

   System.Diagnostics.EventLog appLog = new System.Diagnostics.EventLog();
   appLog.Source = "This Application's Name";
   appLog.WriteEntry("An entry to the Application event log.");

正如MSDN(如。https://msdn.microsoft.com/en-us/library/system.diagnostics.eventlog(v=vs.110).aspx),检查一个不存在的源和创建一个源需要管理员权限。

然而,可以使用源“应用程序”而不使用。 在我在Windows 2012 Server r2下的测试中,我使用“应用程序”源获得了以下日志条目:

The description for Event ID xxxx from source Application cannot be found. Either the component that raises this event is not installed on your local computer or the installation is corrupted. You can install or repair the component on the local computer. If the event originated on another computer, the display information had to be saved with the event. The following information was included with the event: {my event entry message} the message resource is present but the message is not found in the string/message table

我定义了以下方法来创建源代码:

    private string CreateEventSource(string currentAppName)
    {
        string eventSource = currentAppName;
        bool sourceExists;
        try
        {
            // searching the source throws a security exception ONLY if not exists!
            sourceExists = EventLog.SourceExists(eventSource);
            if (!sourceExists)
            {   // no exception until yet means the user as admin privilege
                EventLog.CreateEventSource(eventSource, "Application");
            }
        }
        catch (SecurityException)
        {
            eventSource = "Application";
        }

        return eventSource;
    }

我用currentAppName = AppDomain.CurrentDomain.FriendlyName调用它

也许可以使用EventLogPermission类来代替这个try/catch,但不确定我们是否可以避免catch。

也可以在外部创建源,例如在提升的Powershell中:

New-EventLog -LogName Application -Source MyApp

然后,在上面的方法中使用'MyApp'将不会生成异常,并且可以使用该源创建EventLog。

您可以使用EventLog类,如如何:写入应用程序事件日志(Visual c#)中所述:

var appLog = new EventLog("Application");
appLog.Source = "MySource";
appLog.WriteEntry("Test log message");

但是,你需要使用管理权限来配置这个源“MySource”:

使用WriteEvent和WriteEntry将事件写入事件日志。必须指定事件源来写入事件;在使用事件源写入第一个条目之前,必须创建并配置事件源。

是的,有一种方法可以写入您正在寻找的事件日志。您不需要创建一个新的源,只需简单地使用现有的源,它通常与事件日志的名称相同,并且在某些情况下,如事件日志应用程序,可以在没有管理权限的情况下访问*。

*其他情况下,你不能直接访问它,是安全事件日志,例如,它只能被操作系统访问。

我使用这段代码直接写入事件日志

using (EventLog eventLog = new EventLog("Application")) 
{
    eventLog.Source = "Application"; 
    eventLog.WriteEntry("Log message example", EventLogEntryType.Information, 101, 1); 
}

如您所见,EventLog源与EventLog的名称相同。原因可以在事件源@ Windows Dev Center中找到(我加粗了引用源名称的部分):

Eventlog键中的每个日志都包含称为事件源的子键。事件源是记录该事件的软件的名称。它通常是应用程序的名称,如果应用程序比较大,则是应用程序的子组件的名称。最多可以向注册中心添加16,384个事件源。

This is the logger class that I use. The private Log() method has EventLog.WriteEntry() in it, which is how you actually write to the event log. I'm including all of this code here because it's handy. In addition to logging, this class will also make sure the message isn't too long to write to the event log (it will truncate the message). If the message was too long, you'd get an exception. The caller can also specify the source. If the caller doesn't, this class will get the source. Hope it helps.

顺便说一下,你可以从网上得到一个objectdump。我不想把这些都贴在这里。我从这里得到了我的:C:\Program Files (x86)\Microsoft Visual Studio 10.0\Samples\1033\CSharpSamples.zip\LinqSamples\ objectdump

using System;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Linq;
using System.Reflection;
using Xanico.Core.Utilities;

namespace Xanico.Core
{
    /// <summary>
    /// Logging operations
    /// </summary>
    public static class Logger
    {
        // Note: The actual limit is higher than this, but different Microsoft operating systems actually have
        //       different limits. So just use 30,000 to be safe.
        private const int MaxEventLogEntryLength = 30000;

        /// <summary>
        /// Gets or sets the source/caller. When logging, this logger class will attempt to get the
        /// name of the executing/entry assembly and use that as the source when writing to a log.
        /// In some cases, this class can't get the name of the executing assembly. This only seems
        /// to happen though when the caller is in a separate domain created by its caller. So,
        /// unless you're in that situation, there is no reason to set this. However, if there is
        /// any reason that the source isn't being correctly logged, just set it here when your
        /// process starts.
        /// </summary>
        public static string Source { get; set; }

        /// <summary>
        /// Logs the message, but only if debug logging is true.
        /// </summary>
        /// <param name="message">The message.</param>
        /// <param name="debugLoggingEnabled">if set to <c>true</c> [debug logging enabled].</param>
        /// <param name="source">The name of the app/process calling the logging method. If not provided,
        /// an attempt will be made to get the name of the calling process.</param>
        public static void LogDebug(string message, bool debugLoggingEnabled, string source = "")
        {
            if (debugLoggingEnabled == false) { return; }

            Log(message, EventLogEntryType.Information, source);
        }

        /// <summary>
        /// Logs the information.
        /// </summary>
        /// <param name="message">The message.</param>
        /// <param name="source">The name of the app/process calling the logging method. If not provided,
        /// an attempt will be made to get the name of the calling process.</param>
        public static void LogInformation(string message, string source = "")
        {
            Log(message, EventLogEntryType.Information, source);
        }

        /// <summary>
        /// Logs the warning.
        /// </summary>
        /// <param name="message">The message.</param>
        /// <param name="source">The name of the app/process calling the logging method. If not provided,
        /// an attempt will be made to get the name of the calling process.</param>
        public static void LogWarning(string message, string source = "")
        {
            Log(message, EventLogEntryType.Warning, source);
        }

        /// <summary>
        /// Logs the exception.
        /// </summary>
        /// <param name="ex">The ex.</param>
        /// <param name="source">The name of the app/process calling the logging method. If not provided,
        /// an attempt will be made to get the name of the calling process.</param>
        public static void LogException(Exception ex, string source = "")
        {
            if (ex == null) { throw new ArgumentNullException("ex"); }

            if (Environment.UserInteractive)
            {
                Console.WriteLine(ex.ToString());
            }

            Log(ex.ToString(), EventLogEntryType.Error, source);
        }

        /// <summary>
        /// Recursively gets the properties and values of an object and dumps that to the log.
        /// </summary>
        /// <param name="theObject">The object to log</param>
        [SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "Xanico.Core.Logger.Log(System.String,System.Diagnostics.EventLogEntryType,System.String)")]
        [SuppressMessage("Microsoft.Naming", "CA1720:IdentifiersShouldNotContainTypeNames", MessageId = "object")]
        public static void LogObjectDump(object theObject, string objectName, string source = "")
        {
            const int objectDepth = 5;
            string objectDump = ObjectDumper.GetObjectDump(theObject, objectDepth);

            string prefix = string.Format(CultureInfo.CurrentCulture,
                                          "{0} object dump:{1}",
                                          objectName,
                                          Environment.NewLine);

            Log(prefix + objectDump, EventLogEntryType.Warning, source);
        }

        private static void Log(string message, EventLogEntryType entryType, string source)
        {
            // Note: I got an error that the security log was inaccessible. To get around it, I ran the app as administrator
            //       just once, then I could run it from within VS.

            if (string.IsNullOrWhiteSpace(source))
            {
                source = GetSource();
            }

            string possiblyTruncatedMessage = EnsureLogMessageLimit(message);
            EventLog.WriteEntry(source, possiblyTruncatedMessage, entryType);

            // If we're running a console app, also write the message to the console window.
            if (Environment.UserInteractive)
            {
                Console.WriteLine(message);
            }
        }

        private static string GetSource()
        {
            // If the caller has explicitly set a source value, just use it.
            if (!string.IsNullOrWhiteSpace(Source)) { return Source; }

            try
            {
                var assembly = Assembly.GetEntryAssembly();

                // GetEntryAssembly() can return null when called in the context of a unit test project.
                // That can also happen when called from an app hosted in IIS, or even a windows service.

                if (assembly == null)
                {
                    assembly = Assembly.GetExecutingAssembly();
                }


                if (assembly == null)
                {
                    // From http://stackoverflow.com/a/14165787/279516:
                    assembly = new StackTrace().GetFrames().Last().GetMethod().Module.Assembly;
                }

                if (assembly == null) { return "Unknown"; }

                return assembly.GetName().Name;
            }
            catch
            {
                return "Unknown";
            }
        }

        // Ensures that the log message entry text length does not exceed the event log viewer maximum length of 32766 characters.
        private static string EnsureLogMessageLimit(string logMessage)
        {
            if (logMessage.Length > MaxEventLogEntryLength)
            {
                string truncateWarningText = string.Format(CultureInfo.CurrentCulture, "... | Log Message Truncated [ Limit: {0} ]", MaxEventLogEntryLength);

                // Set the message to the max minus enough room to add the truncate warning.
                logMessage = logMessage.Substring(0, MaxEventLogEntryLength - truncateWarningText.Length);

                logMessage = string.Format(CultureInfo.CurrentCulture, "{0}{1}", logMessage, truncateWarningText);
            }

            return logMessage;
        }
    }
}