2011-02-17 9 views
7

Tengo un programa que necesita descubrir archivos DLL de complemento en su host.Escaneo de archivos DLL para ensamblados de .NET con una interfaz particular - ¡algunos archivos DLL arrojan R6034!

Lo hace al enumerar todas las DLL dentro de una ruta (bastante grande). Esta ruta incluye muchas cosas, incluidas las DLL nativas.

foreach (var f in Directory.EnumerateFiles(@"c:\Program Files", "*.dll", SearchOption.AllDirectories)) 
{ 
    try 
    { 
     var assembly = Assembly.LoadFile(f); 
     var types = assembly.GetTypes(); 
     foreach (var type in types) 
     { 
      if (type.GetInterface("My.IInterface") != null) 
      { 
       plugins.Add(f); 
       break; 
      } 
     } 
     assembly = null; 
    } 
    catch (Exception e) 
    { 
    } 
} 

Si el escáner realiza un DLL MS tiempo de ejecución (por ejemplo, msvcm80.dll) me sale un error de ejecución R6034 inalcanzable: "Una aplicación ha hecho un intento de cargar la biblioteca de tiempo de ejecución C incorrectamente." Esta ventana bloquea la ejecución del programa. No quiero esta DLL (obviamente); ¿Hay alguna forma de obtener un elegante error de esta situación?

[q relacionadas: ¿hay forma en que un eficiente (por ejemplo, no excepción) de determinar si un DLL es un ensamblado de .NET o no, si que DLL no está cargado actualmente en el espacio de proceso]

Respuesta

10

Primero haga una carga de solo reflexión con Assembly.ReflectionOnlyLoadFrom. Solo después de encontrar un complemento en el ensamblaje, debe cargarlo completamente con Assembly.LoadFrom.

Para responder a su otra pregunta, puede verificar si el archivo tiene un encabezado CLR.

See this post "Read CLR Header" on m.p.dotnet.framework

En conjunto, estos deben permitir eludir las posibles excepciones y los cuadros de mensajes de error durante la búsqueda de plugins.

+1

Interesante en ReflectionOnlyLoadFrom. Lástima que tiene las mismas limitaciones que solo cargar un ensamblaje de un nombre de pila en el dominio de la aplicación. Y el uso de un dominio de aplicación alternativo es aparentemente extraordinariamente doloroso; No pude encontrar a nadie que haya descrito con éxito cómo tomar otro dominio de aplicación, cargar ensamblajes con éxito (sin dictar tipos específicos) y luego interrogar las propiedades de esos ensamblajes. Bleah. – Joe

2

Doesn Parece una buena idea en \ Archivos de programa ... ¿Podría alguien poner archivos DLL maliciosos allí?

¿Ha mirado usando MEF? Puede ser un poco más seguro, también.

Hay un catálogo de directorios que cargará automáticamente los ensamblajes y le devolverá una matriz de su interfaz.

No estoy seguro de si está familiarizado con Dependency Injection o (IoC) Inversion of Control, pero también puede usar MEF para eso.

Se incluye en .Net 4.0.

+0

Interesante. Se ve prometedor, gracias. – Joe

+2

Ok, esto es ridículo. MEF muestra el mismo problema. Si le indica a MEF que use un DirectoryCatalog en un directorio que contiene bibliotecas de tiempo de ejecución de VC++, obtendrá la misma ventana emergente de R6034. (Además, DirectoryCatalog no admite la recursión de directorios, por lo que debe enumerar todos los directorios que desee de todos modos.) Me gusta la abstracción de MEF, pero desafortunadamente no resuelve el problema. – Joe

+0

¿Sabes si? 1) MEF carga todos los ensamblajes del catálogo dado y luego filtra los tipos dados o 2) llama al método Assembly.ReflectionOnlyLoad, filtra y luego carga? –

Cuestiones relacionadas