Killing the process associated with a Windows service programatically?

Hey experts,

I have a question that I'm struggling with and would love your help with this. Let me start with the logic of what I'm trying to do.

Logic:

1. There is a windows service running. eg. Name = "Service A"
2. I want to stop the service.
3. I have an associated timeout for the service. eg. 2000
4. if the timeout occurs and the service doesnt stop in that time, I want to kill the process associated with the service.

Question:

How do I kill the process associated with the service, when I only have the name of the service. Basically, if I'm using serviceController, How do I kill the service?

I have some psuedo code here. Please advice.

Thanks,
ServiceController service  = new ServiceController("Service A");
 
try 
{
     service.stop();
     service.waitforstatus(STOPPED, 2000);
}
catch 
{
     // need to kill the process associated with the service. But only have the service name  
     // with me i.e. 'Service A'
}

Open in new window

kunal_hopra28Asked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Anurag AgarwalPython DeveloperCommented:
abelCommented:
I assume you already use the code like the one in this post: http://www.csharp-examples.net/restart-windows-service/
 
problem
 Assuming you find out at some point what process the service belongs to, you'll still have a problem there: one service-process (svchost.exe) can run multiple services and you don't want the other services to fall down with yours, I hope?

solution 1
Suppose that your service is always ran within a single process without any other services in it. In that case, you can query the current processes and check whether they are svchost.exe and whether their arguments contain the name of your service.

solution 2
If your service has its own executable, things become a bit easier. All you need to do is query HKLM\System\controlSet001\Services\[Service Name Here]|ImagePath and compare that to the list of processes.

The whole idea would look something like this. Note that you need the registry access, because the .NET service controller and related classes cannot return the ImagePath:

-- Abel --

PS: I wrote this code and it compiled, but I did not test it, it is likely that it needs some tweaking.

string registryImgPath = (string) Registry.GetValue(@"HKEY_LOCAL_MACHINE\System\controlSet001\Services\YourServiceName", "Image", "");
// do some replacing here to only get the executable
registryImgPath = Regex.Replace(registryImgPath, @"(*\.exe ).*", "$1");
if (registryImgPath != null)
{
 
    Process proc = (from Process p in Process.GetProcesses()
                    where p.StartInfo.FileName == "yourImagePath.exe"
                    select p).FirstOrDefault();   // FirstOrDefault will return null if none exists
 
    if(proc != null)  // proc found
        proc.Kill();   // send kill command to process
}

Open in new window

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
abelCommented:
On review it seems that it needs a slight change to work:

string registryImgPath = (string) Registry.GetValue(@"HKEY_LOCAL_MACHINE\System\controlSet001\Services\YourServiceName", "Image", "");
if (registryImgPath != null)
{
    // do some replacing here to only get the executable
    registryImgPath = Regex.Replace(registryImgPath, @"([^\/]+\.exe).*", "$1");
 
    Process proc = (from Process p in Process.GetProcesses()
                    where p.StartInfo.FileName == registryImgPath 
                    select p).FirstOrDefault();   // FirstOrDefault will return null if none exists
 
    if(proc != null)  // proc found
        proc.Kill();   // send kill command to process
}

Open in new window

abelCommented:
I come with a complex solution for a complex problem in a short amount of time and you don't follow up with why it is not good enough for you, yet you grade low. Please read the 10 pts must principle of EE and give us a chance to help you and to earn that grade. Remember that the expert you grade today you may need to rely on tomorrow.
kunal_hopra28Author Commented:
Thanks Admin for doing this. I was going to do this this afternoon. Sorry Abel for giving the lower grade. It was a mistake on my part since I had not read the rules that you sent me.

I appreciate your effort and dedication in helping me with this. I look forward to your expertise in the future as well.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C#

From novice to tech pro — start learning today.