How to programatically set or clear the 32BIT flag?

霸气de小男生 提交于 2019-12-21 18:08:27

问题


When compiling, I always set it for Any CPU. However there are some customers that do not have a 64 bit version of a required binary, even when running on an x64 system. In these instances I have asked them to modify my binary with the corflags.exe /32BIT+ option:

http://msdn.microsoft.com/en-us/library/ms164699(VS.80).aspx

I would like to make this transparent and modify the binary myself during installation time if the 64 bit version is not present. I would prefer not to make a call to corflags.exe myself as that would mean I would need to redistribute the application which is not allowed as part of our shipping requirements.

So my question is; is there any way to modify this flag programatically myself, or alternatively to modify the binary directly (is it just setting a byte somewhere in the file itself)?


回答1:


Why not just build your assemblies for both architectures (32-bit and 64-bit) specifically, include both in your installer, and then at install time, detect which version of this dependent assembly your client has and then install the appropriate architecture version of your application. This way there's no messing around modifying binaries manually or needing to include corflags in your installer.




回答2:


I have not tried this however are you able to run corflags on a copy of the binary and do a binary diff to determine what offset was modified. You could do this as a build action of your install script and store the offset with the installer.

At install time just alter the offset that if needed.

Of course I would never endorse such actions, just sayin'

;-)

As an aside, if you are continually needing to mark the assembly for 32bit you may consider just targeting that platform instead of altering it as 32bit after the fact.

Cheers.




回答3:


For the file itself, I believe (haven't confirmed) you could just modify the IMAGE_COR20_HEADER yourself. Just setting MinorRuntimeVersion should do the trick. Here is an (somewhat outdated) explanation on how the IMAGE_COR20_HEADER is used for determining which runtime is loaded: http://blogs.msdn.com/joshwil/archive/2004/10/15/243019.aspx

Why not just always compile for x86, does the 64bit runtime give you any benefit?

Note that some code (interop/P/invoke) will only work in either 32 or 64 bit runtime, so just loading the same assembly into another runtime won't work.

Edit: quick and dirty sample to read 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));

Not convinced it's a good idea doing this as an installer step though.




回答4:


If you can detect this during the install, why not just run corflags.exe from the installer directly? This sounds much better to me, rather than trying to alter the binary data myself.



来源:https://stackoverflow.com/questions/937206/how-to-programatically-set-or-clear-the-32bit-flag

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!