2009-01-16 9 views
15

¿Cómo puedo obtener la lista de todas las dependencias DLL de un archivo DLL o EXE dado?Cómo obtener relaciones DLL por programación

En otras palabras, me gustaría hacer lo mismo que la herramienta "Dependency walker", pero programáticamente.

¿Cuál es la API de Windows (idealmente .NET) para eso?

Respuesta

9

Puede usar la función EnumProcessModules. API administrada como kaanbardak sugerida no le dará una lista de módulos nativos.

Por ejemplo, véase this page en MSDN

Si es necesario analizar estáticamente el archivo DLL que tiene que cavar en PE format y aprender acerca de las tablas de importación. Vea esto excellent tutorial para más detalles.

+0

Correcto, pero puede usarlo solo en un proceso de ejecución. – sthiers

+0

Si desea analizar dll sin cargarlo, entonces necesita leer su tabla de importación – aku

+0

Desafortunadamente, el enlace al excelente tutorial está muerto. –

4

NOTA: Basado en los comentarios del post de abajo, supongo que esto podría perderse dependencias no administrados, así porque se basa en la reflexión.

Aquí es un pequeño programa en C# escrito por Jon Skeet de bytes.com en un .NET Dependency Walker

using System; 
using System.Reflection; 
using System.Collections; 

public class DependencyReporter 
{ 
    static void Main(string[] args) 
    { 
     //change this line if you only need to run the code one: 
     string dllToCheck = @""; 

     try 
     { 
      if (args.Length == 0) 
      { 
       if (!String.IsNullOrEmpty(dllToCheck)) 
       { 
        args = new string[] { dllToCheck }; 
       } 
       else 
       { 
        Console.WriteLine 
         ("Usage: DependencyReporter <assembly1> [assembly2 ...]"); 
       } 
      } 

      Hashtable alreadyLoaded = new Hashtable(); 
      foreach (string name in args) 
      { 
       Assembly assm = Assembly.LoadFrom(name); 
       DumpAssembly(assm, alreadyLoaded, 0); 
      } 
     } 
     catch (Exception e) 
     { 
      DumpError(e); 
     } 

     Console.WriteLine("\nPress any key to continue..."); 
     Console.ReadKey(); 
    } 

    static void DumpAssembly(Assembly assm, Hashtable alreadyLoaded, int indent) 
    { 
     Console.Write(new String(' ', indent)); 
     AssemblyName fqn = assm.GetName(); 
     if (alreadyLoaded.Contains(fqn.FullName)) 
     { 
      Console.WriteLine("[{0}:{1}]", fqn.Name, fqn.Version); 
      return; 
     } 
     alreadyLoaded[fqn.FullName] = fqn.FullName; 
     Console.WriteLine(fqn.Name + ":" + fqn.Version); 

     foreach (AssemblyName name in assm.GetReferencedAssemblies()) 
     { 
      try 
      { 
       Assembly referenced = Assembly.Load(name); 
       DumpAssembly(referenced, alreadyLoaded, indent + 2); 
      } 
      catch (Exception e) 
      { 
       DumpError(e); 
      } 
     } 
    } 

    static void DumpError(Exception e) 
    { 
     Console.ForegroundColor = ConsoleColor.Red; 
     Console.WriteLine("Error: {0}", e.Message); 
     Console.WriteLine(); 
     Console.ResetColor(); 
    } 
} 
+1

Este código no mostrará los módulos no administrados. Mono.Cecil sería una solución mucho mejor para el código administrado porque no requiere que cargue ensamblados en AppDomain (y no puede descargar el ensamblaje más adelante) – aku

+0

Prueba/captura extra añadida, si un ensamblaje falla, los demás deberían estar en la lista. Se agregó un color a la excepción y una entrada para que sea más fácil de leer. Se agregó un campo de cadena para cuando solo desea ejecutar un F5 para una descripción general rápida (es más fácil que agregarlo a la configuración de compilación). –

1

Para obtener dependencias de módulos nativos, creo que debería estar bien para conseguirlo de la importación del archivo PE mesa, aquí hay 2 enlaces que explican que en profundidad:

http://msdn.microsoft.com/en-us/magazine/bb985992.aspx

http://msdn.microsoft.com/en-us/magazine/cc301808.aspx

Para obtener dependencias de .NET, podemos usar API de .NET, como Assembly.Load.

Para obtener todas las dependencias de un módulo .NET, ¿qué tal combinar las 2 formas? Los ensamblados .NET son solo archivos PE con metadatos.

-1

Para leer los archivos DLL (módulos) cargados por un ejecutable, utilice las funciones ToolHelp32 Tool help Documentation on MSDN.

No estoy seguro de lo que mostrará para .Net ejecutando exe (nunca lo he probado). Pero, muestra la ruta completa desde donde se cargaron las DLL. A menudo, esta era la información que necesitaba al tratar de resolver los problemas de DLL. Se supone que .Net eliminó la necesidad de usar estas funciones (busque DLL Hell para más información).

1

Si bien esta pregunta ya tiene una respuesta aceptada, la documentación a la que se hace referencia en las otras respuestas, donde no está rota, es antigua. En vez de leer a través de toda ella sólo para descubrir que no cubre las diferencias entre Win32 y x64, u otras diferencias, mi enfoque era la siguiente:

C:\UnxUtils\usr\local\wbin>strings.exe E:\the-directory-I-wanted-the-info-from\*.dll > E:\TEMP\dll_strings.txt 

Esto me permitió utilizar Notepad ++ o gvim o lo que sea para buscar dlls que seguían dependiendo de dlls de MS con 120.dll al final del nombre dll para poder encontrar los que necesitaban actualización.

Esto podría escribirse fácilmente en su idioma favorito.

Dado que mi búsqueda de esta información fue con VS 2015 en mente, y esta pregunta fue el resultado principal de una búsqueda en Google, proporcioné esta respuesta que tal vez pueda ser útil para otra persona que viene a buscar la la misma cosa.

Cuestiones relacionadas