Service Windows. Recherchez les erreurs système et affichez-les dans WinForm C #

Dans cet article, nous verrons comment créer une application à partir de zéro qui fonctionnera avec les services Windows et affichera les erreurs système dans WinForm (C #).

Le plan de cet article:

  • CrĂ©ation de service
  • Observateur d'Ă©vĂ©nements
  • Code de service
  • VĂ©rification du service (dĂ©marrage manuel du service)
  • Mappage WinForm

Création de service


Ouvrez Visual Studio. Fichier suivant → Nouveau → Projet → (Bureau Windows) → Service Windows (.Net Framework) → Ok.

Vous devez ensuite créer un programme d'installation. Dans la fenêtre qui s'ouvre, cliquez sur RMB et sélectionnez "Ajouter un programme d'installation". Vous aurez «ProjectInstaller.cs [Design]» créé, après quoi vous devrez aller au code «F7» ou RMB «View Code». Vous devez trouver la ligne "InitializeComponent ();", placez le curseur dessus et appuyez sur "F12", puis vous devez ajouter les lignes suivantes:

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

Mais vous devez ajouter ces lignes uniquement dans la séquence et le lieu suivants. Sinon, il y aura une erreur lors de l'installation du service.



Observateur d'événements


Ceci est nécessaire pour vérifier le bon fonctionnement de notre programme.

Observateur d'événements - un programme pour afficher le journal des événements qui se trouve sur chaque ordinateur doté de Windows. Chaque programme qui s'exécute sur un ordinateur publie une notification dans le journal des événements avant de s'arrêter. Tout accès au système, modifications de sécurité, réglage du système d'exploitation, défaillance matérielle et défaillance du pilote - tout cela entre dans le journal des événements. L'Observateur d'événements analyse les fichiers journaux de texte, les combine et les place dans l'interface.

Comment l'ouvrir? - Démarrer → Observateur d'événements (en recherche) → «Afficher les journaux d'événements».

Ensuite, «Vues personnalisées» → «Événements administratifs». Ici, nous pouvons voir toutes les erreurs, avertissements et informations les concernant.

Il existe 3 types de journaux: Application (Application), System (System) et Security (Security). Nous avons seulement besoin d'un système (System).

Code de service


Nous trouvons le fichier .cs avec le nom du service, je l'ai "Service1.cs", ouvrez-le. Le fichier doit avoir 2 méthodes remplacées:

  • OnStart (string [] args) - exĂ©cutĂ© au dĂ©marrage du service,
  • OnStop () - exĂ©cutĂ© lorsque le service est arrĂŞtĂ©.

Il existe également quelques autres méthodes, mais nous n'en avons pas besoin maintenant. Vous pouvez les trouver vous-même.

Les données que nous obtenons seront stockées dans un fichier texte mis à jour, nous ajoutons donc

 using System.IO; 

Ajoutez le code à la méthode OnStart (chaîne [] arguments):

 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]); } } 

Ensuite, vous devez collecter la solution "Solution" -> "Rebuild Solution". Une fois l'assemblage réussi, vous pouvez vérifier le fonctionnement.

Vérification du service (démarrage manuel du service)


Le service Windows ne peut pas être démarré en tant qu'application régulière. Vous pouvez uniquement exécuter la ligne de commande en tant qu'administrateur.

Exécutez la ligne de commande en tant qu'administrateur. Entrez les commandes suivantes:

 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 

Ensuite, appuyez sur la touche Win + R. Entrez "Services.msc". Nous trouvons notre service dans la liste, cliquez dessus et cliquez sur «Démarrer». Après un lancement réussi, un fichier sera généré sur le chemin spécifié dans le code dans lequel se trouvera la liste des erreurs système.
N'oubliez pas de supprimer le service après vérification.

Mappage WinForm


Pour afficher dans la console, si vous essayez, vous pouvez trouver des articles, mais je ne l'ai pas trouvé à afficher dans WinForm, alors le voici. Par défaut, un projet de service est créé de type Application. Pour afficher via la console, ce paramètre doit être modifié dans les paramètres, pour que WinForm le laisse tel quel. Ensuite, vous devez ajouter le formulaire au projet. «WindowsService1» → RMB → Ajouter → Windows Form → Ajouter. Et faites la conception suivante. Ensuite, modifiez le fichier "Program.cs".

Ajoutez en utilisant:

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

Et changez la méthode Main:

 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)); //  } } 

Ajoutez une nouvelle classe "SystemError". ("WindowsService1" -> RMB -> Ajouter -> Classe -> Ajouter). Ici, nous stockons les données d'erreur. Changez-le:

 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; } 

Plus loin dans "Service1.cs" nous ajoutons la méthode "RunFromForm (string [] args)" qui démarre le service.

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

Ajoutez une nouvelle classe "GetListErrors". ("WindowsService1" -> RMB -> Ajouter -> Classe -> Ajouter). Ici, nous obtiendrons les données du fichier. Ajoutez en utilisant:

 using System.IO; 

Changez-le:

 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); } } } } 

Ensuite, modifiez le code du formulaire "Form1.cs". Ajoutez en utilisant:

 using System.ServiceProcess; using System.Diagnostics; 

Changez-le:

 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); //  } 

Vous pouvez maintenant démarrer le service en tant qu'application régulière. Le résultat est le suivant:

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


All Articles