2012-01-29 11 views
15

Sto sviluppando un programma C# che caricherà file e otterrà informazioni come data di creazione del file caricato, data di modifica, dimensione ecc. Un'altra cosa che devo sapere è se il file caricato (executable.exe) è collegato con il flag LARGEADDRESSAWARE. La classe FileInfo non fornisce queste informazioni.come controllare se exe è impostato come LARGEADDRESSAWARE

Qualcuno sa come in C# posso scoprire se un determinato eseguibile.exe è collegato con il flag LARGEADDRESSAWARE (per gestire indirizzi più grandi di 2 GB)?

+2

Si prega di non inserire il prefisso vostri titoli con "C#" e così via. Ecco a cosa servono i tag. Inoltre, FYI, 'FileInfo' non fa parte di C#. Fa parte di .NET. –

+1

È archiviato in IMAGE_FILE_HEADER.Caratteristiche, IMAGE_FILE_LARGE_ADDRESS_AWARE bit: http://msdn.microsoft.com/en-us/library/windows/desktop/ms680313%28v=vs.85%29.aspx –

risposta

22

Ecco un codice che controlla la presenza del flag Indirizzo grande. Tutto quello che devi fare è passare un flusso puntato all'inizio di un eseguibile.

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

Molte grazie per il tuo aggiornamento Alto. Questo ha davvero risolto il mio problema. Molto apprezzato. – harrygg

15

Le MSDN documentation per /LARGEADDRESSAWARE stati:

Se un'applicazione è stato collegato con/LARGEADDRESSAWARE, DUMPBIN/headers verranno visualizzate le informazioni in tal senso.

Se si sta cercando un modo per farlo in modo programmatico, è possibile richiamare il dumpbin dall'applicazione e analizzare l'output.

Aggiornamento:

C'è anche un buon post sul blog here che discute la questione in modo più approfondito.

+0

[Questa risposta] (https : //stackoverflow.com/a/6777574/25507) ha maggiori dettagli sull'utilizzo di dumpbin per verificare la presenza di grandi indirizzi. –

1

Dalla risposta di Will sopra Sto utilizzando il seguente nel mio pacchetto di installazione 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; 
    } 
Problemi correlati