In the Adobe Forums I saw this question
AIR 29 on Windows: Detecting if 64 bit runtime
and yeah sure OK the question is valid so let's write about the different behaviour of 32-bit and 64-bit under Windows
You deal with 3 things
- the processor or CPU
- the operating system or OS
- the program itself
with that general rule that when you are 64-bit you can execute both 32-bit and 64-bit,
but then you are 32-bit you can only execute 32-bit.
You could have a 64-bit CPU executing a 32-bit OS
as well as a 64-bit OS executing a 32-bit program
Under Windows to detect if you are a 32-bit or 64-bit OS
You can use PROCESSOR_ARCHITECTURE
environment variable that reports the native processor architecture (except for WOW64).
C:/> echo %PROCESSOR_ARCHITECTURE%
IA64
stands for "Intel Architecture 64" or IA-64
see HOWTO: Detect Process Bitness
In an ideal world you would have 64-bit programs running on 64-bit OS: the AMD64
value
or 32-bit programs runnign on 32-bit OS: the x86
value, but under Windows you can have
a special case where you have a legacy 32-bit program running on a 64-bit OS, this is
the WOW64 case, eg. "Windows 32-bit on Windows 64-bit".
For WOW64, you also have to use the PROCESSOR_ARCHITEW6432
environment variable
which reports the original native processor architecture (only for WOW64).
In pseudo-code
if( (PROCESSOR_ARCHITECTURE == "AMD64") || (PROCESSOR_ARCHITEW6432 == "AMD64") )
{
// OS is 64-bit
}
else
{
// OS is 32-bit
}
or the opposite
if( (PROCESSOR_ARCHITECTURE == "x86") || (PROCESSOR_ARCHITEW6432 == "") )
{
// OS is 32-bit
}
else
{
// OS is 64-bit
}
And in Adobe AIR you will be able to use
Capabilities.supports32BitProcesses
and
Capabilities.supports64BitProcesses
that's the part that basically tell you what the operating system can do, but it does not tell you if the AIR runtime itself (your program) is either 32-bit or 64-bit.
eg. if you get a Capabilities.supports64BitProcesses = true
you can say that the OS is 64-bit.
So let's say you produce an AIR 64-bit app and you try to run it under a 32-bit OS
you will get that error

this just to say that when you publish your app you should clearly mark it as 32-bit or 64-bit.
Now, the real problem is when the user have a 64-bit OS and either downloaded your 32-bit or 64-bit app and within your app you want to know which one you are so you can allocate more or less resources.
Well... for that part we gonna need to do it ourselves because so far there is no API in AIR that can tell us if the runtime itself is 32-bit or 64-bit.
Luckily, under Windows, all executables follow the Portable Executable format or PE Format
The Portable Executable (PE) format is a file format for executables, object code, DLLs, FON Font files, and others used in 32-bit and 64-bit versions of Windows operating systems. The PE format is a data structure that encapsulates the information necessary for the Windows OS loader to manage the wrapped executable code.
Here the layout
Basically what we want to do is to load the program exe into a ByteArray
and parse it in such a way we can get informations about the executable.
here the PDF:
PE Format Walkthrough.pdf (504.0 KB)
found on http://blog.dkbza.org/
here a basic test class that demo how to do it
the gut of the thing is
private function _parsePE():void
{
var air_exe:String = _getAIRExecutable();
var air_file:File = File.applicationDirectory;
air_file = air_file.resolvePath( air_exe );
if( air_file.exists )
{
const AMD64:uint = 0x8664;
const I386:uint = 0x014c;
var fs:FileStream = new FileStream();
fs.endian = Endian.LITTLE_ENDIAN;
fs.open( air_file, FileMode.READ );
trace( "endian = " + fs.endian );
trace( "bytesAvailable = " + fs.bytesAvailable );
trace( "position = " + fs.position );
// MZ magic number
var peMZ:int = fs.readShort(); // 0x5a4d - MZ
trace( "peMZ = " + peMZ + " - 0x" + hex(peMZ,2) );
// PE Header offset is always at 0x3C
fs.position = 0x3c;
trace( "position = " + fs.position );
var peOffset:int = fs.readShort();
trace( "peOffset = " + peOffset + " - 0x" + hex(peOffset,2) );
fs.position = peOffset;
// PE Header Signature is always PE\0\0
var peHead:uint = fs.readUnsignedInt(); // 0x00004550 - PE\0\0
trace( "peHead = " + peHead + " - 0x" + hex(peHead,8) );
/*
public enum MachineType : ushort
{
IMAGE_FILE_MACHINE_UNKNOWN = 0x0,
IMAGE_FILE_MACHINE_AM33 = 0x1d3,
IMAGE_FILE_MACHINE_AMD64 = 0x8664,
IMAGE_FILE_MACHINE_ARM = 0x1c0,
IMAGE_FILE_MACHINE_EBC = 0xebc,
IMAGE_FILE_MACHINE_I386 = 0x14c,
IMAGE_FILE_MACHINE_IA64 = 0x200,
IMAGE_FILE_MACHINE_M32R = 0x9041,
IMAGE_FILE_MACHINE_MIPS16 = 0x266,
IMAGE_FILE_MACHINE_MIPSFPU = 0x366,
IMAGE_FILE_MACHINE_MIPSFPU16 = 0x466,
IMAGE_FILE_MACHINE_POWERPC = 0x1f0,
IMAGE_FILE_MACHINE_POWERPCFP = 0x1f1,
IMAGE_FILE_MACHINE_R4000 = 0x166,
IMAGE_FILE_MACHINE_SH3 = 0x1a2,
IMAGE_FILE_MACHINE_SH3DSP = 0x1a3,
IMAGE_FILE_MACHINE_SH4 = 0x1a6,
IMAGE_FILE_MACHINE_SH5 = 0x1a8,
IMAGE_FILE_MACHINE_THUMB = 0x1c2,
IMAGE_FILE_MACHINE_WCEMIPSV2 = 0x169,
}
*/
// 2-byte machine type
var machineType:uint = fs.readUnsignedShort();
trace( "machineType = " + machineType + " - 0x" + hex(machineType,4) );
if( machineType == AMD64 )
{
trace( "AIR is 64-bit" );
_is64bit = true;
}
else if( machineType == I386 )
{
trace( "AIR is 32-bit" );
_is64bit = false;
}
else
{
trace( "AIR is UNKNOWN" );
_is64bit = false;
}
fs.close();
}
}
Simply put, you read the first 2-byte to verify the magic number is MZ
then you move to the offset 0x3c
to find the PE header offset
you move to that new offset and you read a uint32
to verify the PE header signature eg. PE\0\0
and then you read a 2-byte value which indicate the MachineType
of the executable
this machine type will indicate if the executable is either 32-bit (eg. 0x014c
for "I386")
or 64-bit (eg. 0x8664
for "AMD64")
and that's about it 