Link to home
Create AccountLog in
C#

C#

--

Questions

--

Followers

Top Experts

Avatar of William Myers
William Myers🇺🇸

C# windows service to monitor another windows service...
We have a third party windows service that runs after installation and we need to monitor that service.  So in the grand scheme of things under high volumes of using the service of the vendor it stops.

The issue is that we do not know when it stops and the business has to tell us that this or that isn't working and we then have to find the failing service (many boxes with the same service) and manually start it.

Writing a C# .NET app to "monitor" this service is what we are seeking but have no great examples of this.  There are articles on how to keep alive the service that you built but not another service.

We are trying to "query" what is there and get it from that angle without much success.

Any suggestions?  I know this isn't a windows service code below but it was easier to try and debug/output etc.

using System;
using System.Management;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace RestartProcess
{
    class processes
    {
        public static void Main()
        {
            ManagementEventWatcher startWatch = new ManagementEventWatcher(
              new WqlEventQuery("SELECT * FROM Win32_ProcessStartTrace"));
            startWatch.EventArrived += new EventArrivedEventHandler(startWatch_EventArrived);
            startWatch.Start();
            ManagementEventWatcher stopWatch = new ManagementEventWatcher(
              new WqlEventQuery("SELECT * FROM Win32_ProcessStopTrace"));
            stopWatch.EventArrived += new EventArrivedEventHandler(stopWatch_EventArrived);
            stopWatch.Start();
            Console.WriteLine("Press any key to exit");
            while (!Console.KeyAvailable) System.Threading.Thread.Sleep(50);
            startWatch.Stop();
            stopWatch.Stop();
        }

        static void stopWatch_EventArrived(object sender, EventArrivedEventArgs e)
        {
            Console.WriteLine("Process stopped: {0}", e.NewEvent.Properties["ProcessName"].Value);
        }

        static void startWatch_EventArrived(object sender, EventArrivedEventArgs e)
        {
            Console.WriteLine("Process started: {0}", e.NewEvent.Properties["ProcessName"].Value);
        }
    }
}

Is there a way to tell it "here is the service" to monitor and if it is down - restart it?

Any help would be greatly appreciated.

Zero AI Policy

We believe in human intelligence. Our moderation policy strictly prohibits the use of LLM content in our Q&A threads.


Avatar of it_saigeit_saige🇺🇸

There are a couple of ways to do this, however, before you get into the programming aspect of it, why not just utilize the Recovery options available from the Services snap-in?User generated image-saige-

Avatar of William MyersWilliam Myers🇺🇸

ASKER

We have it set this way actually but it doesn't restart the service all the time. The failure can cause the service to be down for minutes while it crashes.  When it crashes we need to have it come back up after x attempts.

It seems illogical I agree....we went down this road first before trying to develop an app as a windows service.

My contention is if we wait x minutes and try then repeat until it starts back up we will be good to go.  Give it a "lag" if you will.

So the idea is to have a file with the name of the service and wait time to try a restart to be successful.

Great thought though.

Avatar of it_saigeit_saige🇺🇸

That was my fear.  Just to paraphrase to ensure that I am understanding you.  You have a service that will no longer process requests.  Sometimes when this happens the service process stops but at other times it does not.

Does this describe the issue?  If it does, then you are correct, simply enabling the service recovery will not work (unless the executable itself actually quits, if this is the case then you will want to ensure that you have checked the option to 'Enable actions for stops with errors.'

-saige-

Reward 1Reward 2Reward 3Reward 4Reward 5Reward 6

EARN REWARDS FOR ASKING, ANSWERING, AND MORE.

Earn free swag for participating on the platform.


Avatar of William MyersWilliam Myers🇺🇸

ASKER

Yes you have nailed it....that is what we are facing.  It is some real spaghetti code so we have no idea what "part" is failing so it could be anything really since there are so many things that can choke.

If we give it a cyclic approach I am thinking this would resolve it.  Like once the final "piece" has choked out it can be restarted.  We have to do it manually but by the time the business knows it is down, we RDP into the box (after finding which one it is out of the 9 total servers) we have the ability to manually start it again.

So I was thinking about something like this:

using System;
using System.Management;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.ServiceProcess;

namespace RestartProcess
{
    class processes
    {
        public static void Main()
        {
            ManagementEventWatcher startWatch = new ManagementEventWatcher(
              new WqlEventQuery("SELECT * FROM Win32_ProcessStartTrace"));
            startWatch.EventArrived += new EventArrivedEventHandler(startWatch_EventArrived);
            startWatch.Start();
            Console.WriteLine(startWatch.ToString());
            ManagementEventWatcher stopWatch = new ManagementEventWatcher(
              new WqlEventQuery("SELECT * FROM Win32_ProcessStopTrace"));
            stopWatch.EventArrived += new EventArrivedEventHandler(stopWatch_EventArrived);
            Console.WriteLine(stopWatch.ToString());
            stopWatch.Start();
            Console.WriteLine("Press any key to exit");
            while (!Console.KeyAvailable) System.Threading.Thread.Sleep(1000); // 1000 ms variable
            startWatch.Stop();
            stopWatch.Stop();
        }

        static void stopWatch_EventArrived(object sender, EventArrivedEventArgs e)
        {
            Console.WriteLine("Process stopped: {0}", e.NewEvent.Properties["ProcessName"].Value);
        }

        static void startWatch_EventArrived(object sender, EventArrivedEventArgs e)
        {
            Console.WriteLine("Process started: {0}", e.NewEvent.Properties["ProcessName"].Value);
        }
         
        public static void StartService(String strSVCName)
        {

        ServiceController sc = new System.ServiceProcess.ServiceController(strSVCName);
        try
        {
            if (sc.Status.Equals(ServiceControllerStatus.Paused))
            {
                WriteLogEntry(DateTime.Now, "Paused");
                sc.Start();
                sc.WaitForStatus(ServiceControllerStatus.Running);
                WriteLogEntry(DateTime.Now, "Started Up!");
            }

            if (sc.Status.Equals(ServiceControllerStatus.PausePending))
            {
                WriteLogEntry(DateTime.Now, "Pause Pending");
            }

            if (sc.Status.Equals(ServiceControllerStatus.ContinuePending))
            {
                WriteLogEntry(DateTime.Now, "Continue Pending");
            }

            if (sc.Status.Equals(ServiceControllerStatus.StartPending))
            {
                WriteLogEntry(DateTime.Now, "Start Pending");
            }

            if (sc.Status.Equals(ServiceControllerStatus.StopPending))
            {
                WriteLogEntry(DateTime.Now, "Stop Pending");
            }

            if (sc.Status.Equals(ServiceControllerStatus.Stopped))
            {
                WriteLogEntry(DateTime.Now, "Stopped");
                sc.Start();
                sc.WaitForStatus(ServiceControllerStatus.Running);
                WriteLogEntry(DateTime.Now, "Started Up!");
            }
        }

        catch (Exception ex)
        {
            Console.WriteLine(ex.InnerException.ToString());
        }
        finally
        {
            sc.Close();
            sc.Dispose();
        }
        }

        public static void WriteLogEntry(DateTime When, String What)
        {
            StreamWriter WriteLog = new StreamWriter("ServiceUpkeep.log");
            WriteLog.Write(What + " " + When);
        }
    }
}


And then specify the strSVCName string to read from the flat file.  So it would cycle through everything and if it has a status of Running nothing happens.  Otherwise it writes to the log file and then restarts it and will wait until it is actually started.

Does that make sense?

I am just trying to determine the best way to get this into a windows service and "call it" to do the job since the console app can be closed, we could auto start the service, etc. for a better solution.

Which is of course the part that I am struggling with a bit here....lol

Avatar of it_saigeit_saige🇺🇸

First question then, when you remote into the servers, how do you make the determination that the service is no longer responding?

-saige-

Avatar of William MyersWilliam Myers🇺🇸

ASKER

Usually by going to the Task Manager and seeing if the process is running.  The status is usually stopped or blank.

Free T-shirt

Get a FREE t-shirt when you ask your first question.

We believe in human intelligence. Our moderation policy strictly prohibits the use of LLM content in our Q&A threads.


Avatar of William MyersWilliam Myers🇺🇸

ASKER

Or the entry is missing all together (forgot that one).

ASKER CERTIFIED SOLUTION
Avatar of it_saigeit_saige🇺🇸

Link to home
membership
Log in or create a free account to see answer.
Signing up is free and takes 30 seconds. No credit card required.
Create Account

Avatar of William MyersWilliam Myers🇺🇸

ASKER

Great work!  Everything works as expected and starts in the console.

Thanks so much!

Avatar of William MyersWilliam Myers🇺🇸

ASKER

Perfect solution

Reward 1Reward 2Reward 3Reward 4Reward 5Reward 6

EARN REWARDS FOR ASKING, ANSWERING, AND MORE.

Earn free swag for participating on the platform.

C#

C#

--

Questions

--

Followers

Top Experts

C# is an object-oriented programming language created in conjunction with Microsoft’s .NET framework. Compilation is usually done into the Microsoft Intermediate Language (MSIL), which is then JIT-compiled to native code (and cached) during execution in the Common Language Runtime (CLR).