c# 读取Windows EventLog

读取Windows EventLog

我在尝试读取用户VDI连接数据,以便统计用户的访问时长的过程中,首先发现 .evtx文件只能用Windows事件查看器不会乱码,其次发现通过System.Diagnostics.EventLog找不到VDI的log,也就没办法自动获取VDI数据,不得已:把VDI evtx文件复制到指定文件夹,程序到指定文件夹读取,此时需要用System.Diagnostics.Eventing.Reader然后压缩备份到另一个文件夹(不同的事件ID有不同的属性内容,详细的属性内容可以参考Windows事件查看器的某条Log的详细信息,如此就知道哪个属性Value是我们想要的了.
这里是:建议用Eventing.Reader读取Windows相关EventLog

通过EventLog获取日志

通过EventLog获取日志,Sample1

先展示下面的 代码片.

// 如果已经引用using System.Diagnostics,则可以直接写:EventLog[]
System.Diagnostics.EventLog[] EventLogList;
//指定電腦上的所有事件記錄檔,並建立含有清單的 EventLog 物件陣列
EventLogList= System.Diagnostics.EventLog.GetEventLogs(".");
//不管是在我个人电脑还是在VDI服务器上:EventLogList.Length都是9
Console.WriteLine("Number of logs on computer: " + EventLogList.Length);
//显示Log名称和每个Log的事件个数(Security需要管理员权限)
foreach (System.Diagnostics.EventLog log in EventLogList)
	{
	Console.WriteLine();
	Console.WriteLine("  Log name = \t {0}", log.Log);
	Console.WriteLine("  Number of event log entries = {0}", log.Entries.Count.ToString());
	// "Application"应用程序, "Security"安全, "System"系统
	//以Application为例,大同小异
	if (log.Log=="Application")
		{
			DateTime EventCreateTime;
			string EventID, EventMessage, Param1, Param2, Param3;
			foreach (EventLogEntry eventLog in log.Entries)
			{
			 EventID = eventLog.InstanceId.ToString();
			 if (EventID == "4625")
			 {
				EventMessage = eventLog.Message;
				EventCreateTime = eventLog.TimeGenerated;
				Param1 = eventLog.ReplacementStrings[0].ToString();
				Param2 = eventLog.ReplacementStrings[1].ToString();
				Param3 = eventLog.ReplacementStrings[2].ToString();
			 }
		   }
		}
	}

通过EventLog获取日志,Sample2

先展示下面的 代码片.

//"Application"应用程序, "Security"安全, "System"系统
EventLog myEventLog = new EventLog("Application");
Console.WriteLine("  Number of Eventlog = {0}", myEventLog.Entries.Count.ToString());
//
DateTime EventCreateTime;
string EventID, EventMessage, Param1, Param2, Param3;
	foreach (EventLogEntry eventLog in myEventLog.Entries)
	{
	 EventID = eventLog.InstanceId.ToString();
	 if (EventID == "4625")
	 {
		EventMessage = eventLog.Message;
		EventCreateTime = eventLog.TimeGenerated;
		Param1 = eventLog.ReplacementStrings[0].ToString();
		Param2 = eventLog.ReplacementStrings[1].ToString();
		Param3 = eventLog.ReplacementStrings[2].ToString();
	 }
   }		

Eventing.Reader读取特定路径或Log名称的完整示例

在App.config中设定参数

注意 appSettings中的内容.

<appSettings>
		<!--VDI日志目录路径-->
		<add key="VDILogPath" value="C:\EventLog\VDI"/>
		<!--VDI日志名称-->
		<add key="VDILogName" value="VDILog.evtx"/>
		<!--VDI日志备份目录路径-->
		<add key="LogBackupPath" value="C:\EventLog\Backup"/>
	</appSettings>

读取App.config中设定的参数

string VDILogPath = ConfigurationManager.AppSettings["VDILogPath"].ToString();
string VDILogName = ConfigurationManager.AppSettings["VDILogName"].ToString();
string LogBackupPath = ConfigurationManager.AppSettings["LogBackupPath"].ToString();

**注意要引用:System.Configuration.dll;**否则ConfigurationManager无效

基本代码(读取、分析、备份)

注意要引用using System.Diagnostics.Eventing.Reader

static void Main(string[] args)
{
  //读参数中的VDILog所在文件夹  
string VDILogPath = ConfigurationManager.AppSettings["VDILogPath"].ToString();
//读VDILog的名称
string VDILogName = ConfigurationManager.AppSettings["VDILogName"].ToString();
//拼接在一起
string eventLogLocation = VDILogPath + "\\" + VDILogName;
Console.WriteLine("VDI Log Path: "+ eventLogLocation );
//C:\EventLog\VDI\VDILog.evtx
//EventLogQuery后面的参数示例,一个是通过指定文件夹 一个是通过指定Log名称
EventLogQuery eventLogQuery = new EventLogQuery(eventLogLocation, PathType.FilePath);
//EventLogQuery eventLogQuery = new EventLogQuery("Application", PathType.LogName);
 try
   {
    //LogName=eventLogLocation
    EventLogReader eventlogReader = new EventLogReader(eventLogQuery);
    // Display event info
    DisplayEventAndLogInformationForVDI(eventlogReader, eventLogLocation);
   }
    catch (EventLogNotFoundException e)
     {
      Console.WriteLine("Could not Find the VDI Log to Query! " + e.Message);
       return;
     }
}
private static void DisplayEventAndLogInformationForVDI(EventLogReader logReader, string SourceLocation)
 {
  //VDI 303事件所需要的变量
  string LoginDateTime = "";
  Int32 ConnectedSecond = 0;
  string LoginDate = "";
  string LoginTime = "";
  string UserID = "";

   int Count303Type = 0;//303事件数量
   int InsertCount = 0;//成功插入DB的数量
   int TotalCount = 0;//EventLog中的事件数量

   string DBResult = "Ok";// InitDBInfo();初始化数据库省略
    if (DBResult != "Ok")
       {
          Console.WriteLine("DB Connect Fail: {0}", DBResult);
       }
    else
       {
       for (EventRecord eventInstance = logReader.ReadEvent();
            null != eventInstance; eventInstance = logReader.ReadEvent())
       {
        TotalCount++;
         Console.WriteLine("-----------------------------------------------------");
         Console.WriteLine("Event ID: {0}", eventInstance.Id);
          //Link DB For Query or Insert
         if (eventInstance.Id.ToString() == "303")
         {
          Count303Type++;
          LoginDateTime = eventInstance.TimeCreated.ToString();//2022/4/30 13:34:39
          LoginDate = Convert.ToDateTime(LoginDateTime).ToString("yyyy-MM-dd");//2022-04-30
          LoginTime = Convert.ToDateTime(LoginDateTime).ToString("HH:mm:ss");//13:32:13
          //从属性中读数据
          UserID = eventInstance.Properties[0].Value.ToString().Substring(3).ToUpper();//A0236602
          ConnectedSecond = Convert.ToInt32(eventInstance.Properties[6].Value);
         //显示在程序界面的内容
          Console.WriteLine("UserID: {0}", UserID);
          Console.WriteLine("ConnectSeconds: {0}", ConnectedSecond);
          Console.WriteLine("LoginTimeFull: {0}", LoginDateTime);
          Console.WriteLine("LoginDate: {0}", LoginDate);
          Console.WriteLine("LoginTime: {0}", LoginTime);
         //插入DB的部分...
           }
         }
        }
     Console.WriteLine("-----------------------------------------------------");
     Console.WriteLine("TotalRecord: {0}, 303Type Record:{1}, Insert OK Record:{2}", TotalCount, Count303Type, InsertCount);
    Console.WriteLine("-----------------------------------------------------");
     //参数文件中读取备份路径
     string LogFileBackupPath = ConfigurationManager.AppSettings["LogBackupPath"].ToString();
     //如果不存在就创建file文件夹
     if (Directory.Exists(LogFileBackupPath) == false)
       {
        Directory.CreateDirectory(LogFileBackupPath);
       }
       //产生一个随机数
       Random random = new Random(System.Environment.TickCount);
       int randomNumber = random.Next(1001, 9999);
      //备份文件路径和名称           
      string LogFileBackupFile = LogFileBackupPath + "\\" + DateTime.Now.ToString("yyyyMMddHHmmss")+ randomNumber + ".evtx";
     //源文件路径和名称
     string LogSourceLocation = SourceLocation;
     //移动到备份路径,不能用Move,因为文件在使用中
     File.Copy(LogSourceLocation, LogFileBackupFile);
     //如果要压缩则可以用下面的方法
      LogFileBackupFile = LogFileBackupPath + "\\" + DateTime.Now.ToString("yyyyMMddHHmmss")+ randomNumber + ".zip";
     ZipHelper.CreateZip(LogSourceLocation, LogFileBackupFile);
    //处理完毕后,窗口自动关闭
    //如果不想自动关闭,可以增加下面的两行代码
    Console.WriteLine("Press [Enter] To Exist");
    Console.ReadLine();
}

压缩Helper

也很简单,把这个加入项目即可,但需要:ICSharpCode.SharpZipLib.dll

 public class ZipHelper
    {
        /// <summary>
        /// 压缩文件
        /// </summary>
        /// <param name="sourceFilePath"></param>
        /// <param name="destinationZipFilePath"></param>
        public static void CreateZip(string sourceFilePath, string destinationZipFilePath)
        {            
            ZipOutputStream zipStream = new ZipOutputStream(File.Create(destinationZipFilePath));
            zipStream.SetLevel(6);  // 压缩级别 0-9
            CreateSingleZipFile(sourceFilePath, zipStream);
            zipStream.Finish();
            zipStream.Close();
        }
        //压缩单个文件
        private static void CreateSingleZipFile(string sourceFile, ZipOutputStream zipStream)
        {
            Crc32 crc = new Crc32();
            FileStream fileStream = File.OpenRead(sourceFile);
            byte[] buffer = new byte[fileStream.Length];
            fileStream.Read(buffer, 0, buffer.Length);
            string tempFile = sourceFile.Substring(sourceFile.LastIndexOf("\\") + 1);
            ZipEntry entry = new ZipEntry(tempFile);
            entry.DateTime = DateTime.Now;
            entry.Size = fileStream.Length;
            fileStream.Close();
            crc.Reset();
            crc.Update(buffer);
            entry.Crc = crc.Value;
            zipStream.PutNextEntry(entry);
            zipStream.Write(buffer, 0, buffer.Length);
        }
        /// <summary>
        /// 递归压缩文件
        /// </summary>
        /// <param name="sourceFilePath">待压缩的文件或文件夹路径</param>
        /// <param name="zipStream">打包结果的zip文件路径(类似 D:\WorkSpace\a.zip),全路径包括文件名和.zip扩展名</param>
        /// <param name="staticFile"></param>
        private static void CreateZipFiles(string sourceFilePath, ZipOutputStream zipStream)
        {
            Crc32 crc = new Crc32();
            string[] filesArray = Directory.GetFileSystemEntries(sourceFilePath);
            foreach (string file in filesArray)
            {
                if (Directory.Exists(file))                     //如果当前是文件夹,递归
                {
                    CreateZipFiles(file, zipStream);
                }
                else                                            //如果是文件,开始压缩
                {
                    FileStream fileStream = File.OpenRead(file);
                    byte[] buffer = new byte[fileStream.Length];
                    fileStream.Read(buffer, 0, buffer.Length);
                    string tempFile = file.Substring(sourceFilePath.LastIndexOf("\\") + 1);
                    ZipEntry entry = new ZipEntry(tempFile);
                    entry.DateTime = DateTime.Now;
                    entry.Size = fileStream.Length;
                    fileStream.Close();
                    crc.Reset();
                    crc.Update(buffer);
                    entry.Crc = crc.Value;
                    zipStream.PutNextEntry(entry);
                    zipStream.Write(buffer, 0, buffer.Length);
                }
            }
        }
    }
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值