2

I'm working in .NET 3.5 and I have the problem with stopping some service using ServiceController. I searched whole internet and I found no solution to my problem ;)

Here's how I do that:

using (ServiceController service = new ServiceController("Service"))
{
    try
    {
        TimeSpan timeout = TimeSpan.FromSeconds(timeoutSeconds);

        service.Stop();
        service.WaitForStatus(ServiceControllerStatus.Stopped, timeout);
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.ToString());
    }
}

I'm waiting until my service stops. Then I want to replace it's libraries (update it). And the exception is thrown:

UnauthorizedAccessException Exception Details: System.UnauthorizedAccessException: Access to the path 'blablabla' is denied.

I'm sure that I have access to this path, because I run my application as an Administrator.

What is interesting when this piece of code executes, this Service disappear from the List of current services (in Task Manager). So it actually stops it, but some thread has to still use it, so I can not move any Service's files. Even when I try to move files by myself (I go to the Service directory and try to move its files using mouse) I can not do it. But when I stop the Service manually (Task Manager and 'End Task') I can do whatever I want with its files. So what's the difference between stopping it from C# code (using ServiceController) and stopping it using Task Manager?

I don't know if it's important but I run this application (and this Service) on Windows Server 2008 in Virtual Box. (I needed to run it on some other machine then my computer).

Any ideas how can I solve this problem? ;)

Thanks for any help.

Best wishes, Pete.

Tshilidzi Mudau
  • 7,373
  • 6
  • 36
  • 49
Peter
  • 912
  • 3
  • 11
  • 29
  • The reason you can stop the code with `Task Manager` is because it already has an Administrator Token. In order for your application to manipulate the `Service` you'll need to impersonate or verify your application is at the proper Administrator Level. This can be done with `Windows Principal Assembly`. Your other option would be to initiate a `Process` that will run an Administrator Command-Prompt Command of `Net Stop` to stop the `Service`. Then invoke the `Process` again once it has completed it's task to start again. – Greg Feb 09 '13 at 00:21
  • 1
    You did not stop the service with Task Manager, you *killed it*. Big difference. – Hans Passant Feb 09 '13 at 01:32
  • @Greg I thought about it, but I also thought that if we have something like ServiceController I will be able to control my service with it, but in this situation I will have to do as You wrote and use 'net stop' Thanks for all the answers! – Peter Feb 09 '13 at 08:27
  • @HansPassant Ok, so what is the difference between stopping it and killing it? What threads still use this service (or this service's files)? – Peter Feb 09 '13 at 08:28
  • Killing it abruptly stops it. Stopping ensures all components shut down correctly. – Greg Feb 09 '13 at 09:23

1 Answers1

5

Ok, I solved my problem.

First I used an Administrator Command-Prompt Command of Net Stop to stop the Service and it worked, but I started to wonder why. The answer is it took a lot of time! ServiceController actually stopped it, but some processes was still using it.

 service.WaitForStatus(ServiceControllerStatus.Stopped, timeout);

Also workerd fine, because it imidaitely changed the status of the service (it's just one change in Windows Services list), but closing politely all threads using certain Service takes some time :)

So all You need to do is just wait, and then check again if it's still running. If it is, then kill it with Process class.

Peter
  • 912
  • 3
  • 11
  • 29