I have read a few posts and SO questions about the meaning of 32-bit preferred flag. According to the MSDN post
The difference, then, between “Any CPU 32-bit preferred” and “x86” is
only this: a .NET application compiled to x86 will fail to run on an
ARM Windows system, but an “Any CPU 32-bit preferred” application will
run successfully.
Thus, it seems that there is no reason not to use this flag.
Why would someone ever prefer not to use this flag ?
There's a reason, there always is a reason, it resolved an ambiguity once 64-bit ARM processors became available. What did you mean when you changed the Platform Target to x86? Did you mean "should only run on x86 processors"? Or did you mean "should only run in 32-bit mode"?
The "Prefer 32-bit mode" option disambiguates it.
Related
I need to check if an executable programm compiled for 64 bit version or for 32 bit version on a Windows system.
I think this question is hard to answer, because a .NET executable in Windows contains code in two forms:
The first part is a native stub that brings in the system's available runtime (for older Windows systems, when the OS loader didn't natively recognize CLR assemblies). It can be either 32-bit or 64-bit, like other Windows applications. You can find out its target architecture by analyzing its PE header.
As you can tell, this is rather straightforward to determine. However, I suspect it may also be largely irrelevant for your use case (and for most use cases), because this first part does't contain the "useful" part of your program and is there primarily for legacy reasons.
The second part is the IL (bytecode) that will get JIT-compiled and then executed. This is the useful part, but this is largely platform agnostic when not running. It's the runtime JIT-generated code that becomes 32-bit or 64-bit.
Now, if the assembly is explicitly built using the x86 or x64 configuration, it will be marked as such and you can find out programmatically without running it whether it's going to be 32-bit or 64-bit.
However, if it's marked as AnyCPU (like most assemblies are, these days) you can't know beforehand what to expect from the JIT-compiled code. You can only really find out at runtime (by asking the environment or by comparing the size of IntPtr for example). Or you can make an educated guess - if your current program is running under 32-bit Windows (but determining this from unmanaged code may be unreliable), you definitely don't have to expect that a .NET assembly would generate 64-bit CPU instructions. However, if you're running under 64-bit Windows (again, the most likely scenario), it won't be that easy, especially considering that the semantics of the AnyCPU configuration changed with .NET 4.5 and you'll have to account for those changes as well.
Now, here's the catch that you might already have realized: The first part and the second part may not match. And they often don't, because the most common scenario is building with the AnyCPU configuration (which will typically yield a 32-bit PE executable) and deploying on 64-bit systems, where the IL will be JIT-compiled to 64-bit instructions.
In the end, you'll have to decide specifically which of the two you want to know (and whether it's worth the trouble). You may also want to explore other options, like taking advantage of the fact that AnyCPU assemblies can load as either 32-bit or 64-bit and in many cases you can use them without checking.
I have my own old Windows Service (.Net 3.5) which was running at 32-bit windows. Now we have a x64 Windows Server 2012, and would like to migrate this Service.
My question is : should I do something special with this Windows Service in order to achieve in it "all benefits" of 64-bit framework ? I mean - should I set some options during building/compiling it in Visual Studio 2010 (project/solution properties). Or something else ? Or I don't need to do anything - it will use 64-bit framework by itself, no matter how it's build.
It depends on the build target:
if the platform target is x86, it will always run as a 32-bit executable (or not at all)
if the platform target is x64, it will always run as a 64-bit executable (or not at all)
if the platform target is Any CPU without "Prefer 32-bit" enabled, it will run as 64-bit where possible, else 32-bit
if the platform target is Any CPU with "Prefer 32-bit" enabled, it will run as 32-bit where possible, else 64-bit
You can use Environment.Is64BitProcess to check how your application is running (or just look in task manager).
For your scenario, Any CPU without "Prefer 32-bit" would seem the correct choice.
Since this started as a 3.5 project, no, you probably don't have to change anything. The setting that matters is Project + Properties, Build tab, Platform target setting. The default in older versions of Visual Studio was AnyCPU. Which does what it says, it runs on any CPU so you get a 64-bit process on a 64-bit operating system. If it is "x86" (or the Prefer 32-bit checkbox is checked) then you force it to run in 32-bit mode.
It doesn't actually matter much btw, the only benefit of a 64-bit process is that it can consume a lot more memory. Well past the 2 gigabyte that a 32-bit process is restricted to. A service should never have that kind of impact on a machine.
Why is my application, which I compiled with AnyCPU, running as a 32-bit process on my 64-bit machine, and therefore unable to interact with Notepad, which is running as a 64-bit process?
I have the following code which will not run on x64 Operating System since notepad.exe is x64 and a x86 application cannot get the modules information of a x64 process:
prc.Modules[0].FileName
.Net Exception throws on my code:
System.ComponentModel.Win32Exception (0x80004005): A 32 bit processes
cannot access modules of a 64 bit process.
According to many answers and articles on this forum, MSDN, ..., I know that I need to use AnyCPU instead because of the fact that using x64 has no specific benefit for me. Even when Compile on AnyCPU configuration, my error persists, furthermore, in Task Manager I see a (32-bit) at the end of my process name.
(Actually I tested the code with checking performance and the x64 code ran ~40 ms faster. never mind I do not want my code run 40 ms faster :D )
I do not know that is wrong.
VS 2011 Beta (x64)
Windows 8 Consumer Preview (x64)
Sincerely yours,
Peyman Mortazavi
Though the questioner has accepted the answer, I feel like the answer is incomplete since the questioner has mentioned that he is using Visual Studio 2011 and hence assuming the target .Net Framework would be 4.5 there are few caveats with respect to what "AnyCPU" means.
Please refer to both these links, to get a better understanding of how the meaning of "AnyCPU" has changed over time.
http://blogs.microsoft.co.il/sasha/2012/04/04/what-anycpu-really-means-as-of-net-45-and-visual-studio-11/
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/compiler-options/platform-compiler-option
From these links, you can arrive at the answer to the question of why your application is running as 32 bit process
On a 64-bit Windows operating system:
Executables compiled with /platform:anycpu32bitpreferred execute on
the 32-bit CLR.
Here is your culprit.
Go into the project Properties. On the left side, select Build.
Take a look at the "Platform target:" setting for the current active platform. Change it to x64.
(I suspect your "Platform target:" will be explicitly x86 for "Any CPU")
Just got the Visual Studio 11 developer preview installed. I see a new option in the project properties called "Prefer 32-bit" when compiling a managed (C#, VB) application with the AnyCPU target specified. This doesn't appear to be an option for class libraries, just top-level apps.
What does this flag indicate?
It likely indicates the app is AnyCpu but when 32 bit is available it shouold run as such. This makes sense - 64 bit apps use more memory, and sometimes you just dont need the memory space ;)
EDIT:
Application compiled with "Any CPU 32-bit preferred" is compatible with x86, x64 and ARM, while x86 is compatible only with x86, x64 and not ARM. For details see this.
Here's right and simple answer:
There is an good article at What AnyCPU Really Means As Of .NET 4.5 and Visual Studio 11.
The short answer to your question is "When using that flavor of AnyCPU, the semantics are the following:
If the process runs on a 32-bit Windows system, it runs as a 32-bit process. IL is compiled to x86 machine code.
If the process runs on a 64-bit Windows system, it runs as a 32-bit process. IL is compiled to x86 machine code.
If the process runs on an ARM Windows system, it runs as a 32-bit process. IL is compiled to ARM machine code.
The difference, then, between “Any CPU 32-bit preferred” and “x86” is only this: a .NET application compiled to x86 will fail to run on an ARM Windows system, but an “Any CPU 32-bit preferred” application will run successfully."
How do I know the bitness of some process which is in running state. (Not the current one.. where IntPtr.size is useful) iswow64process()... gives only whether it is a WoW64 process, but doesn't output 32/64 bit.. could anybody pl help..
If you know you are running on 64-bit windows then if it a process is running in WoW64 mode then it must be 32-bit (that is what WoW64 is for - running 32-bit applications on 64-bit Windows), if not then you can assume 64-bit.
From MSDN:
WOW64 is the x86 emulator that allows
32-bit Windows-based applications to
run seamlessly on 64-bit Windows.
Also from here:
[IsWow64Process] A pointer to a value that is set to
TRUE if the process is running under
WOW64. If the process is running under
32-bit Windows, the value is set to
FALSE. If the process is a 64-bit
application running under 64-bit
Windows, the value is also set to
FALSE.
IsWow64Process is the right approach. Running under WOW64 is only true for a 32bit process on a 64bit OS.
The real trouble is finding out that you are running on a 64-bit version of Windows. Using IntPtr.Size isn't good enough, your program might have been forced to run in 32-bit mode. You'll have to P/Invoke GetNativeSystemInfo() to get SYSTEM_INFO.wProcessorArchitecture.
Watch out for exceptions from these P/Invokes, the API functions are not available in XP and earlier. When you get one from IsWow64Process then you'll know it is a 32-bit OS. You can avoid the exception with LoadLibrary and GetProcAddress.