2012-01-29 9 views
15

Estoy desarrollando un programa C# que cargará archivos y obtendrá información como la fecha de creación del archivo cargado, la fecha de modificación, el tamaño, etc. Otra cosa que necesito saber es si el archivo cargado (executable.exe) está vinculado con la bandera LARGEADDRESSAWARE. La clase FileInfo no proporciona esta información.cómo comprobar si exe está configurado como LARGEADDRESSAWARE

¿Alguien sabe cómo en C# puedo averiguar si un ejecutable.exe dado está vinculado con el indicador LARGEADDRESSAWARE (para manejar direcciones de más de 2 GB)?

+2

Por favor no uses el prefijo sus títulos con "C#" y tal. Para eso son las etiquetas. Además, para su información, 'FileInfo' no es parte de C#. Es parte de .NET. –

+1

Se almacena en IMAGE_FILE_HEADER.Characteristics, IMAGE_FILE_LARGE_ADDRESS_AWARE bit: http://msdn.microsoft.com/en-us/library/windows/desktop/ms680313%28v=vs.85%29.aspx –

Respuesta

22

Aquí hay algunos códigos que comprueban si hay una bandera de dirección grande. Todo lo que tienes que hacer es pasar una secuencia que apunta al comienzo de un ejecutable.

IsLargeAware("some.exe"); 

static bool IsLargeAware(string file) 
{ 
    using (var fs = File.OpenRead(file)) 
    { 
     return IsLargeAware(fs); 
    } 
} 
/// <summary> 
/// Checks if the stream is a MZ header and if it is large address aware 
/// </summary> 
/// <param name="stream">Stream to check, make sure its at the start of the MZ header</param> 
/// <exception cref=""></exception> 
/// <returns></returns> 
static bool IsLargeAware(Stream stream) 
{ 
    const int IMAGE_FILE_LARGE_ADDRESS_AWARE = 0x20; 

    var br = new BinaryReader(stream); 

    if (br.ReadInt16() != 0x5A4D)  //No MZ Header 
     return false; 

    br.BaseStream.Position = 0x3C; 
    var peloc = br.ReadInt32();   //Get the PE header location. 

    br.BaseStream.Position = peloc; 
    if (br.ReadInt32() != 0x4550)  //No PE header 
     return false; 

    br.BaseStream.Position += 0x12; 
    return (br.ReadInt16() & IMAGE_FILE_LARGE_ADDRESS_AWARE) == IMAGE_FILE_LARGE_ADDRESS_AWARE; 
} 
+1

Muchas gracias por su actualización Alta. Eso realmente resolvió mi problema. Muy apreciado. – harrygg

15

Los MSDN documentation para /LARGEADDRESSAWARE estados:

Si una aplicación se vinculó con/LARGEADDRESSAWARE, DUMPBIN/headers mostrará la información a tal efecto.

Si está buscando una forma de hacerlo de manera programática, puede invocar dumpbin desde su aplicación y analizar el resultado.

Actualización:

También hay una buena entrada en el blog here que discute el tema con mayor profundidad.

+0

[Esta respuesta] (https : //stackoverflow.com/a/6777574/25507) tiene más detalles sobre el uso de dumpbin para comprobar la gran dirección consciente. –

1

De la respuesta de voluntad por encima estoy usando el siguiente en mi paquete de instalación x86:

static bool LargeAware(string file) { 
     using (var fs = File.Open(file, FileMode.Open, FileAccess.ReadWrite, FileShare.None)) { 
      bool b = LargeAware(fs); 
      fs.Close(); 
      return b; 
     } 
    } 

    const int IMAGE_FILE_LARGE_ADDRESS_AWARE = 0x20; 
    static bool LargeAware(Stream stream) { 

     var br = new BinaryReader(stream); 
     var bw = new BinaryWriter(stream); 

     if (br.ReadInt16() != 0x5A4D)  //No MZ Header 
      return false; 

     br.BaseStream.Position = 0x3C; 
     var peloc = br.ReadInt32();   //Get the PE header location. 

     br.BaseStream.Position = peloc; 
     if (br.ReadInt32() != 0x4550)  //No PE header 
      return false; 

     br.BaseStream.Position += 0x12; 
     long nFilePos = (int)br.BaseStream.Position; 
     Int16 nLgaInt = br.ReadInt16(); 
     bool bIsLGA = (nLgaInt & IMAGE_FILE_LARGE_ADDRESS_AWARE) == IMAGE_FILE_LARGE_ADDRESS_AWARE; 
     if (bIsLGA) 
      return true; 
     nLgaInt |= IMAGE_FILE_LARGE_ADDRESS_AWARE; 
     long nFilePos1 = bw.Seek((int)nFilePos, SeekOrigin.Begin); 
     bw.Write(nLgaInt); 
     bw.Flush(); 
     long nFilePos2 = br.BaseStream.Seek(nFilePos, SeekOrigin.Begin); 
     nLgaInt = br.ReadInt16(); 
     bIsLGA = (nLgaInt & IMAGE_FILE_LARGE_ADDRESS_AWARE) == IMAGE_FILE_LARGE_ADDRESS_AWARE; 
     return bIsLGA; 
    } 
Cuestiones relacionadas