It is unclear to me how the compiler will automatically know to compile for 64-bit when it needs to. How does it know when it can confidently target 32-bit?
I am mainly curious about how the compiler knows which architecture to target when compiling. Does it analyze the code and make a decision based on what it finds?
Microsoft has a blog entry What AnyCPU Really Means As Of .NET 4.5 and Visual Studio 11:
In .NET 4.5 and Visual Studio 11 the cheese has been moved. The
default for most .NET projects is again AnyCPU, but there is more than
one meaning to AnyCPU now. There is an additional sub-type of AnyCPU,
“Any CPU 32-bit preferred”, which is the new default (overall, there
are now five options for the /platform C# compiler switch: x86,
Itanium, x64, anycpu, and anycpu32bitpreferred). When using the "Prefer 32-Bit"
flavor of AnyCPU, the semantics are as follows:
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.
Here's a simple answer:
Note: AnyCPU-32bitPreferred is only available in .Net version 4.5 and higher.
When I had 32 bit preferred checked, when run on our server, it was trying to use the 32 bit db driver instead of 64 bit that we had installed, so it wasn't connecting to the db when we ran it, so queries were failing because of failure to connect.
The reason is: in case you don't want to use more memory with 64 bit applicatios. Which means, if your application is AnyCPU, you want to run as 32 bit.
To add more, the setting in Visual Studio targets the particular CLR:
Visual Studio installs the 32-bit version of the CLR on an x86 computer, and both the 32-bit version and the appropriate 64-bit version of the CLR on a 64-bit Windows computer. (Because Visual Studio is a 32-bit application, when it is installed on a 64-bit system, it runs under WOW64.)
Please refer to the article 64-bit Applications (MSDN).
Related
I am working on a tool that loads different assemblies using System.Reflection's method Assembly.Load
Here is what i get
On a 64bit OS, if application configured with :
x64 loads x64 & AnyCPU Assembly
x86 loads x86 & AnyCPU Assembly
AnyCPU loads x64 & AnyCPU Assembly
Now when it's configured with AnyCPU Prefer 32 bit on 64 bit OS,it will be running on 32bit process as it said here
In .NET 4.5 and Visual Studio 11 the cheese has been moved. The
default for most .NET projects is again AnyCPU, but there is more than
one meaning to AnyCPU now. There is an additional sub-type of AnyCPU,
“Any CPU 32-bit preferred”, which is the new default (overall, there
are now five options for the /platform C# compiler switch: x86,
Itanium, x64, anycpu, and anycpu32bitpreferred). When using the
"Prefer 32-Bit" flavor of AnyCPU, the semantics are as follows:
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.
My Question is : Why it loads x64 assembly without any problem? isn't that a strange behaviour?
I have seen this question ODP.NET x64 ANYCPU and Prefer 32-bit setting that support this proposition
.NET assemblies (exe and dll) don't contain x86/x64 assembly. They contain IL (intermediate language), which is architecture-independent. At runtime, the JIT turns the IL into x86/x64 machine code, as appropriate.
The "Any CPU" and "Prefer 32-bit" settings, etc, only change some bits in the header of the assembly, which tells the JIT what to emit at runtime. Only the bits in the header of the .exe matter: the exe dictates what the JIT will emit, and if the JIT is emitting e.g. x86 for the exe, it will do the same for all other assemblies which are loaded into that process.
Now, it might be a bad idea to load a dll which has the "x86" flag set into a process which the JIT is emitting x64 for: presumably that dll has a reason for specifying x86, and that's probably because it's invoking some native code which is compiled for x86. If you force it to run inside an x64 process, then it won't be able to invoke that x86 native code any more.
(Note that the landscape has moved since that quote you found: .NET Core now ignores "Prefer 32-bit", and AnyCPU defaults to x64).
The AnyCPU option allows the .NET virtual IL code in the executable binary file to be run on 32-bit as well as 64-bit computers.
AnyCPU prefers 32-bit indicates to run the process in 32-bit compatibility mode on x64 machines, unless of course some cause prevents that.
It is a parameter at runtime, not at compilation, as explained #canton7.
What is the purpose of the "Prefer 32-bit" setting in Visual Studio and how does it actually work?
If the application loads 64-bit DLLs, it means the code is executed (translated) in 64-bits native machine code, otherwise we would get a system error box.
Having a virtual assembly for a virtual OOP (single inheritance yet) computer is the purpose of DotNet.
If we look using any Task Manager we will see that the process is indeed x64 and not x32.
What is said in the following links about x32-x64 is valid for x64-x32:
Is it possible to load a 64-bit dll into a 32-bit process?
Calling 32bit Code from 64bit Process
Load 32bit DLL library in 64bit application
Process Interoperability
To be able to load a DLL of a different architecture than the highest one, we need certain things like creating a sandbox. For example, Renoise can run 32-bit VST while the DAW is 64-bit.
I've got a windows service compiled as AnyCPU. I'm trying to get it into our installer to distribute. However... I am unclear on the difference between the 32 bit and 64 bit versions of InstallUtil. Does anyone know what (if any) there are?
On my 64 bit machine, I can run either the $(WinDir)\Microsoft.NET\Framework64\v2.0.50727 or the $(WinDir)\Microsoft.NET\Framework\v2.0.50727.
In both cases, the resulting service Process in Task Manager does not have the *32 flag applied to it.
Only the 32 bit InstallUtil works on 32 bit machines (obviously).
Is there a need to use the \Framework64\ version of InstallUtil? What does it do differently?
According to this, you are supposed to use the 64 bit version to install 64-bit and MSIL assemblies, but it doesn't say why.
Starting with the .NET Framework version 2.0, the 32-bit version of
the common language runtime (CLR) ships with only the 32-bit version
of the Installer tool, but the 64-bit version of the CLR ships with
both 32-bit and 64-bit versions of the Installer tool. When using the
64-bit CLR, use the 32-bit Installer tool to install 32-bit
assemblies, and the 64-bit Installer tool to install 64-bit and
Microsoft intermediate language (MSIL) assemblies. Both versions of
the Installer tool behave the same.
I believe here explains why. If you look at the bottom of the post, it explains some differences between the two and when to use the 32-bit intallutil.
Installutil.exe is built for a specific platform, therefore it will
start as a 32 or 64-bit process and the related registry hive will be
updated. Note that if you have a snap-in built with the platform
switch, you will only be able to register it in one of the hives
(32-bit or 64-bit).
I ran across this as well. The issue was my VS2008 project was set to Platform Target: Any CPU. No matter which InstallUtil.exe (32 or 64) I ran on the 64 bit OS it was installing as 64 bit.
I changed my project setting Target to x86 and then ran the 32 bit installutil.exe and everything works fine. It now shows the *32 flag in Task Manager.
If you're installing a 64-bit only assembly, the 32-bit InstallUtil won't be able to load it. You'll need to use the 64-bit version.
I'm using Windows 7 and x64 cpu.
Does it mean that I should always compile with "x64" option in Visual Studio? What about "dll", can I use x86 dll from x64 application? Probably there are other concerns?
This article contains a brief overview of each option.
Here's a small quote:
The default setting, Any CPU, means that the assembly will run
natively on the CPU is it currently running on. Meaning, it will run
as 64-bit on a 64-bit machine and 32-bit on a 32-bit machine. If the
assembly is called from a 64-bit application, it will perform as a
64-bit assembly and so on.
If the project is set to x86, this means the project is intended to
run only as a 32-bit process. A 64-bit process will be unable to call
into an assembly set as X86. Reasons to set your project as x86
include dependencies upon native DLLs that are only available in
32-bit or making native calls assuming 32-bit . Applications and
assemblies marked for x86 can still run on 64-bit Windows. However
they run under WOW64. Visual Studio itself runs under this emulation
mode since it is a 32-bit application.
Setting the project to x64 will specify that the assembly must run
under 64-bit Windows. Attempting to run the assembly on 32-bit
Windows or call the assembly from a 32-bit process will result in a
runtime error.
Generally speaking, you should use AnyCpu all the time.
If you have specific reasons to expect compatibility problems with that, then you'll need to choose x86 or x64 as appropriate.
As noted in the comments, dll's built against specific architectures can require you to build your assembly a certain way. This will be something you'll want to do when you need to, not otherwise.
No... the machine you write your code on/compile/build your software (EXE, DLL...) does not have anything to do with the question which target (x86 / x64 / Any).
IF you want the result of the build to run anywhere you use either x86 or AnyCPU. If you want the result to run on x64 only then you use x64.
There are some cases where you must use x86 or x64 - that is when you use some (3rd-party?) component/library/DLL/ActiveX etc. in your project which is 32 Bit only (then x86) or only 64 Bit only (then x64).
AnyCPU is what I generally recommend. You can see this issue discussed in depth at this SO post.
The only concern is that you cannot go backwards - you can't use an x64 assembly from a x86 application. AnyCPU alleviates this potential pitfall.
I have got a .net application,
Class library (Target Platform set to Any CPU)
Winform Application (Target platform set to Any CPU)
Installer (Target Platform set to X86 and Detected dependencies set for .net framework(x86))
Now when I install this application through setup.exe on a 64-bit machine, it is installed in the Program Files [x86] folder; I guess this is WoW64 feature of emulating 32-bit environment on a 64-bit application.
Now when a client asks to convert it to 64-bit, why does it matter to him if the 32-bit version itself works fine through WoW64? would converting it to 64 bit result in performance benefits?
And when I try to convert it to 64-bit, do I need to change it for all, ie ,
Class Library (change Target platform to 64) (What if I skip this step?)
Winform Application (change target platform to 64) (What if I skip this too?)
Installer (change target platform to 64) [Detected dependencies listing doesn't show any .NET framework x64 option, why?]
Please suggest.
No conversion is necessary, your app already runs as a 64-bit process. Because you used AnyCPU on the EXE project. You installed it to the wrong folder but that doesn't matter much if no other process tries to start yours programmatically. That's exceedingly rare.
Verify this from TaskMgr.exe, Processes tab. A 32-bit process has *32 after its process name.
Make your client happy by changing the Setup project's TargetPlatform setting to x64 so it gets installed in c:\program files. Takes you a few minutes.
You can leave the .NET code projects on AnyCPU, however to install onto 64-bit without hitting the 32-bit WOW stuff you need to change the installer project property that you mention.
If you have custom actions in the installer, these may not work when you change to 64-bit. You might get a BadImageFormatException. To resolve this, you need to faff with the resulting MSI:
http://adamhouldsworth.blogspot.com/2010/10/64bit-custom-actions.html
It won't make much of a difference to the client if your application is standalone. There is no free performance benefit, other than access to more RAM, when going to 64-bit (though the JIT has different types of optimisations available).
The only situation I've seen where 64-bit is required is when you consume that DLL in another application, you cannot mix bit-ness in a single process.
Update: perhaps the lack of a 64-bit framework prerequisite is because you are using VS 2005?
http://social.msdn.microsoft.com/Forums/en-US/winformssetup/thread/7b00f4e9-64e3-4fb6-9906-880820ecda92
64 bit may or may not give performance differences. A 64 bit application can also utilize (way) more memory than a 32bit application.
If you launch an AnyCpu exe on a 64bit OS it should launch in 64bit (see in the task manager, 32bit processes are appended with *32 there). If you set the application to x64, the library must be either x64 or AnyCpu.
If you do not have native x64-only references you can leave your exe and dll as AnyCpu, but you will need to modify the setup to x64.
As for the framework, on an x64 machine (which is the only place an x64 app will run anyway), the framework always includes both 32 and 64 bit, found in C:\Windows\Microsoft.NET\Framework and Framework64 respectively.
Now when i install this application through setup.exe on a 64-bit machine, it is installed in the
Program Files [x86] folder; I guess this is WOW feature of emulating 32-bit environment on a 64-
bit application.
No, it has NOTHING to do with the program, only with the installer.
•Installer (Target Platform set to X86 and Detected dependencies set for .net framework(x86))
32 bit installer installes it in the 32 bit folder for programs, regarless whether the program is 32 or 64 bit.
Sadly you can not have one installer doing both - you need an installer for 32 and one for 64 bit in concept, by design.
This is totally a design decision on the MSI part and, again, has nothing to do with the program at all.
I create application in visual studio 2010.
I tested on server 2003 r2 x64 and the program does not start.
trying to compile x64 and I crash exception
Error while Trying to run Project:
Debugger cannot start: The assembly to
be debugged was built with platform
incompatible with the current system
If your application references 32-bit .dll-files it can't run as 64-bit. Either .Net assemblies compiled to x86-target (which is default now), or P/Invoke on native Windows .dll-files, will prevent you from running your 64-bit app.
The Windows installation you are running this on also needs to be 64-bit in order for it to handle 64-bit debugging. (Note: Compiling to 64-bit will work fine!)
Set target CPU type to x86 in project properties (under Build) to make it work. If you don't reference any external 32-bit .dll's you can set it to "any" to let .Net decide. It will then run 64-bit mode on 64-bit operating systems and 32-bit mode on 32-bit operating systems.
I'm not sure about VS2010, but for VS2005 I build with "Mixed Platforms" set for "Active solution platform."