tags:

views:

403

answers:

5

hi i have this little snippet of code i wrote that checks to see if a folder is present (only exists in x64) if so it does "X" commands, if not (i.e x86) does "Z" commands (x,Z are just markers for code) but what i wanna know is there a better or more reliable way to do this using only the 2.0 .net Framework?

string target = @"C:\Windows\SysWow64";
        {
            if (Directory.Exists(target))
            {
                //do x64 stuff
            }
            else
            {
                 //do x86 stuff
            }
A: 

Raymond Chen covered a solution in his blog post:

http://blogs.msdn.com/b/oldnewthing/archive/2005/02/01/364563.aspx

Paul Kearney - pk
A pretty useless answer since the majority of Raymond Chen's post assumes a native code compiler that is targetting either 32 or 64 bit AT COMPILE TIME and uses conditional compilation and target architecture defines. The question is posed specifically for .NET framework, where the "compilation" does not necessarily determine target CPU architecture so runtime code must be provided to dynamically detect the runtime environment. The only part of Raymonds post that is relevant is the tip to use IsWOW64Process. Surely far more helpful to link to that directly?
Deltics
@Deltics: Fair enough, but I wasn't trying to be a "smart ass". I was simply trying to point the poster to a solution that shows the use of IsWow64Process. I'll accept that it's not a solution for .Net, but I certainly wasn't trying to be a smart ass.
Paul Kearney - pk
@Deltics: not quite true. It uses conditional compilation to determine whether the code is 64-bit code, in which case it will not run on a 32-bit OS, so it can simply be assumed that the OS is 64-bit. In other cases it makes a call to `IsWow64Process` to determine whether the code runs on 64-bit OS or not. The compiler condition for 64-bit is necessary since `IsWow64Process` returns false if it is a 64-bit code running on 64-bit windows.
Fredrik Mörk
+1  A: 

You can use the IntPtr.Size property. Its value is 4 for 32 bit and 8 for 64 bit.

Chinjoo
I think that will return the correct size based on the version of the .Net Framework that is running, but not the OS. IOW, it will return 4 if you are running on 32-bit framework on a 64-bit OS.
Paul Kearney - pk
It determines if process is 32 or 64 bit, not OS. 64 bit OS can run both.
max
+1  A: 

If you like text,

Console.WriteLine(System.Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE"));

That will return either x86 or AMD64.

gnucom
how can that be turned into a "if x64" do this else do that?
NightsEVil
and that shows x86 on my x64 laptop..
NightsEVil
+3  A: 

You can use Reflector to look how it is implemented in FW 4.0:

[DllImport("kernel32.dll", CharSet=CharSet.Ansi, SetLastError=true, ExactSpelling=true)]
private static extern IntPtr GetProcAddress(IntPtr hModule, string methodName);

[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail), DllImport("kernel32.dll", CharSet=CharSet.Auto, SetLastError=true)]
private static extern IntPtr GetModuleHandle(string moduleName);

[DllImport("kernel32.dll", CharSet=CharSet.Auto, SetLastError=true)]
internal static extern IntPtr GetCurrentProcess();

[SecurityCritical]
internal static bool DoesWin32MethodExist(string moduleName, string methodName)
{
   IntPtr moduleHandle = GetModuleHandle(moduleName);
   if (moduleHandle == IntPtr.Zero)
   {
       return false;
   }
   return (GetProcAddress(moduleHandle, methodName) != IntPtr.Zero);
}

[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("kernel32.dll", SetLastError=true)]
internal static extern bool IsWow64Process([In] IntPtr hSourceProcessHandle, [MarshalAs(UnmanagedType.Bool)] out bool isWow64);

[SecuritySafeCritical]
public static bool get_Is64BitOperatingSystem()
{
    bool flag;
    return (IntPtr.Size == 8) ||
        ((DoesWin32MethodExist("kernel32.dll", "IsWow64Process") &&
        IsWow64Process(GetCurrentProcess(), out flag)) && flag);
}

It checks if IsWow64Process() function exists, and calls it.

Update: added all functions used by get_Is64BitOperatingSystem()

Update2: fixed for 64-bit process

max
`Win32Native` is an internal class however, and `DoesWin32MethodExist` appears to be new in .NET 4.0.
Thorarin
All this API tells you is whether your 32-bit application is running in WOW64. If you compile for application to be AnyCPU, on a 64-bit OS, it should be running as a 64-bit application and IsWow64() will return false.
Ants
Thanks for that. Reflector loaded 32-bit mscorlib.dll by default, so there is no check if is a 64-bit process. 64-bit version of mscorlib simply returns `true` in `get_Is64BitOperatingSystem()`. Corrected code for this case.
max
well this seemed to work for my get_Is64BitOperatingSystem().ToString();but how would this be used for a IF x64 then this else then that?
NightsEVil
A: 

You'll want to P/Invoke GetNativeSystemInfo(): http://msdn.microsoft.com/en-us/library/ms724340(v=VS.85).aspx

and look at the SYSTEM_INFO.wProcessorArchitecture field.

Ants