Как проверить, установлен ли exe как LARGEADDRESSAWARE
Я разрабатываю программу на С#, которая будет загружать файлы и получать информацию, такую как дата загрузки файла, дата изменения, размер и т.д. Еще одна вещь, которую мне нужно знать, заключается в том, связан ли загруженный файл (executable.exe
) с LARGEADDRESSAWARE
. Класс FileInfo не предоставляет эту информацию.
Кто-нибудь знает, как в С# я могу узнать, связан ли данный файл executable.exe с флагом LARGEADDRESSAWARE
(для обработки адресов более 2 ГБ)?
Ответы
Ответ 1
Вот некоторый код, который проверяет флаг 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;
}
Ответ 2
В документации MSDN для /LARGEADDRESSAWARE
указано:
Если приложение было связано с /LARGEADDRESSAWARE, DUMPBIN/HEADERS отобразит информацию об этом.
Если вы ищете способ сделать это программно, вы можете вызвать dumpbin из своего приложения и проанализировать вывод.
Update:
Здесь также есть хорошее сообщение в блоге , в котором более подробно рассматривается проблема.
Ответ 3
От ответа Ответ выше Я использую следующее в моем установочном пакете 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;
}