写入Windows应用程序事件日志写入Windows应用程序事件日志(Write to Window

2019-05-13 04:39发布

有没有写这个事件日志的方式:

或者至少,一些其他Windows默认的日志, 在那里我没有注册的事件源

Answer 1:

是的,有写日志,你正在寻找的事件的方式。 你并不需要创建一个新的来源,只是简单地使用一个存在的,往往具有相同的名称作为事件日志的名字,并在某些情况下,如事件日志,应用程序,可以没有管理权限*访问。

*其他情况下,如果你不能直接访问它,是安全日志,例如,仅由操作系统访问。

我用这个代码直接写入到事件日志的应用:

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

正如你所看到的,事件日志来源是一样的事件日志的名称。 这样做的原因可以发现事件源@ Windows开发人员中心 (我粗体这是指源名称的部分):

每个日志中的事件日志项中包含子项叫做事件源。 事件源记录事件的软件的名称。 它往往是应用程序或者应用程序是大型应用程序的子组件的名称的名称 。 您最多16,384事件源可以添加到注册表中。



Answer 2:

您可以使用EventLog类,如在解释如何:写入应用程序事件日志(Visual C#中) :

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

但是,你需要配置该 “MYSOURCE”使用管理权限:

使用WriteEvent和WriteEntry将事件写入事件日志。 您必须指定一个事件源写事件; 您必须创建并写入与源的第一项之前配置事件源。



Answer 3:

这是我使用的记录器类。 私人日志()方法EventLog.WriteEntry()在里面,这是你如何实际写入到事件日志。 我包括所有这些代码都在这里,因为它的方便。 除了记录,这个类也将确保信息不会太长写入到事件日志(它将截断的消息)。 如果消息太长,你会得到一个异常。 呼叫者也可以指定源。 如果主叫方没有,这个类会得到源。 希望能帮助到你。

顺便说一句,你可以从网上的ObjectDumper。 我不想在这里发布了这一切。 我得到了我在这里: C:\Program Files (x86)\Microsoft Visual Studio 10.0\Samples\1033\CSharpSamples.zip\LinqSamples\ObjectDumper

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


Answer 4:

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

但是,可以使用源“应用程序”没有。 在我在Windows 2012服务器R2的测试,但是我使用“应用程序”的源获得以下日志项:

用于从源应用程序事件ID XXXX的描述不能被发现。 要么引发此事件的组件未安装在本地计算机上或安装已损坏。 您可以安装或修复组件在本地计算机上。 如果该事件源于另一台计算机上,显示信息必须与事件被保存。 下面的信息包括与事件:{我的事件登录信息}消息资源是存在的,但该消息没有在字符串/消息表中找到

我定义下面的方法来创建源:

    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叫它

这可能是可以使用的,而不是这个try / catch语句,但不能肯定我们能够避免的渔获EventLogPermission类。

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

New-EventLog -LogName Application -Source MyApp

然后,在该方法中使用“MyApp的”上面不会产生异常,事件日志可以与该源被创建。



Answer 5:

尝试

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


文章来源: Write to Windows Application Event Log