خدمة ويندوز. البحث عن أخطاء النظام وعرضها في WinForm C #

في هذه المقالة ، سنبحث في كيفية إنشاء تطبيق من البداية يعمل مع خدمات Windows وعرض أخطاء النظام في WinForm (C #).

الخطوط العريضة لهذا المقال:

  • إنشاء الخدمة
  • عارض الأحداث
  • كود الخدمة
  • التحقق من الخدمة (بدء تشغيل الخدمة يدويًا)
  • رسم خرائط WinForm

إنشاء الخدمة


افتح Visual Studio. الملف التالي ← جديد ← مشروع ← (سطح مكتب Windows) ← خدمة Windows (.Net Framework) ← موافق.

القادمة تحتاج إلى إنشاء المثبت. في النافذة التي تفتح ، انقر فوق RMB وحدد "Add Installer". سيتم إنشاء "ProjectInstaller.cs [Design]" ، وبعد ذلك ستحتاج إلى الانتقال إلى رمز "F7" أو "عرض رمز" RMB. تحتاج إلى العثور على السطر "InitializeComponent () ؛" ، ضع المؤشر عليه واضغط على "F12" ، ثم تحتاج إلى إضافة الأسطر التالية:

this.serviceProcessInstaller1.Account = System.ServiceProcess.ServiceAccount.LocalSystem; //       this.serviceInstaller1.Description = "Show me system error."; //       this.serviceInstaller1.DisplayName = "GetSystemError"; //        

لكنك تحتاج إلى إضافة هذه السطور فقط في التسلسل والمكان التاليين. خلاف ذلك ، سيكون هناك خطأ عند تثبيت الخدمة.



عارض الأحداث


هذا ضروري للتحقق من التشغيل الصحيح لبرنامجنا.

Event Viewer - برنامج لعرض سجل الأحداث الموجود على كل جهاز كمبيوتر مزود بنوافذ. ينشر كل برنامج يتم تشغيله على جهاز الكمبيوتر إشعارًا في سجل الأحداث قبل أن يتوقف. أي وصول إلى النظام ، وتغييرات الأمان ، وضبط نظام التشغيل ، وتعطل الأجهزة وفشل برنامج التشغيل - كل هذا يدخل في سجل الأحداث. يقوم "عارض الأحداث" بفحص ملفات السجل النصي ، والجمع بينها ووضعها في الواجهة.

كيفية فتحه؟ - ابدأ → عارض الأحداث (قيد البحث) → "عرض سجلات الأحداث".

بعد ذلك ، "طرق عرض مخصصة" → "أحداث إدارية". هنا يمكننا أن نرى كل الأخطاء والتحذيرات والمعلومات المتعلقة بها.

هناك 3 أنواع من السجلات: التطبيق (التطبيق) ، النظام (النظام) والأمان (الأمان). نحن بحاجة فقط إلى نظام (النظام).

كود الخدمة


نجد ملف .cs باسم الخدمة ، لدي "Service1.cs" ، افتحه. يجب أن يحتوي الملف على طريقتين تم تجاوزهما:

  • OnStart (string [] args) - يتم تنفيذها عند بدء تشغيل الخدمة ،
  • OnStop () - يتم تنفيذه عند إيقاف الخدمة.

هناك أيضًا بعض الطرق الأخرى ، لكننا لسنا بحاجة إليها الآن. يمكنك العثور عليها بنفسك.

سيتم تخزين البيانات التي نحصل عليها في ملف نصي محدث ، لذلك نضيف

 using System.IO; 

أضف التعليمات البرمجية إلى أسلوب OnStart (سلسلة [] وسيطات):

 EventLog myLog; //       string filepath = AppDomain.CurrentDomain.BaseDirectory + @"\ServiceLog.txt";; //    List<string> list; //    protected override void OnStart(string[] args) { myLog = new EventLog(); myLog.Log = "System"; //     - (Application),    (System). myLog.Source = "System Error"; for (int index = myLog.Entries.Count - 1; index > 0; index--) //         { var errEntry = myLog.Entries[index]; \\     if (errEntry.EntryType == EventLogEntryType.Error) \\    { //     var appName = errEntry.Source; list = new List<string>(); list.Add("Entry Type: " + Convert.ToString(errEntry.EntryType)); list.Add("Event log: " + (string)myLog.Log); list.Add("Machine Name: " + (string)errEntry.MachineName); list.Add("App Name: " + (string)errEntry.Source); list.Add("Message: " + (string)errEntry.Message); list.Add("Time Written: " + errEntry.TimeWritten.ToString()); list.Add("-*-"); WriteToFile(list); //    } } } public void WriteToFile(List<string> list) //   { using (StreamWriter sw = File.AppendText(filepath)) { for (int i = 0; i < list.Count; i++) sw.WriteLine(list[i]); } } 

بعد ذلك ، تحتاج إلى جمع حل "الحل" -> "إعادة بناء الحل". بعد التجميع الناجح ، يمكنك التحقق من العملية.

التحقق من الخدمة (بدء تشغيل الخدمة يدويًا)


لا يمكن بدء تشغيل خدمة windows كتطبيق منتظم. يمكنك فقط تشغيل سطر الأوامر كمسؤول.

قم بتشغيل سطر الأوامر كمسؤول. أدخل الأوامر التالية:

 cd C:\Windows\Microsoft.NET\Framework\v4.0.30319 InstallUtil.exe \  .exe (InstallUtil.exe C:\Users\\source\repos\WindowsService1\WindowsService1 \bin\Debug\WindowsService1.exe)    : InstallUtil.exe -u \  .exe 

بعد ذلك ، اضغط على مفتاح Win + R. أدخل "Services.msc". نجد خدمتنا في القائمة ، انقر فوقها ، وانقر فوق "ابدأ". بعد بدء التشغيل بنجاح ، سيتم إنشاء ملف على المسار المحدد في الكود الذي سيتم تحديد قائمة أخطاء النظام به.
لا تنسَ حذف الخدمة بعد التحقق.

رسم خرائط WinForm


لعرضه في وحدة التحكم ، إذا حاولت ، يمكنك العثور على مقالات ، لكنني لم أجدها لعرضها في WinForm ، لذلك هنا. افتراضيًا ، يتم إنشاء مشروع خدمة من النوع Application. لعرضها من خلال وحدة التحكم ، يجب تغيير هذه المعلمة في الإعدادات ، حتى يتركها WinForm كما هي. بعد ذلك تحتاج إلى إضافة النموذج إلى المشروع. "WindowsService1" ← RMB ← إضافة ← نموذج Windows ← إضافة. والقيام بالتصميم التالي. بعد ذلك ، قم بتغيير الملف "Program.cs".

إضافة باستخدام:

 using System.Windows.Forms; using System.Security.Principal; using System.ComponentModel; using System.Diagnostics; 

وتغيير الطريقة الرئيسية:

 static void Main(string[] args) { WindowsPrincipal windowsPricipal = new WindowsPrincipal(WindowsIdentity.GetCurrent()); bool hasAdministrativeRight = windowsPricipal.IsInRole(WindowsBuiltInRole.Administrator); if (hasAdministrativeRight == false) //    { ProcessStartInfo processInfo = new ProcessStartInfo(); //   processInfo.Verb = "runas"; //       processInfo.FileName = Application.ExecutablePath; try { Process.Start(processInfo); //   } catch (Win32Exception){} Application.Exit(); } else { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Form1(args)); //  } } 

أضف فئة جديدة "SystemError". ("WindowsService1" -> يوان -> إضافة -> فئة -> إضافة). هنا سنقوم بتخزين بيانات الخطأ. غيره:

 public string EntryType{ get; set; } public string EventLog{ get; set; } public string MachineName { get; set; } public string AppName { get; set; } public string Message { get; set; } public string TimeWritten { get; set; } 

كذلك في "Service1.cs" نضيف طريقة "RunFromForm (string [] args)" التي تبدأ الخدمة.

 public void RunFromForm(string[] args) { OnStart(args); OnStop(); } 

أضف فئة جديدة "GetListErrors". ("WindowsService1" -> يوان -> إضافة -> فئة -> إضافة). هنا سنحصل على البيانات من الملف. إضافة باستخدام:

 using System.IO; 

غيره:

 string filepath = AppDomain.CurrentDomain.BaseDirectory + @"\ServiceLog.txt"; SystemError systemError; public List<SystemError> listSysErrs; public void ReadFile() //          { systemError = new SystemError(); listSysErrs = new List<SystemError>(); using (StreamReader sr = new StreamReader(filepath)) { string line; while ((line = sr.ReadLine()) != null) { if (line.Contains("-*-")) { listSysErrs.Add(systemError); systemError = new SystemError(); //       } if (line.Contains("Entry Type")) { systemError.EntryType = line.Substring(12); } else if (line.Contains("Event log")) { systemError.EventLog = line.Substring(11); } else if (line.Contains("Machine Name")) { systemError.MachineName = line.Substring(14); } else if (line.Contains("App Name")) { systemError.AppName = line.Substring(10); } else if (line.Contains("Message")) { systemError.Message = line.Substring(9); } else if (line.Contains("Time Written")) { systemError.TimeWritten = line.Substring(14); } } } } 

بعد ذلك ، قم بتغيير رمز النموذج "Form1.cs". إضافة باستخدام:

 using System.ServiceProcess; using System.Diagnostics; 

غيره:

 Service1 service = new Service1(); List<SystemError> listSysErrs; string[] args; public Form1(string[] args) { InitializeComponent(); this.args = args; if (Environment.UserInteractive)//          { service.RunFromForm(args); //  GetListErrors getListErrors = new GetListErrors(); getListErrors.ReadFile(); //      listSysErrs = getListErrors.listSysErrs; FillDataGridView(); //    } else { ServiceBase[] ServicesToRun; ServicesToRun = new ServiceBase[] { service }; ServiceBase.Run(ServicesToRun); } } public void FillDataGridView() //     { foreach (SystemError item in listSysErrs) { dataGridView1.Rows.Add(item.AppName, item.Message); } } private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e) //                { SystemError sys = listSysErrs[dataGridView1.CurrentRow.Index]; label1.Text = "Entry Type: " + sys.EntryType + "\nEvent log: " + sys.EventLog + "\nMachine Name: " + sys.MachineName + "\nApp Name: " + sys.AppName + "\n\nMessage: " + FormatMessage(sys.Message) + "\n\nTime Written: " + sys.TimeWritten; } private string FormatMessage(string msg) //       ,                 { string retMsg = ""; int count = 75; if (msg.Length > count - 9) { retMsg += msg.Substring(0, count - 9) + "\n"; msg = msg.Substring(count - 9); } while (msg.Length > count) { retMsg += msg.Substring(0, count) + "\n"; msg = msg.Substring(count); } retMsg += msg + "\n"; return retMsg; } private void button1_Click(object sender, EventArgs e) //          { if (Environment.UserInteractive) { while (dataGridView1.Rows.Count != 0) { dataGridView1.Rows.Remove(dataGridView1.Rows[dataGridView1.Rows.Count - 1]); } service.RunFromForm(args); GetListErrors getListErrors = new GetListErrors(); getListErrors.ReedFile(); listSysErrs = getListErrors.listSysErrs; FillDataGridView(); } else { ServiceBase[] ServicesToRun; ServicesToRun = new ServiceBase[] { service }; ServiceBase.Run(ServicesToRun); } } private void button2_Click(object sender, EventArgs e) { Process.Start(AppDomain.CurrentDomain.BaseDirectory); //  } 

الآن يمكنك بدء الخدمة كتطبيق منتظم. والنتيجة هي كما يلي:

Source: https://habr.com/ru/post/ar452688/


All Articles