C# - Parando, Iniciando e Reiniciando os serviços do Windows - III
O artigo de hoje vamos recordar como tratar com os serviços do Windows em uma aplicação C# mostrando como parar, iniciar e reiniciar serviços do Windows. |
Na primeira parte do artigo eu mostrei como exibir todos os serviços do Windows e na segunda parte como listar os processos ativos em execução.
Para concluir esta série de artigo vamos mostrar como parar, iniciar e reiniciar serviços do Windows.
Implementar o código para realizar essa tarefa não é muito complexo, mas realizar a tarefa em si é outra história, pois o usuário deverá ter direitos de administrador do sistema para isso.
Então se você testar o código e obter a mensagem de acesso negado é por que você não tem direito de administrador.
Para entender
como isso funciona saiba que a conta IUSER_MachineName (IUSER daqui em
diante) é, por boas razões, uma conta relativamente limitada, com privilégios
apenas acima da conta de convidado. Assim essa conta não tem permissão para
iniciar e parar serviços do Windows, ou mesmo para interrogá-los (para obter
seu status etc.).
Quando executado no contexto de um exe autônomo, a lógica acima é
bem-sucedida porque a conta subjacente é com certeza um membro do
grupo Administradores.
A maneira mais fácil, mas não recomendada, para sair desta situação, é dar à
conta IUSER mais privilégios tentando adicionar esta conta ao grupo de
administradores. Isso vai funcionar (mas também vai lançar alguns falha de
segurança potencialmente perigoso).
Uma abordagem melhor é fazer um lista explícita dos serviços específicos do
Windows que serão autorizados por meio do IIS, e definir o seu descritor de
segurança de serviço individual de modo que a conta IUSER (ou outra
conta/grupo criado para a ocasião) seja autorizada a iniciar e/ou parar os
serviços como desejado.
A dificuldade na implementação desta abordagem é que, pelo menos que eu saiba,
não há nenhuma GUI ou ferramenta intuitiva de administração para inspecionar e
modificar o descritor de segurança dos serviços: você precisa usar sd e
"aprender" a linguagem SDDL.
Recursos usados :
Incluindo um novo projeto na solução
Abra a solução Tratando_Servicos, criada no VS 2013 Express for Windows desktop, no primeiro artigo anterior.
A seguir clique em FILE -> Add -> New Project;
Selecione o template Visual C# -> Class Library;
Informe o nome ServicosWin e clique no botão OK;
Renomeie a classe Class1.cs criada por padrão para ServicosWin.cs e a seguir inclua nesta classe o código abaixo:
using System;
using System.ServiceProcess;
namespace ServicosWin
{
public class ServicosWin
{
public static void StartService(string serviceName, int timeoutMilliseconds = 10000)
{
ServiceController service = new ServiceController(serviceName);
try
{
TimeSpan timeout = TimeSpan.FromMilliseconds(timeoutMilliseconds);
service.Refresh();
if (service.Status == ServiceControllerStatus.Stopped)
{
service.Start();
service.WaitForStatus(ServiceControllerStatus.Running, timeout);
}
else
{
throw new Exception(string.Format("{0} --> já esta iniciado.", service.DisplayName));
}
}
catch
{
throw;
}
}
public static void StopService(string serviceName, int timeoutMilliseconds = 10000)
{
ServiceController service = new ServiceController(serviceName);
try
{
TimeSpan timeout = TimeSpan.FromMilliseconds(timeoutMilliseconds);
service.Refresh();
if (service.Status == ServiceControllerStatus.Running)
{
service.Stop();
service.WaitForStatus(ServiceControllerStatus.Stopped, timeout);
}
else
{
throw new Exception(string.Format("{0} --> já esta parado.", service.DisplayName));
}
}
catch
{
throw;
}
}
public static void RestartService(string serviceName, int timeoutMilliseconds=10000)
{
ServiceController service = new ServiceController(serviceName);
try
{
int millisec1 = Environment.TickCount;
TimeSpan timeout = TimeSpan.FromMilliseconds(timeoutMilliseconds);
service.Refresh();
if (service.Status != ServiceControllerStatus.Stopped)
{
service.Stop();
service.WaitForStatus(ServiceControllerStatus.Stopped, timeout);
// conta o resto do timeout
int millisec2 = Environment.TickCount;
timeout = TimeSpan.FromMilliseconds(timeoutMilliseconds - (millisec2 - millisec1));
service.Start();
service.WaitForStatus(ServiceControllerStatus.Running, timeout);
}
else
{
service.Start();
throw new Exception(string.Format("{0} --> foi parado e a seguir iniciado", service.DisplayName));
}
}
catch
{
throw;
}
}
}
}
|
Esta classe possui 3 métodos estáticos que recebem como parâmetro o nome do serviço e o tempo em milisegundos para timeout (esse parâmetro é opcional e possui o valor padrão igual a 10 segundos)
StartService()
StopService()
RestartService()
Para testar essa classe vamos abrir a solução Tratando_Servicos, criada no VS 2013 Express for Windows desktop, na primeira parte do artigo.
A seguir vamos incluir uma referência ao projeto Class Library ServicosWin no projeto Windows Forms Tratando_Servicos;
Clique com o botão direito sobre o projeto Tratando_Servicos e a seguir em Add Reference;
Selecione o projeto ServicosWin e clique em OK;
Agora vamos incluir no formulário do projeto 3 botões de comando a partir da ToolBox:
1 Button - btnPararServico
1 Button - btnIniciar
1 Button - btnReiniciar
Disponha os controles no formulário conforme o leiaute da figura abaixo:
No início do formulário teremos que ter definidos os seguintes namespaces:
using
System;No formulário Form1.cs vamos incluir um método rodarComoAdmin() no construtor do formulário e a seguir vamos definir uma variável chamada nomeServico para armazenar o nome do serviço selecionado:
public Form1()
{
InitializeComponent();
rodarComoAdmin();
}
string nomeServico = "";
|
O código do método rodarComoAdmin() é dado a seguir:
private void rodarComoAdmin() { WindowsPrincipal principal = new WindowsPrincipal(WindowsIdentity.GetCurrent()); bool administrativeMode = principal.IsInRole(WindowsBuiltInRole.Administrator);
if (!administrativeMode) |
Este código é uma tentativa de fazer com que o usuário que esta executando o projeto tenha direito de administrador. Devido às particularidades de cada Sistema operacional ele pode ou não funcionar.
Nota: Se este código fizer o programa travar encerre e desabilite o código comentando a sua chamada no construtor.
Agora vamos implementar em cada um dos botões de comando o código para realizar o respectivo serviço:
1- Parar Serviço
private void btnPararServico_Click(object sender, EventArgs e) { if (string.IsNullOrEmpty(nomeServico)) if (resultado == DialogResult.Yes) |
2- Iniciar Serviço
private void btnIniciar_Click(object sender, EventArgs e) { if (string.IsNullOrEmpty(nomeServico)) { MessageBox.Show("Informe o nome do serviço", "Nome do Servico", MessageBoxButtons.OK, MessageBoxIcon.Information); } else { try { DialogResult resultado = MessageBox.Show("Deseja iniciar o serviço : " + nomeServico + " ?", "Iniciar", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
if (resultado == DialogResult.Yes) |
3- Reiniciar Serviço
private void btnReiniciar_Click(object sender, EventArgs e) { if (string.IsNullOrEmpty(nomeServico)) { MessageBox.Show("Informe o nome do serviço", "Nome do Servico", MessageBoxButtons.OK, MessageBoxIcon.Information); } else { try { DialogResult resultado = MessageBox.Show("Deseja reiniciar o serviço : " + nomeServico + " ?", "Reiniciar", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
if (resultado == DialogResult.Yes) |
Finalmente vamos implementar no evento SelectedIndexChanged do controle ListView o código que obtém o nome do serviço e o atribui à variável nomeServico:
private void lvServicos_SelectedIndexChanged(object sender, EventArgs e) { try { nomeServico = lvServicos.SelectedItems[0].SubItems[0].Text; } |
Executando o projeto e selecionando um serviço da lista de serviços apresentada no ListView iremos obter o seguinte resultado:
Pegue o projeto completo aqui : Tratando_Servicos_3.zip
Jesus lhes respondeu, e disse: A minha
doutrina não é minha, mas daquele que me enviou.
Se alguém quiser fazer a vontade dele, pela mesma doutrina conhecerá se ela é de
Deus, ou se eu falo de mim mesmo.
João 7:16,17
Veja os
Destaques e novidades do SUPER DVD Visual Basic
(sempre atualizado) : clique e confira !
Quer migrar para o VB .NET ?
Quer aprender C# ??
Quer aprender os conceitos da Programação Orientada a objetos ? Quer aprender o gerar relatórios com o ReportViewer no VS 2013 ? |
Gostou ? Compartilhe no Facebook Compartilhe no Twitter
Referências: