c# TraceEventSession 监控应用程序的启动与退出

|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||

上一篇提到了 Process 与 [WMI] ManagementEventWatcher 的相关监控及源码,今天简单使用 TraceEventSession 来做同样的事情。

上篇:https://blog.csdn.net/qq_33538554/article/details/96433844

本人比较赖,不太喜欢打字,所以就简单说下怎么用,然后上代码,其他的自己研究,或者留言。

主要实现的就是监控各种应用程序的启动与退出。

1.首先新建一个 c#  控制台程序(用来可视化监控结果)

   新建的项目中,安装 NuGet 程序包:Microsoft.Diagnostics.Tracing.TraceEvent

2.接着新建两个类:MonEventSource.cs :主要处理监控的逻辑,MonitorTrigger.cs:枚举类,定义或者区分回调事件。

 ① MonEventSource.cs  Code

using Microsoft.Diagnostics.Tracing.Parsers;
using Microsoft.Diagnostics.Tracing.Parsers.Kernel;
using Microsoft.Diagnostics.Tracing.Session;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;

namespace MonitoringProcessConsole
{
    internal class MonEventSource : IDisposable
    {
        private static readonly Lazy<MonEventSource> InstanceLazy = new Lazy<MonEventSource>(() => new MonEventSource());
        public static MonEventSource Instance => InstanceLazy.Value;

        private  List<App> appList;

        public  List<App> AppList
        {
            get
            {
                if (appList == null)
                {
                    appList = new List<App>
                    {
                        new App { ProcessName = "TeamViewer", CurrentState = false  },
                        new App { ProcessName = "wmplayer", CurrentState = false  },
                    };

                }
                return appList;
            }
            set
            {
                appList = value;
            }
        }
        
        private readonly TraceEventSession _session = new TraceEventSession("TestEventSession", null);
        private readonly Thread _traceThread;
        private MonEventSource()
        {
            try
            {
                _session.StopOnDispose = true;
                _session.EnableKernelProvider(KernelTraceEventParser.Keywords.Process);
                _session.Source.Kernel.ProcessStart += data => FireAppProcMonEvent(data, MonitorTrigger.Launch);
                _session.Source.Kernel.ProcessStop += data => FireAppProcMonEvent(data, MonitorTrigger.Exit);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
            _traceThread = new Thread(() => _session.Source.Process())
            {
                IsBackground = true,
                Name = "TestProcess"
            };
        }

        private void FireAppProcMonEvent(ProcessTraceData data, MonitorTrigger trigger)
        {
            try
            {
                uint processId = (uint)data.ProcessID;
                string processName = data.ProcessName;

                if (trigger == MonitorTrigger.Launch)
                {
                    Console.WriteLine("Launch------" + "processId:" + processId + "-------processName:" + processName + "-------Count:" + AppList.Where(x => x.CurrentState == true).ToList().Count);
                    App app = AppList?.Where(x => x.ProcessName.ToLower() == processName.ToLower() && x.CurrentState == false)?.LastOrDefault();
                    if (app != null)
                    {
                        app.ProcessId = processId;
                        app.CurrentState = true;
                        Console.ForegroundColor = ConsoleColor.Green;
                        Console.WriteLine("Launch------" + "processId:" + processId + "-------processName:" + processName + "-------Count:" + AppList.Where(x => x.CurrentState == true).ToList().Count);
                        Console.ForegroundColor = ConsoleColor.White;
                    }  
                }

                if (trigger == MonitorTrigger.Exit)
                {
                    Console.WriteLine("Exit-------" + "processId:" + processId + "-------processName:" + processName + "-------Count:" + AppList.Where(x=>x.CurrentState == true).ToList().Count);
                    App app = AppList?.Where(x => x.ProcessId == processId && x.CurrentState == true)?.LastOrDefault();
                    if (app != null)
                    {
                        app.CurrentState = false;
                        Console.ForegroundColor = ConsoleColor.Green;
                        Console.WriteLine("Exit-------" + "processId:" + processId + "-------processName:" + app.ProcessName + "-------Count:" + AppList.Where(x => x.CurrentState == true).ToList().Count);
                        Console.ForegroundColor = ConsoleColor.White;
                    }
                }
            }
            catch (Exception e)
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine(e.ToString());
                Console.ForegroundColor = ConsoleColor.White;
            }
        }
        public void Dispose()
        {
            try
            {
                _session.Dispose();
            }
            catch (Exception e)
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine(e.ToString());
                Console.ForegroundColor = ConsoleColor.White;
            }
        }

        public void Start()
        {
            try
            {
                _traceThread.Start();
            }
            catch (Exception e)
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine(e.ToString());
                Console.ForegroundColor = ConsoleColor.White;
            }
        }

        public void Stop()
        {
            try
            {
                _session.Stop(true);
            }
            catch (Exception e)
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine(e.ToString());
                Console.ForegroundColor = ConsoleColor.White;
            }
        }
    }

    public class App {
        public uint ProcessId { get; set; }
        public string ProcessName { get; set; }
        public bool CurrentState { get; set; }
    }
}

 ② MonitorTrigger.cs Code

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MonitoringProcessConsole
{
    public enum MonitorTrigger
    {
        Launch = 0,
        Exit = 1
    }
}

3. 接着在 Program.cs 的Main 函数中,调用监控函数。

    ① Program.cs   Code

using System;

namespace MonitoringProcessConsole
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.ForegroundColor = ConsoleColor.Yellow;
            Console.WriteLine($"Please input:(y/n) [y: Start Monitoring n: Stop Monitoring]");
            Console.ForegroundColor = ConsoleColor.White;
            while (true)
            {
                string input = Console.ReadLine().ToLower();
                if (input == "n")
                {
                    MonEventSource.Instance.Stop();
                    Console.ForegroundColor = ConsoleColor.White;
                    Console.WriteLine($"------------------------------------------------------------");
                    Console.WriteLine($"Welcome to use, the program is exiting!");
                    Environment.Exit(0);
                }
                else if (input == "y")
                {
                    MonEventSource.Instance.Start();
                }
                else
                {
                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.WriteLine($"Wrong input!Please input :(y/n) [y: Start Monitoring n: Stop Monitoring]");
                    Console.ForegroundColor = ConsoleColor.White;
                }
            }
        }
    }
}

 

注意:必须以管理员权限运行;代码中的 AppList 是所要监控的应用程序名称。

           此代码未经过优化,或者逻辑上的纰漏处理,不喜勿喷,谢谢!

最后附上截图:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值