Estoy trabajando para migrar una aplicación web de 32 bits a 64 bits y tengo algunos problemas con nuestro código de cargador de complementos.Determinar si un dll es un dll CLR .valido leyendo directamente el PE (problema de 64 bits)
En la versión de 32 bits, escaneamos el directorio bin de webapps para todos los .net dlls, luego los cargamos con Assembly.Load
para verificar la presencia de nuestros atributos de plugin.
Hicimos esto de una manera bastante ingeniosa utilizando el código de dominio público:
/// <summary>
/// Returns true if the file specified is a real CLR type,
/// otherwise false is returned.
/// False is also returned in the case of an exception being caught
/// </summary>
/// <param name="file">A string representing the file to check for
/// CLR validity</param>
/// <returns>True if the file specified is a real CLR type,
/// otherwise false is returned.
/// False is also returned in the case of an exception being
/// caught</returns>
public static bool IsDotNetAssembly(String file)
{
Stream fs = new FileStream(@file, FileMode.Open, FileAccess.Read);
try
{
BinaryReader reader = new BinaryReader(fs);
//PE Header starts @ 0x3C (60). Its a 4 byte header.
fs.Position = 0x3C;
uint peHeader = reader.ReadUInt32();
//Moving to PE Header start location...
fs.Position = peHeader;
uint peHeaderSignature = reader.ReadUInt32();
ushort machine = reader.ReadUInt16();
ushort sections = reader.ReadUInt16();
uint timestamp = reader.ReadUInt32();
uint pSymbolTable = reader.ReadUInt32();
uint noOfSymbol = reader.ReadUInt32();
ushort optionalHeaderSize = reader.ReadUInt16();
ushort characteristics = reader.ReadUInt16();
// PE Optional Headers
// To go directly to the datadictionary, we'll increase the stream's current position to with 96 (0x60).
// 28 bytes for Standard fields
// 68 bytes for NT-specific fields
// 128 bytes DataDictionary
// DataDictionay has 16 directories
// 8 bytes per directory (4 bytes RVA and 4 bytes of Size.)
// 15th directory consist of CLR header! (if its 0, it is not a CLR file)
uint[] dataDictionaryRVA = new uint[16];
uint[] dataDictionarySize = new uint[16];
ushort dataDictionaryStart = Convert.ToUInt16(Convert.ToUInt16(fs.Position) + 0x60);
fs.Position = dataDictionaryStart;
for (int i = 0; i < 15; i++)
{
dataDictionaryRVA[i] = reader.ReadUInt32();
dataDictionarySize[i] = reader.ReadUInt32();
}
if (dataDictionaryRVA[14] == 0)
{
fs.Close();
return false;
}
else
{
fs.Close();
return true;
}
}
catch (Exception)
{
return false;
}
finally
{
fs.Close();
}
}
Ahora el problema es que ahora tenemos que manejar 64 bits o plataforma DLL independientes y el desplazamiento parece haber cambiado y no logra este código . ¿Alguien sabe las modificaciones correctas en el código anterior para que sea verdadero solo para 64 bits válidos O dlls independientes de plataforma?
¿De verdad tienes que usar el código de arriba? – Hans
Nifty? Más como implementación específica, creación de suposiciones y obligado a meterse en problemas ... oh, sí, ya lo hizo. :) – bzlm
la aplicación web es enorme, con más de 100 dlls en el directorio bin. Muchos de los dlls no son complementos para nuestra aplicación y muchos no son clr dlls, por lo que usar Assembly.Load no es una buena opción. – Vaevictus