views:

66

answers:

5

I've got a windows service that relies on a DLL. Whether the service is running or not, its executable is keeping a handle to that DLL, which is preventing me from updating it automatically.

Why is this, and how can I remove that handle programatically (preferably via .Net)?

Update: I know that the service's executable is the one with the handle because I ran handle.exe on the dll and only the service's exe came up. Nothing cane up when I ran it on the exe and I know that the service isn't running because I checked the services list. There is nothing else that would be using the dll that I can think of.

+2  A: 

This is not possible. Only a running process can have a handle to a file.

You can use Process Explorer to find out which process has a handle to the DLL open:

  1. Start Process Explorer
  2. Press Ctrl+F and search for the DLL name
  3. Wait for the search to complete
  4. You will see which process(es) have an open handle to the DLL.
0xA3
+1  A: 

There is no way to have an EXE drop a handle to a DLL from another process. It almost certainly has the handle because the DLL is being actively used by the process. The only option available really is to kill the EXE process from the service. This can be done via the Process.Kill method.

Although killing other processes you don't own is generally speaking bad behavior in the programming world. Why is your program better than theirs?

JaredPar
Well, you can at least make the process free the library from the outside, but this is obviously not a very smart choice.
Jim Brissom
+2  A: 

The DLL was loaded and mapped into virtual memory. That puts a lock on the file. Starting or stopping the service doesn't change that. The exact same is true for the service EXE.

You would have to dynamically load and unload the DLL to fix this. LoadLibrary and FreeLibrary. But that only works if it is an unmanaged DLL. And is very risky if you use pinvoke because the CLR won't automatically load the DLL again after you unloaded it.

If it is a managed DLL that you can only unload it if it was loaded in another AppDomain. No bed of roses either.

Hans Passant
I do shut down the service in an app domain that I then unload. I also unload the app domain that installed the service. I can try unloading the domain that starts it as well. Do you think that might help?
Mike Pateras
It turns out I was already doing that.
Mike Pateras
That's where the roses get prickly, it is difficult to work with ADs and not get the type loaded in both domains. You need interfaces declared in a separate assembly that you can afford to have loaded in both. Perhaps a good topic for a new question.
Hans Passant
I started a new question, because I'm running into the problem that this comment addresses. Even though my service is shut down, there's a lock on the executable, and I'm not sure how to free it up so that I can update it. Here's the new post: http://stackoverflow.com/questions/3823708/how-can-i-avoid-file-locks-when-updating-a-windows-service
Mike Pateras
A: 

This was a nasty little problem. The service has two threads, and one of them performs a very subtle, not frequently needed function, and I did not notice that it was getting deadlocked over a shared resource. So it was hanging, indefinitely, which is what was keeping my executable engaged, despite the service being shut down. Fixing that issue resolved my file handle issue.

Thanks for the suggestions, all.

Mike Pateras
A: 

I always here such problems when people create long running windows service process and then invest great time in resolving problems it create.

If possible, can you think of using Windows Task Scheduler for this? You see here why..http://pavangayakwad.blogspot.com/2010/09/windows-service-or-windows-task.html

Pavan G R