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
































Friday, May 15, 2015

Freeing Disk Space on Windows Servers

We have some old  servers that will be replaced soon.However on one of the servers the C drive hardly has any space left.I decided to clean up some old files so that we have enough space till we get the replacement servers.


Below are some ways of freeing up disk space by deleting old,unwanted files.

1) Use Disk Cleanup
Click on Start -> Program -> Accessories -> System Tools -> Disk Cleanup
















2) Delete files from Temp folder C:\Windows\Temp\













3) Delete .tmp files
Go to search and search for files with extension .tmp

















4) Delete Uninstall folders
Go to search and search for folders $UnInstal. These folders are hidden and are under C:\Windows\ 























5) Delete folders from C:\Windows\SoftwareDistribution\Download\
These are files/folders created by the windows update program.Once the programs are installed these files can be cleaned up to free up some diskspace.Before deleting the files make sure you stop the windows update service.













c# - Extract data from Green Plum Warehouse Tables PostGreSql

Below are two ways to extract data from Green Plum Warehouse tables.For tables that are small the code is straightforward.However for tables with millions of rows the steps are a little different.
I have listed the code for both here.

I have used the Npgsql.dll to create the connection to progresql Green Plum Warehouse.Add it as a reference in your C# project.Documentation can be found here http://npgsql.projects.pgfoundry.org/

1) For tables with small number of rows.

using Npgsql;
using System;
using System.Configuration;

namespace GPExtract
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                ExtractData();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                Console.WriteLine(ex.StackTrace);
            }
            Console.WriteLine("Done !");
            Console.Read();
        }
        private static void ExtractData()
        {
            using (NpgsqlConnection oConn = new                             NpgsqlConnection(ConfigurationManager.AppSettings["GP_CONNECTION_STRING"]))
            {
                       NpgsqlCommand oCmd = new NpgsqlCommand(@"select distinct(id),min(create_ts),max(create_ts) from mytable group by id order by id", oConn);
                       oCmd.CommandTimeout = int.Parse(ConfigurationManager.AppSettings["COMMAND_TIMEOUT"]);
                      NpgsqlDataReader oReader = oCmd.ExecuteReader();

                      using (StreamWriter oWriter = new StreamWriter(ConfigurationManager.AppSettings["OUTPUT_FOLDER_PATH"] + "myoutputfile.txt"))
                      {
                              while (oReader.Read())
                              {
                                        oWriter.WriteLine(string.Format("{0}\t{1}\t{2}", dr.GetValue(0) != null ? dr.GetValue(0).ToString() : "", dr.GetValue(1) != null ? GetFormattedDateTime(dr.GetValue(1).ToString()) : "", dr.GetValue(2) != null ? GetFormattedDateTime(dr.GetValue(2).ToString()) : ""));
                               }
                       }
             }
         }
    }
}

2) In case of millions of rows the extraction of all rows is done by creating file on Green Plum accessible share, a temporary external table and loading the external table with the data from the Green Plum warehouse table. 

using Npgsql;
using System;
using System.Configuration;

namespace GPExtract
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                string sGpFilePath = ConfigurationManager.AppSettings["GP_FILE_PATH"];
                string sOutputFilePath = ConfigurationManager.AppSettings["OUTPUT_FILE_PATH"];
                ExtractData(sGpFilePath,sOutputFilePath);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                Console.WriteLine(ex.StackTrace);
            }
            Console.WriteLine("Done !");
            Console.Read();
        }
        private static void ExtractData(string sGpFilePath,string sOutputFilePath)
        {
                if(!File.Exists(sGPFilePath)
               {
                          //Create a file for GP to load from external table
                          File.Create(sGpFilePath);

                          string sSql = @"CREATE WRITABLE EXTERNAL TEMP TABLE temp_mytable (  id character varying(22),
  min_create_dt integer,
  max_create_dt integer)LOCATION (
                'gpfdist://server-1:8082/mylogin/DATA/myfile.txt',
                'gpfdist://server-1:8083/mylogin/DATA/myfile.txt',
                'gpfdist://server-1:8084/mylogin/DATA/myfile.txt',
                'gpfdist://server-1:8085/mylogin/DATA/myfile.txt')
                FORMAT 'text' (delimiter E'\t' null '' )
                ENCODING 'LATIN9'
                DISTRIBUTED randomly;
            insert into temp_mytable
                select distinct(id),min(create_dt),max(create_dt) from  mytable group by id order by id;";

            using (NpgsqlConnection oConn = new NpgsqlConnection(ConfigurationManager.AppSettings["GP_CONNECTION_STRING"]))
            {
                oConn.Open();
                NpgsqlCommand oCmd = new NpgsqlCommand(sSql, oConn);
                oCmd.ExecuteNonQuery();
            }
             //Move the file from GP share to server
              File.Move(sGpFilePath, sOutputFilePath);
        }
    }
}

Note: The second program is parallel extract across ports 8082-8085 and is faster.

Tuesday, May 5, 2015

c# - Call exe with incremental filenames as command line arguements

I work on projects involving data processing and more often than not, we end up processing files created over months.This requires that the data processing program is called over number of times.Instead of doing it manually I created this small utility program to automate the processing of these files.

Below I have listed the code for sequential/batch processing of files using a program as well as parallel processing of files using the same program.

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace IncrementCmdLineArgs
{
    class Program
    {
        static void Main(string[] args)
        {
            int iStartCounter = int.Parse(ConfigurationManager.AppSettings["START_COUNTER"]);
            int iEndCounter = int.Parse(ConfigurationManager.AppSettings["END_COUNTER"]);
            string sInputFile = ConfigurationManager.AppSettings["INPUT_FILENAME"];
            string sOutputFile = ConfigurationManager.AppSettings["OUTPUT_FILENAME"];
            string sExeName = ConfigurationManager.AppSettings["EXE_NAME"];
            string sWorkingDir = ConfigurationManager.AppSettings["WORKING_DIR"];
            string sInputParam = ConfigurationManager.AppSettings["INPUT_PARAM_NAME"];
            string sOutputParam = ConfigurationManager.AppSettings["OUTPUT_PARAM_NAME"];

            try
            {
                for (int iCounter = iStartCounter; iCounter <= iEndCounter; iCounter++)
                {
                    Process oProc = new Process();
                    oProc.StartInfo.FileName = sExeName;
                    oProc.StartInfo.WorkingDirectory = sWorkingDir;
                    oProc.StartInfo.CreateNoWindow = true;
                    oProc.StartInfo.Arguments = string.Format(" {0}={1} {2}={3}", sInputParam, sInputFile + iCounter + ".txt", sOutputParam, sOutputFile + iCounter + ".txt");
                    Console.WriteLine(string.Format(" {0}={1} {2}={3}", sInputParam, sInputFile + iCounter + ".txt", sOutputParam, sOutputFile + iCounter + ".txt"));
                    oProc.Start();
                    oProc.WaitForExit();
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                Console.WriteLine(ex.StackTrace);
            }
            Console.Write("Done.Press any key to exit !");
            Console.Read();
        }
    }
}


The parallel version is below

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace IncrementCmdLineArgs
{
    class Program
    {
        static void Main(string[] args)
        {
            int iStartCounter = int.Parse(ConfigurationManager.AppSettings["START_COUNTER"]);
            int iEndCounter = int.Parse(ConfigurationManager.AppSettings["END_COUNTER"]);
            string sInputFile = ConfigurationManager.AppSettings["INPUT_FILENAME"];
            string sOutputFile = ConfigurationManager.AppSettings["OUTPUT_FILENAME"];
            string sExeName = ConfigurationManager.AppSettings["EXE_NAME"];
            string sWorkingDir = ConfigurationManager.AppSettings["WORKING_DIR"];
            string sInputParam = ConfigurationManager.AppSettings["INPUT_PARAM_NAME"];
            string sOutputParam = ConfigurationManager.AppSettings["OUTPUT_PARAM_NAME"];

            try
            {
                 Parallel.For(iStartCounter, iEndCounter, iCounter =>
                {
                    Process oProc = new Process();
                    oProc.StartInfo.FileName = sExeName;
                    oProc.StartInfo.WorkingDirectory = sWorkingDir;
                    oProc.StartInfo.CreateNoWindow = true;
                    oProc.StartInfo.Arguments = string.Format(" {0}={1} {2}={3}", sInputParam, sInputFile + iCounter + ".txt", sOutputParam, sOutputFile + iCounter + ".txt");
                    Console.WriteLine(string.Format(" {0}={1} {2}={3}", sInputParam, sInputFile + iCounter + ".txt", sOutputParam, sOutputFile + iCounter + ".txt"));
                    oProc.Start();
                });
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                Console.WriteLine(ex.StackTrace);
            }
            Console.Write("Done.Press any key to exit !");
            Console.Read();
        }
    }
}