如何使用 Microsoft.Diagnostics.Tracing 将事件写入子文件夹

问题描述

我想写入系统事件日志,位于“应用程序和服务日志”下的子文件夹中。我曾尝试手动创建注册表项(请参阅 here),但这似乎不起作用。我试图找出如何正确创建这些键,这导致了“Microsoft.Diagnostics.Tracing”nuget 包。我已经创建了演示应用程序,并使用 wevtutil 注册了清单。

注册后,我查看事件查看器,看到这个:

enter image description here

为什么“Operational”节点不只是称为“Operational”(和其他节点一样)? 如果我右键单击“示例”并选择“刷新”,“EventSourceDemos”下面的所有内容都会消失。如果我重新启动事件查看器,它就会回来。

我已经运行了示例代码,但没有看到任何记录(来自事件查看器)。我添加一个带有通道调试的事件。此日志有时会出现在事件查看器中 - 但并非总是如此。在清单中,它说没有启用带有“调试”chid 的通道。为什么 - 当“操作”启用时?我已经重新运行了 wevtutil - 每次构建都必须这样做吗?

某处是否有完整的示例?有没有更简单的方法来写入这些子文件夹日志?

我的代码

using Microsoft.Diagnostics.Tracing;

namespace ConsoleApp11
{
    class Program
    {
        static void Main(string[] args)
        {
            var listener = new CustomEventListener();
            listener.EnableEvents(MyEventSource.Log,EventLevel.Verbose);

            MyEventSource.Log.Load(1234,"hello");
            MyEventSource.Log.DoStuff("hello world");

            var options = new EventSourceOptions { Level = EventLevel.Error };
            MyEventSource.Log.Write("Failed !",options);
        }
    }

    [EventSource(Name = "Samples-EventSourceDemos-EventLog")]
    public sealed class MyEventSource : EventSource
    {
        public static MyEventSource Log = new MyEventSource();

        [Event(1,Message = "{0} -> {1}",Channel = EventChannel.Operational)]
        public void Load(long baseAddress,string imageName)
        {
            WriteEvent(1,baseAddress,imageName);
        }

        [Event(2,Message = "{0}",Channel = EventChannel.Debug)]
        public void DoStuff(string message)
        {
            WriteEvent(2,message);
        }
    }

    public class CustomEventListener : EventListener
    {
        protected override void OnEventWritten(EventWrittenEventArgs eventData)
        {
        }
    }
}

编辑:手动创建注册表项:

static public void Create(string companyName,string applicationName,string functionName,string logName,Guid publisher)
{
    var publisherGuid = $"{{{publisher}}}";
    var publisherLocation = @"SOFTWARE\Microsoft\Windows\CurrentVersion\WINEVT\Publishers";
    var primaryLocation = @"SOFTWARE\Microsoft\Windows\CurrentVersion\WINEVT\Channels";
    var secondaryLocation = @"SYstem\CurrentControlSet\Services\EventLog\Application";

    var primaryLogName = $@"{companyName}-{applicationName}-{functionName}/{logName}";
    var secondaryLogName = $"{companyName}-{applicationName}-{functionName}";
    var publisherName = $"{companyName}-{applicationName}";

    var primaryEventRoot = $@"{primaryLocation}\{primaryLogName}";
    var secondaryEventRoot = $@"{secondaryLocation}\{secondaryLogName}";
    var publisherEventRoot = $@"{publisherLocation}\{publisherGuid}";

    var evtxFilePath = $@"%systemRoot%\System32\Winevt\Logs\{secondaryLogName}\{logName}.evtx";

    if (!Registry.LocalMachine.Exists(primaryEventRoot))
    {
        using (var primaryKey = Registry.LocalMachine.CreateSubKey(primaryEventRoot))
        {
            primaryKey.SetValue("Enabled",1,RegistryValueKind.DWord);
            primaryKey.SetValue("Type",RegistryValueKind.DWord);
            primaryKey.SetValue("Isolation",RegistryValueKind.DWord);
            primaryKey.SetValue("RestrictGuestAccess","1",RegistryValueKind.String);
            primaryKey.SetValue("OwningPublisher",publisherGuid,RegistryValueKind.String);
        }
    }

    if (!Registry.LocalMachine.Exists(secondaryEventRoot))
    {
        using (var secondaryKey = Registry.LocalMachine.CreateSubKey(secondaryEventRoot))
        {
            secondaryKey.SetValue("ProviderGuid",RegistryValueKind.String);
            secondaryKey.SetValue("File",evtxFilePath,RegistryValueKind.String);
        }
    }

    if (!Registry.LocalMachine.Exists(publisherEventRoot))
    {
        using (var publisherKey = Registry.LocalMachine.CreateSubKey(publisherEventRoot))
        {
            publisherKey.SetValue("",publisherName,RegistryValueKind.String);
            publisherKey.SetValue("Enabled",RegistryValueKind.DWord);

            using (var channelReference = publisherKey.CreateSubKey("ChannelReferences"))
            {
                channelReference.SetValue("Count",RegistryValueKind.DWord);

                using (var reference0 = channelReference.CreateSubKey("0"))
                {
                    reference0.SetValue("Flags",RegistryValueKind.DWord);
                    reference0.SetValue("Id",16,RegistryValueKind.DWord);
                }
            }
        }
    }
}

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)