Click here to Skip to main content
15,888,968 members
Please Sign up or sign in to vote.
5.00/5 (1 vote)
See more:
Hello Everyone,

I am looking for a way to grab the loaded assemblies of a running process.

I have found it is possible to get the list of assembly from the current running process via:

C#
public static void PrintAssemblies()
{
  var assemblies = AppDomain.CurrentDomain.GetAssemblies();
  foreach (var assembly in assemblies)
  {
    Console.WriteLine(assembly.GetName());
  }
}


This works well but I cannot use it directly via a list of Processes like for example:

C#
Process[] Processes = Process.GetProcesses();

foreach (Process Proc in Processes)
{
  Console.WriteLine("{0}", Proc.ProcessName);
  Console.WriteLine("------------------------");

  foreach (var assembly in Proc.[assemblies])  // Ideally
  {
    Console.WriteLine(assembly.GetName());
  }

  /*

  This iteration is only prompting a few dll but not the .net assemblies 
  I have referenced to this process.

  foreach (ProcessModule ProcMod in Proc.Modules)
  {
    Console.WriteLine("{0}", ProcMod.ModuleName);
  }

  */
}


As results, I only get:
dllhost
------------------------
DllHost.exe
ntdll.dll
wow64.dll
wow64win.dll
wow64cpu.dll


Where I would expect:
C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System\v4.0_4.0.0.0__b77a5c561934e089
\System.dll
mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
ListofDomains, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
log4net, Version=1.2.13.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a
System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f1
1d50a3a
System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089


Do you think there is a way to cover my expectation.
I can see all the assemblies happily via procexp.exe.
There should then be a way to proceed I assume.

Thank you very much in advance.
Best regards.

SuperMiQi
Posted
Updated 5-Feb-15 7:18am
v2
Comments
Sergey Alexandrovich Kryukov 5-Feb-15 13:51pm    
Do you understand that you will have different kinds of processes, not only .NET ones? Just checking...
—SA

1 solution

This is pretty simple, but you need to understand that not all processed are related to .NET. You have been close but probably missed one simple thing: assemblies are made of modules; and a PE file represents not an assembly, but an assembly module. Moreover, even though Visual Studio does not directly support it, the assemblies can be made of more than one module, only one of them representing the assembly via its assembly manifest, main module. So, you need to filter out all other modules (which may or may not be the modules with assembly manifest) and then get to assemblies.

Armed with this understanding, you can easily dig into modules. First, you get modules of each of your process:
https://msdn.microsoft.com/en-us/library/system.diagnostics.process.modules%28v=vs.110%29.aspx[^].

For each module, you can get its file name. Note that this is a different class from assembly Module. This is because ProcessModule has to implement all executable modules, not only .NET ones:
https://msdn.microsoft.com/en-us/library/system.diagnostics.processmodule%28v=vs.110%29.aspx[^],
https://msdn.microsoft.com/en-us/library/system.diagnostics.processmodule.filename(v=vs.110).aspx[^].

Now, pretend that this module is a main module of some assembly and try to interpret is like this. Be ready to handle exceptions. Even though the assembly is already loaded in that detected process, you have to load (try to load) it again, in another process: you executing process:
https://msdn.microsoft.com/en-us/library/1009fa28(v=vs.110).aspx[^] (don't mix-up Assembly.LoadFrom and Assembly.Load; you don't need the second one).

You can load only for reflection: https://msdn.microsoft.com/en-us/library/system.reflection.assembly.reflectiononlyloadfrom%28v=vs.110%29.aspx[^].

Now when you get to the instance of the System.Assembly of some detected process (in case of successful load), you can continue your search with it:
https://msdn.microsoft.com/en-us/library/system.reflection.assembly%28v=vs.110%29.aspx[^],
get loaded modules: https://msdn.microsoft.com/en-us/library/4t888ytw(v=vs.110).aspx[^],
referenced assemblies: https://msdn.microsoft.com/en-us/library/system.reflection.assembly.getreferencedassemblies(v=vs.110).aspx[^],
see also: https://msdn.microsoft.com/en-us/library/43wc4hhs%28v=vs.110%29.aspx[^].

If you really need actually loaded assemblies, don't confuse them with referenced assemblies. Some referenced assemblies may be not loaded, and some assembly can be loaded dynamically without referencing. So, you rather need to get to all loaded modules (see the link above, this time, these are not process modules (ProcessModule) but instances of System.Reflection.Module. Look at the assembly of each:
https://msdn.microsoft.com/en-us/library/system.reflection.module%28v=vs.110%29.aspx[^],
https://msdn.microsoft.com/en-us/library/system.reflection.module.assembly(v=vs.110).aspx[^].

—SA
 
Share this answer
 
v3
Comments
SuperMiQi 6-Feb-15 4:46am    
Hello Sergey,

Thank you for you quick answer.
I tried that and this works pretty well for managed process.

When I try on unmanaged process with clr option, it does not show me the assemblies I have referenced.
This is what I am looking for.
Do you know if there is a way to get them ? Like procexp is doing.

Thank you very much in advance.
Best regards.
MiQi
Sergey Alexandrovich Kryukov 6-Feb-15 13:14pm    
There is no such thing as "assemblies referenced by unmanaged process". However, this case if very interesting. If you used CLR option, it could be the managed process, or it could be some mixed-mode (managed+unmanaged), which could present some problem. Now, my question is: did you collect modules (ProcessModule) for such process? What was on the list of such module? I supposed to have all modules, including those used in some assemblies. Maybe you did something in a bit different way. Could you show your relevant code sample?
—SA

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900