2

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
            }
NightsEVil
  • 507
  • 2
  • 13
  • 21
  • 1
    possible duplicate of [How to detect Windows 64 bit platform with .net?](http://stackoverflow.com/questions/336633/how-to-detect-windows-64-bit-platform-with-net) – Thorarin Jun 08 '10 at 05:15
  • 2
    Don't assume that Windows will always be installed to C:\Windows\ folder. – Nimesh Madhavan Jun 08 '10 at 05:17
  • so I guess it's ok if I do this: if (Directory.Exists(Environment.GetEnvironmentVariable("SystemRoot") + "\\SysWow64")) //In this case we deal with 64 bit OS – Koen Oct 26 '12 at 14:44

7 Answers7

6

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
  • 33,369
  • 7
  • 73
  • 84
  • `Win32Native` is an internal class however, and `DoesWin32MethodExist` appears to be new in .NET 4.0. – Thorarin Jun 08 '10 at 05:20
  • 1
    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 Jun 08 '10 at 05:23
  • 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 Jun 08 '10 at 05:38
  • 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 Jun 08 '10 at 20:13
4

None of the following is original content (I will cite as best I can) but will help aggregate info on this situation.

If you're using .Net 4 or higher, stop reading now. This is built into the framework (check out System.Environment.get_is64bitoperatingsystem)

For all else, there are a number of options I've come across along the way.

Solution 1: Compile Time Directives

Raymond Chen's MSDN Blog: http://blogs.msdn.com/b/oldnewthing/archive/2005/02/01/364563.aspx

BOOL Is64BitWindows()
{
#if defined(_WIN64)
 return TRUE;  // 64-bit programs run only on Win64
#elif defined(_WIN32)
 // 32-bit programs run on both 32-bit and 64-bit Windows
 // so must sniff
 BOOL f64 = FALSE;
 return IsWow64Process(GetCurrentProcess(), &f64) && f64;
#else
 return FALSE; // Win64 does not support Win16
#endif
}

Credits For this solution: @Thorarin points to a dup. thread where Stefan Schultze links to this article. I'm not sure that the thread is a dupe though. The author specifically says that he is checking the OS platform. I'm not sure that the intent is to discover if your application is running in 32bit or 64bit mode.

Solution 2: Pointer Observations I'll defer to @Max for this one and just add the following MSDN article for extra reading: http://msdn.microsoft.com/en-us/library/system.intptr.size.aspx The bit to know: Pointer size on 32bit = 4, on 64bit = 8.

Give the man a point!

Solution 3: Using WinAPI - AKA - To hell w/ .Net, I'll find out my damn self! http://msdn.microsoft.com/en-us/library/ms684139(v=vs.85).aspx

BOOL WINAPI IsWow64Process(
  __in   HANDLE hProcess,
  __out  PBOOL Wow64Process
);

Notes: There are hacks such as looking for "Program Files(x86)", or looking at your processor architecture flags.
The issues with these methods are that

  1. They rely on common folder names that may not hold in "custom" installations
  2. The processor's x64 flag will not always reflect your current runtime state. Are you guaranteed to have compiled for "Any CPU"? Running a 32bit OS on a 64bit processor? etc.

Ideally you should not rely on external indicators and instead look for cues within the current appdomain. We want all solutions (whenever possible) to be bombproof.

JFish222
  • 1,026
  • 7
  • 11
3

If you like text,

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

That will return either x86 or AMD64.

sholsapp
  • 15,542
  • 10
  • 50
  • 67
  • how can that be turned into a "if x64" do this else do that? – NightsEVil Jun 08 '10 at 07:11
  • This reflects the processor architecture and not the run-time state of the app domain. Please see the "Notes" section of my post in this thread. [Direct Link](http://stackoverflow.com/a/10807723/1195927) – JFish222 Jan 31 '13 at 02:40
2

You can determine that the current operating system is 64 bit OS or not. In .NET Framework 4 there is one function Is64BitOperatingSystem is available to check that current operating system is a 64-bit operating system.

   if (System.Environment.Is64BitOperatingSystem == true)
    {
        Response.Write("This is 64 Bit Operating System.");
    }
    else
    {
        Response.Write("This is not 64 Bit Operating System.");
    }
Bill the Lizard
  • 398,270
  • 210
  • 566
  • 880
Jayesh Sorathia
  • 1,596
  • 15
  • 16
1

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

Chinjoo
  • 2,697
  • 6
  • 28
  • 45
  • 3
    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 Jun 08 '10 at 05:11
  • 1
    It determines if process is 32 or 64 bit, not OS. 64 bit OS can run both. – max Jun 08 '10 at 05:11
0

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
  • 2,628
  • 22
  • 35
  • Processor architecture does not indicate the state of the current AppDomain (ie: 32 bit runtime on a 64 bit system.) – JFish222 Feb 04 '13 at 21:40
0

In VB.NET, What I wanted works like below.

Define the custom constant "Win64" in x64 all configurations (debug, release etc) as in the below diagram and use like

If (Win64) Then

   '64 bit code

else

   ' 32 bit code here

End If

enter image description here