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 是所要監控的應用程序名稱。

           此代碼未經過優化,或者邏輯上的紕漏處理,不喜勿噴,謝謝!

最後附上截圖:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章