views:

145

answers:

2

I'm trying to deploy new copies of my DLL to the GAC on remote servers, but I need to identify if any processes currently running have a loaded copy of the DLL I'm replacing - I'd like to restart them, or at least tell the user.

For example, Biztalk seems to load the DLLs it needs the first time they're used, and then replacing them keeps the old copy in memory until the Host Instances are restarted - something I could easily do as part of my deployment.

Is there a way to tell using .NET which processes have loaded a particular DLL from the GAC?

UPDATE:

Some further investigation shows that both Process Explorer has this functionality, and another Sysinternals tool, ListDLL, does exactly what I want to be able to do. I'd like to know how they do it, since I'd love to replicate this functionality in my application without having to include and screen-scrape ListDLL (if that's even allowed inside the license).

A: 

You need to do this programmatically or manually?

You can use the handle/DLL search capability of Process Explorer to manually find what modules are in use.

link text

Update:

No, I have no idea how this works, other than extensive use of things from dusty corners of the Win32 and NT APIs.

There are some open-source alternatives you could take a look at:

Another utility, PSList will list the processes on a remote machine, and that page says it does so using the Windows performance counters, the same thing that drives the control panel/admin tools/performance MMC. I know you can access these counters from .NET, but I have no idea if you can get the loaded modules or other details about the processes.

The MSDN docs say that Process.GetProcesses uses performance counters, so that's probably the way to go, you just need to figure out how to make it work. Whatever problem you're having with that will also happen if you do the same thing manually. You don't need to do this from a Win95/98/ME machine do you?

You may need to do something like WNetAddConnection to authenticate yourself on the remote machine before querying it. I'm not sure what the .net equivalent is, though.

Worst case I guess is you write an app that runs locally on your server and returns the results to you over a socket or something.

Tim Sylvester
I'd love to do it programmatically - since Process Explorer does it, that means it can be done, which is encouraging. Any ideas how they do?
rwmnau
@rwmnau Answer updated.
Tim Sylvester
A: 

Would something like this work:

Process[] proc = Process.GetProcesses("<optional machine name>");
ProcessModuleCollection mods = proc[0].Modules;

The mods collection would contain every module loaded for the current process. You could easily iterate over the proc collection, and then mod collection and see if any modules of interest are loaded, if so, you can then kill the process.

Jason Miesionczek
It looks like I get a "NotSupportedException" on the second line - "Feature is not supported for remote machines", though it works like a champ locally. Any ideas about another method that would work on a remote machine?
rwmnau