Wednesday, May 27, 2015

c# - WPF Application for restarting Windows Service

I have windows service that runs on 11 different web & file servers.Every now and then our team has to restart these services. I use the sc command to do this at the command prompt
Example: 
stop service: sc \\server_name stop service_name
start service: sc \\server_name start service_name

It's hard to recollect the command if you are new to managing services.Remote logging in to the server to restart the service on 11 different servers is tedious.So I decided to create a small application that would let my team members to choose the server and restart the service.

I created a new project in Visual Studio,selected WPF application and gave it name RemoteRestartSVC.
Added a ListBox and Button to the XAML.The listbox contains the names of the server.I've added a progressbar to indicate the status(very basic progressbar)

Below is the App form and the XAML.
















<Window x:Class="RemoteWindowsSVCRestarter.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Service Restarter" Height="469.762" Width="400" Background="#FFF9F9F9">
    <Grid Margin="0,0,0,391">
        <Label Content="Server Collection" HorizontalAlignment="Left" Margin="25,10,0,-15" VerticalAlignment="Top" FontWeight="Bold" Height="32" FontSize="16"/>
       
        <Button Name="RestartButton" Content="Restart Service" HorizontalAlignment="Left" Margin="131,295,0,-298" VerticalAlignment="Top" Width="135" Height="30" Click="RestartButton_Click" FontWeight="Bold" Background="#FFE8E8E8" RenderTransformOrigin="0.573,1.892" FontSize="14"/>
        <ListBox Name="ServiceListBox" HorizontalAlignment="Left" Height="234" Margin="25,47,0,-254" VerticalAlignment="Top" Width="345">
            <ListBoxItem Content="wk01" FontSize="14"></ListBoxItem>
            <ListBoxItem Content="wk02" FontSize="14"></ListBoxItem>
            <ListBoxItem Content="wk03" FontSize="14"></ListBoxItem>
            <ListBoxItem Content="wk04" FontSize="14"></ListBoxItem>
            <ListBoxItem Content="wk05" FontSize="14"></ListBoxItem>
            <ListBoxItem Content="hf01" FontSize="14"></ListBoxItem>
            <ListBoxItem Content="hf02" FontSize="14"></ListBoxItem>
            <ListBoxItem Content="hf03" FontSize="14"></ListBoxItem>
            <ListBoxItem Content="hf04" FontSize="14"></ListBoxItem>
            <ListBoxItem Content="hf05" FontSize="14"></ListBoxItem>
            <ListBoxItem Content="hf06" FontSize="14"></ListBoxItem>
        </ListBox>
        <Label Content="Status:" HorizontalAlignment="Left" Height="31" Margin="5,351,0,-333" VerticalAlignment="Top" Width="49" FontWeight="Bold"/>
        <ProgressBar Name="RestartProgressBar" Margin="54,351,5,-332" />
    </Grid>
</Window>


Below is the code for the entire Application.It consists of two main methods.Stop Service and Start Service.

Stop Service method creates the process and calls the cmd.exe with the sc command to stop the service.It checks the status of the service and once the service is stopped, it returns a flag that indicates the service was successfully stopped.

Start Service method is similar to Stop Services method and it starts the service once the service status is Stopped.

using System.Diagnostics;
using System.ServiceProcess;
using System.Threading;
using System.Windows;
using System.Windows.Controls;

namespace RemoteWindowsSVCRestarter
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void RestartButton_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                RestartButton.IsEnabled = false;
                RestartProgressBar.IsIndeterminate = true;
                ListBoxItem oServerItem = (ListBoxItem)ServiceListBox.SelectedItem;
                if (oServerItem != null)
                {
                    string sServerName = oServerItem.Content.ToString();

                    if (!string.IsNullOrEmpty(sServerName))
                    {
                        bool bStopFlag = StopService(sServerName);
                        if (!bStopFlag)
                            StartService(sServerName);
                    }
                }
                else
                {
                    MessageBox.Show("Select a server name before clicking restart service");
                }
            }
            catch 
            {
                MessageBox.Show("Unexpected error occurred while restarting the service");
            }
            RestartButton.IsEnabled = true;
            RestartProgressBar.IsIndeterminate = false;
        }

        /// <summary>
        /// Start the service
        /// </summary>
        /// <param name="sServerName"></param>
        private static void StartService(string sServerName)
        {
            ExecuteCommand(string.Format(@"/C sc \\{0} start MyService", sServerName));

            int iStartSeconds = 0;
            bool bStartFlag = false;
            ServiceController oRestartedService = new ServiceController("MyService", sServerName);
            while (oRestartedService != null && oRestartedService.Status != ServiceControllerStatus.Running)
            {
                Thread.Sleep(1000);
                iStartSeconds++;
                //Wait for 30 seconds for the service to start
                if (iStartSeconds == 30)
                {
                    bStartFlag = true;
                    break;
                }
                oRestartedService = new ServiceController("MyService", sServerName);
            }
            if (!bStartFlag)
                MessageBox.Show("Service restarted on server " + sServerName + " successfully");
            else
                MessageBox.Show("Alert: The service restart on server " + sServerName + " failed !");
        }

        /// <summary>
        /// Stop the service
        /// </summary>
        /// <param name="sServerName"></param>
        /// <returns></returns>
        private static bool StopService(string sServerName)
        {
            ExecuteCommand(string.Format(@"/C sc \\{0} stop MyService", sServerName));

            int iStopSeconds = 0;
            bool bStopFlag = false;
            ServiceController oService = new ServiceController("MyService", sServerName);
            while (oService != null && oService.Status != ServiceControllerStatus.Stopped)
            {
                Thread.Sleep(1000);
                iStopSeconds++;
                //Wait for 30 seconds for the service to stop
                if (iStopSeconds == 30)
                {
                    bStopFlag = true;
                    break;
                }
                oService = new ServiceController("MyService", sServerName);
            }
            return bStopFlag;
        }



        /// <summary>

        /// Creates a process and executes a command

        /// </summary>

        /// <param name="sCommand"></param>

        private static void ExecuteCommand(string sCommand)

        {

            Process oProcess = new Process();
            ProcessStartInfo oStartInfo = new ProcessStartInfo();
            oStartInfo.WindowStyle = ProcessWindowStyle.Hidden;
            oStartInfo.FileName = "cmd.exe";
            oStartInfo.Arguments = sCommand;
            oProcess.StartInfo = oStartInfo;
            oProcess.Start();
        }
    }
}
































No comments: