Serviço do Windows. Procure por erros do sistema e exiba-os no WinForm C #

Neste artigo, veremos como criar um aplicativo do zero que funcione com os serviços do Windows e exibirá erros do sistema no WinForm (C #).

O esboço deste artigo:

  • Criação de Serviço
  • Visualizador de eventos
  • Código de serviço
  • Verificando o serviço (Iniciando o serviço manualmente)
  • Mapeamento do WinForm

Criação de Serviço


Abra o Visual Studio. Próximo arquivo → Novo → Projeto → (Área de trabalho do Windows) → Serviço do Windows (.Net Framework) → Ok.

Em seguida, você precisa criar um instalador. Na janela que se abre, clique em RMB e selecione "Adicionar instalador". Você terá o “ProjectInstaller.cs [Design]” criado, após o qual precisará acessar o código “F7” ou o “View Code” do RMB. Você precisa encontrar a linha “InitializeComponent ();”, colocar o cursor sobre ela e pressionar “F12”, depois você precisa adicionar as seguintes linhas:

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

Mas você precisa adicionar essas linhas apenas na seguinte sequência e local. Caso contrário, haverá um erro ao instalar o serviço.



Visualizador de eventos


Isso é necessário para verificar o funcionamento correto do nosso programa.

Visualizador de Eventos - um programa para visualizar o log de eventos que está em todos os computadores com janelas. Cada programa executado em um computador publica uma notificação no log de eventos antes de parar. Qualquer acesso ao sistema, alterações de segurança, ajuste do sistema operacional, falha de hardware e driver - tudo isso entra no log de eventos. O Visualizador de Eventos verifica os arquivos de log de texto, combina-os e os coloca na interface.

Como abrir? - Iniciar → Visualizador de eventos (na pesquisa) → “Visualizar logs de eventos”.

Em seguida, “Visualizações personalizadas” → “Eventos administrativos”. Aqui podemos ver todos os erros, avisos e informações sobre eles.

Existem 3 tipos de logs: Aplicativo (Aplicativo), Sistema (Sistema) e Segurança (Segurança). Nós precisamos apenas de um sistema (System).

Código de serviço


Nós encontramos o arquivo .cs com o nome do serviço, eu tenho "Service1.cs", abri-lo. O arquivo deve ter 2 métodos substituídos:

  • OnStart (string [] args) - executado quando o serviço é iniciado,
  • OnStop () - executado quando o serviço é parado.

Também existem vários outros métodos, mas não precisamos deles agora. Você pode encontrá-los você mesmo.

Os dados que obtivermos serão armazenados em um arquivo de texto atualizado; portanto, adicionamos

 using System.IO; 

Adicione o código ao método OnStart (string [] args):

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

Em seguida, você precisa coletar a solução "Solution" -> "Rebuild Solution". Após a montagem bem-sucedida, você pode verificar a operação.

Verificando o serviço (Iniciando o serviço manualmente)


O serviço do Windows não pode ser iniciado como um aplicativo regular. Você só pode executar a linha de comando como administrador.

Execute a linha de comando como administrador. Digite os seguintes comandos:

 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 

Em seguida, pressione a tecla Win + R. Digite "Services.msc". Encontramos nosso serviço na lista, clique nele e clique em "Iniciar". Após uma inicialização bem-sucedida, um arquivo será gerado no caminho especificado no código em que a lista de erros do sistema será localizada.
Não se esqueça de excluir o serviço após a verificação.

Mapeamento do WinForm


Para exibir no console, se você tentar, poderá encontrar artigos, mas não o encontrei no WinForm, então aqui. Por padrão, um projeto de serviço é criado do tipo Aplicativo. Para exibir no console, esse parâmetro deve ser alterado nas configurações, para que o WinForm o deixe como está. Em seguida, você precisa adicionar o formulário ao projeto. “WindowsService1” → RMB → Adicionar → Windows Form → Adicionar. E faça o seguinte design. Em seguida, altere o arquivo "Program.cs".

Adicione usando:

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

E mude o método 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)); //  } } 

Adicione uma nova classe "SystemError". ("WindowsService1" -> RMB -> Adicionar -> Classe -> Adicionar). Aqui vamos armazenar dados de erro. Mude:

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

Além disso, em "Service1.cs", adicionamos o método "RunFromForm (string [] args)" que inicia o serviço.

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

Adicione uma nova classe "GetListErrors". ("WindowsService1" -> RMB -> Adicionar -> Classe -> Adicionar). Aqui obteremos os dados do arquivo. Adicione usando:

 using System.IO; 

Mude:

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

Em seguida, altere o código do formulário "Form1.cs". Adicione usando:

 using System.ServiceProcess; using System.Diagnostics; 

Mude:

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

Agora você pode iniciar o serviço como um aplicativo regular. O resultado é o seguinte:

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


All Articles