...someplace, where there isn't any trouble? Do you suppose there is such a place, Toto?

Riffing on Dirkie

In einem seiner letzten Blogs hat Dirkie Code vorgestellt, der zur Laufzeit prüft, ob managed Code unter x64 Windows als 64-bit Prozeß zur Ausführung kommt oder aber als 32-bit Prozeß unter x86 Windows oder x64 Windows läuft. Der einfache Größenvergleich von IntPtr mit 8 hat mich stutzig gemacht und ich habe mir überlegt, ob man das mit P/Invoke irgendwie besser hinkriegen kann, denn der Ansatz liefert dasselbe Ergebnis zurück für alle 64 bit Plattformen, inklusive IA64 oder zukünftigen Plattformen (Can you say 64 bit Pocket PC?). Dabei bin ich auf das traditionelle GetSystemInfo zurückgekommen und so funktioniert's damit dann:

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;


namespace platformdetect
{
    enum PROCESSOR_ARCH
    {
        PROCESSOR_ARCHITECTURE_INTEL            = 0,
        PROCESSOR_ARCHITECTURE_MIPS             = 1,
        PROCESSOR_ARCHITECTURE_ALPHA            = 2,
        PROCESSOR_ARCHITECTURE_PPC              = 3,
        PROCESSOR_ARCHITECTURE_SHX              = 4,
        PROCESSOR_ARCHITECTURE_ARM              = 5,
        PROCESSOR_ARCHITECTURE_IA64             = 6,
        PROCESSOR_ARCHITECTURE_ALPHA64          = 7,
        PROCESSOR_ARCHITECTURE_MSIL             = 8,
        PROCESSOR_ARCHITECTURE_AMD64            = 9,
        PROCESSOR_ARCHITECTURE_IA32_ON_WIN64    = 10,
        PROCESSOR_ARCHITECTURE_UNKNOWN          = 0xFFFF
    }


    [StructLayout(LayoutKind.Sequential)]
    class SYSTEM_INFO
    {
        public ushort wProcessorArchitecture;
        public ushort wReserved;
        public uint dwPageSize;
        public IntPtr lpMinimumApplicationAddress;
        public IntPtr lpMaximumApplicationAddress;
        public IntPtr dwActiveProcessorMask;
        public uint dwNumberOfProcessors;
        public uint dwProcessorType;
        public uint dwAllocationGranularity;
        public ushort wProcessorLevel;
        public ushort wProcessorRevision;
    }

    class Program
    {

        [DllImport("kernel32.dll", CharSet = CharSet.Unicode, 
                CallingConvention = CallingConvention.Winapi,
                EntryPoint="GetSystemInfo")]
        private static extern void GetSystemInfo([In, 
                    MarshalAs(UnmanagedType.LPStruct)]
		    SYSTEM_INFO pSysInfo);

        public static ushort GetProcessorArchitecture()
		{
		    SYSTEM_INFO si = new SYSTEM_INFO();
		    GetSystemInfo(si);
		    return si.wProcessorArchitecture;
		}    
        
        static void Main(string[] args)
        {
            ushort uPA = GetProcessorArchitecture();
            string[] platforms = {"x86", "MIPS", "Alpha", 
              "Power PC", "SHX", "ARM", "Itanium", 
              "Alpha 64", "MS intermediate Language", 
              "AMD64", "x86 on Itanium"};
            string strPlatform = "";

            try
            {
                strPlatform = platforms[uPA];
            }
            catch (System.IndexOutOfRangeException e)
            {
                strPlatform = "Unknown";
            }    
            Console.WriteLine("Platform is {0}", strPlatform);
            SYSTEM_INFO si = new SYSTEM_INFO();
            Console.WriteLine("SYSTEM_INFO size is {0} bytes", 
              System.Runtime.InteropServices.Marshal.SizeOf(si));
            Console.ReadKey();
        }
    }
}

Und beim nachschauen, was die Trackback URL von Dirkies Beitrag war, muss ich feststellen, daß Dirkie mit einem Link hierher
das Ganze als "wie es nicht gemacht werden sollte" abtut. Ich finde, damit tut man dieser zugegebenermassen etwas aufwendigeren Variante Unrecht, aber ich denke auch, daß man diese Lösung hier keinesfalls in einer innermost loop verwenden sollte. Aber einmal am Anfang des Programms tut das sicherlich nicht weh...

(Edited 03/11/2006: Oops, Testcode für die IndexOutOfRangeException entfernt)

Trackback address for this post

This is a captcha-picture. It is used to prevent mass-access by robots.
Please enter the characters from the image above. (case insensitive)

2 comments

Comment from: dirk [Visitor]
dirkich hatte glaube ich in einem Udate auch hier rauf verwiesen ?

http://msdn2.microsoft.com/en-us/library/ms229660.aspx

Soviel zu meiner Verteidigung, wobei die Bestimmung der Plattform garnicht im Fokus war ;-).
03/11/06 @ 19:26
Comment from: Stefan [Visitor]
StefanHabe ich gesehen, aber da ist keine aequivalente Plattformbestimmung wie mit dem GetSystemInfo API drin.
03/11/06 @ 23:17

Comments are closed for this post.