2012-01-29 3 views
15

Я разрабатываю программу на C#, которая будет загружать файлы и получать информацию, такую ​​как дата создания файла, дата изменения, размер и т. Д. Еще одна вещь, которую мне нужно знать, - это загруженный файл (executable.exe) связан с флагом LARGEADDRESSAWARE. Класс FileInfo не предоставляет эту информацию.Как проверить, установлен ли exe как LARGEADDRESSAWARE

Кто-нибудь знает, как в C# я могу узнать, связан ли данный исполняемый файл.exe с флагом LARGEADDRESSAWARE (для обработки адресов более 2 ГБ)?

+2

Пожалуйста, не префикса своих названий с «C#» и тому подобными. Для этого нужны теги. Кроме того, FYI, 'FileInfo' не является частью C#. Это часть .NET. –

+1

Он хранится в IMAGE_FILE_HEADER.Характеристики, бит IMAGE_FILE_LARGE_ADDRESS_AWARE: http://msdn.microsoft.com/en-us/library/windows/desktop/ms680313%28v=vs.85%29.aspx –

ответ

22

Вот какой код, который проверяет флаг Large Address Aware. Все, что вам нужно сделать, это передать поток, указывающий на начало исполняемого файла.

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

Большое спасибо за ваше обновление High. Это действительно решило мою проблему. Очень признателен. – harrygg

15

В MSDN documentation для /LARGEADDRESSAWARE состояний:

Если приложение было связано с/LARGEADDRESSAWARE, Dumpbin/HEADERS будет отображать информацию по этому вопросу.

Если вы ищете способ сделать это программно, вы можете вызвать dumpbin из своего приложения и проанализировать вывод.

Update:

Существует также хороший блог here, который обсуждает этот вопрос более подробно.

+0

[Этот ответ] (https : //stackoverflow.com/a/6777574/25507) содержит более подробную информацию об использовании dumpbin для проверки наличия большого адреса. –

1

От ответа Уиллы выше я использую следующий в моем 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; 
    } 
Смежные вопросы