как проверить, установлен ли exe как LARGEADDRESSAWARE - PullRequest
15 голосов
/ 29 января 2012

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

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

Ответы [ 3 ]

22 голосов
/ 30 января 2012

Вот некоторый код, который проверяет флаг «Большой адрес». Все, что вам нужно сделать, это передать поток, который указывает на начало исполняемого файла.

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;
}
15 голосов
/ 29 января 2012

Документация MSDN для /LARGEADDRESSAWARE гласит:

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

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

Обновление:

Есть также хороший блогсообщение здесь , в котором обсуждается проблема более подробно.

1 голос
/ 07 августа 2013

Из ответа Уилла, приведенного выше, в моем пакете установки 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;
    }
...