Как программно установить или снять флаг 32BIT?
При компиляции я всегда устанавливал его для любого процессора. Однако есть клиенты, у которых нет 64-битной версии необходимого двоичного файла, даже при работе в системе x64. В этих случаях я попросил их изменить мой двоичный файл с помощью параметра corflags.exe /32BIT+:
http://msdn.microsoft.com/en-us/library/ms164699(VS.80).aspx
Я хотел бы сделать это прозрачным и изменить двоичный файл самостоятельно во время установки, если 64-разрядная версия отсутствует. Я бы предпочел не делать вызов corflags.exe самостоятельно, так как это означало бы, что мне нужно будет распространять приложение, которое не разрешено в рамках наших требований к доставке.
Итак, мой вопрос: Есть ли способ изменить этот флаг сам программно, или в качестве альтернативы, чтобы изменить двоичный файл напрямую (это просто установка байта где-то в самом файле)?
4 ответа
Почему бы просто не собрать свои сборки специально для обеих архитектур (32-разрядной и 64-разрядной), включить их в установщик, а затем во время установки определить, какая версия этой зависимой сборки установлен на вашем клиенте, а затем установить соответствующую версию архитектуры ваше приложение. Таким образом, нет необходимости возиться с модификацией двоичных файлов вручную и не нужно включать corflags в ваш установщик.
Я не пробовал это, однако вы можете запустить corflags на копию двоичного файла и сделать двоичный разност, чтобы определить, какое смещение было изменено. Вы можете сделать это как действие сборки вашего установочного скрипта и сохранить смещение с помощью установщика.
Во время установки просто измените смещение, если это необходимо.
Конечно, я бы никогда не одобрил такие действия, просто сказал
;-)
Кроме того, если вам постоянно нужно пометить сборку для 32-битной, вы можете рассмотреть возможность нацеливания на эту платформу, а не изменять ее как 32-битную после факта.
Приветствия.
Я считаю, что для самого файла (не подтвердили) вы можете просто изменить IMAGE_COR20_HEADER самостоятельно. Просто установка MinorRuntimeVersion должна сделать свое дело. Вот (несколько устаревшее) объяснение того, как IMAGE_COR20_HEADER используется для определения того, какая среда выполнения загружена: http://blogs.msdn.com/joshwil/archive/2004/10/15/243019.aspx
Почему бы не всегда компилировать для x86, дает ли 64-битная среда выполнения какую-либо выгоду?
Обратите внимание, что некоторый код (interop/P/invoke) будет работать только в 32- или 64-битной среде выполнения, поэтому простая загрузка той же сборки в другую среду выполнения не будет работать.
Изменить: быстрый и грязный пример для чтения IMAGE_COR20_HEADER:
_pDosHeader = reinterpret_cast<PIMAGE_DOS_HEADER>(_pFileBase);
_pNTHeader = reinterpret_cast<PIMAGE_NT_HEADERS>(_pFileBase + _pDosHeader->e_lfanew);
_pFileHeader = reinterpret_cast<PIMAGE_FILE_HEADER>(&_pNTHeader->FileHeader);
_pOptionalHeader = reinterpret_cast<PIMAGE_OPTIONAL_HEADER>(&_pNTHeader->OptionalHeader);
IMAGE_DATA_DIRECTORY const* entry = NULL;
entry = &pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_COMHEADER];
if (entry->VirtualAddress == 0 || entry->Size == 0 || entry->Size < sizeof(IMAGE_COR20_HEADER)) {
return E_FAIL;
}
pClrHeader = reinterpret_cast<IMAGE_COR20_HEADER*>(RtlImageRvaToVa32(_pNTHeader, _pFileBase, entry->VirtualAddress, 0));
Не уверен, что это хорошая идея сделать это как шаг установщика.
Если вы можете обнаружить это во время установки, почему бы просто не запустить файл corflags.exe непосредственно из установщика? Для меня это звучит намного лучше, чем пытаться изменить двоичные данные самостоятельно.