Confused about building for 32- or 64-bit - c#

I've got a VS2013 solution with several projects (a C# WPF application plus class libraries). Each project's "Platform Target" is set to "Any CPU". I was under the impression that the resulting EXE would run as a 64-bit application on a 64-bit PC, and a 32-bit application on a 32-bit PC. Is this correct? My dev PC is 64-bit, but when I run the application (either standalone or via VS debugging), it appears in task manager as "foo.exe *32". What's going on here?
We have a junior developer with a 32-bit machine. Will he still be able to open the solution and run it in VS?
Also, some of the projects reference a 3rd-party DLL. The vendor provides both a 32- and 64-bit version - which one should the projects be referencing? If I reference the 32-bit DLL will this prevent the application from running as a 64-bit application? And if I reference the 64-bit version, will this cause problems for the 32-bit developer? And what about end-users - will my installer need to check the OS version and copy across the appropriate DLL?
Finally, what about DLLs referenced via NuGet? Does NuGet install 32- or 64-bit versions of DLLs? How do I deal with 32- or 64-bit end-user installation?

I'm going to try to answer some of your questions since you've bundled so many into a single one..
We have a junior developer with a 32-bit machine. Will he still be able to open the solution and run it in VS?
Yes, as long as all projects are set to build for Any CPU and there are no external dependencies on 64bit assemblies or native DLLs.
If I reference the 32-bit DLL will this prevent the application from running as a 64-bit application?
Yes, if any of the assemblies, or COM components linked was specifically built against the 32bit CLR then it will require the whole project to run as a 32bit process. You always have to be careful about native code that your project may be dependant on.
And if I reference the 64-bit version, will this cause problems for the 32-bit developer?
Yes, the 32bit developer will not be able to run the project on his machine, if there are any 64bit assemblies.
As a final thought I'd like to add that it is very important whether the final executable project is built as Any CPU, or for a specific 32bit or 64bit target platform.
Usually I found that having the final executable built as Any CPU can cause all sorts of problems at runtime (of the Bad Image runtime exception variety) unless all assemblies linked are also targeted for Any CPU and there are no external, native, dependencies. This latter requirement is the hardest to ensure.
On the other hand, a final executable built for an explicitly specified 32bit or 64bit platform can happily incorporate other assemblies built for Any CPU

We have a junior developer with a 32-bit machine. Will he still be able to open the solution and run it in VS?
Yes, He can run.
If I reference the 32-bit DLL/ 64-bit will this prevent the application from running as a 64-bit/32-bit application?
The manual edition of the .csproj file(s). You also need separate directories for the different binaries, ideally siblings of each other, and with the same name as the platform you are targeting.
Refer Conditionally use 32/64 bit reference when building in Visual Studio
what about end-users - will my installer need to check the OS version and copy across the appropriate DLL?
Yes, you need to manage build process scripts to create specific version for different architecture..
References:
What does the Visual Studio "Any CPU" target mean?

Related

how to know which cpu to use in build (x86 x64 or AnyCpu)?

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.

C# compiling for 32/64 bit, or for any cpu puzzler

This question relates to these previous question on SO
Any CPU question 1 and Any CPU Question 2
I have a application which was originally built on Win XP using Visual Studio 2005 (don't laugh!). This app calls into our win32 C++ dll. The C# components which call the C++ dlls were built with the "Any CPU" configuration and have been happily working on Win XP without any issue.
We are now moving to Win 7 and the release version of our app (which was built on Win XP with VC 2005) works fine. However with the roll out of win 7 to our users we have now taken the opputunity to move to VS 2010 and I have built the C# components on win 7 with VC 2010 but now when running this version I get lots "unable to load abc.dll" where abc.dll is our win32 c++ components.
I understand that recompiling the C# assemblies with x86 config will solve the problem but what I don't understand is how the release version c# assemblies built with Win-XP/Visual studio 2005 (Any CPU config) are able to run on Win 7 without any issues? Surely these C# assemblies built with "Any CPU" should JIT to 64 bit code when loaded in Win 7 and cause BadImageFormatException or other errors because they call Win32 C++ dlls.
UPDATE : I have Some more information that have been requested in the comments below.
On my Windows 7 box I right click on my computer and look at the properties. The System information says "System Type : 64 bit operating system" confirming this is a Win64 OS.
Opening up the solution in VC2005 on Windows XP When viewing the configuration manager for the solution I can confirm ALL the C# projects are platform type "Any CPU".
When running the release build (which was done on VC2005/win xp) on 64bit Win 7 machine, I task manager shows the image name as "Test.exe *32", this confirms it is jit'd and loaded into 32bit process.
Under Win7, the process is 64-bit. 64-bit processes cannot have 32-bit DLLs in them, that's a pretty fundamental design limitation of Windows.
And the fact that this managed code EXE calls into a 32-bit DLL is not obvious from the get-go - P/Invoke, as well as COM interop, works via late binding. So the EXE is loaded, the loader does not check the dependencies - for one thing, the dependencies might be conditional - then the DLL loading time comes, wackiness ensues.
So yeah, if you have managed code with known 32-bit dependencies, you better specify a 32-bit CPU at compile time. Or recompile the C++ parts to 64 bits, that's also an option.
I can confirm that you should get BadImageFormatException. Is it possible that the compilation on XP was monkeyed with badly enough that it's not actually building AnyCPU but rather builds x86 labelled as AnyCPU. I can also confirm it's possible to monkey with a project file badly enough that it would do that and the project upgrade component chokes on that.
One possible explanation is that one of your projects in the solution on the 32-bit development system had a binary reference to a 32-bit assembly, which would force it to be loaded as a 32-bit process even on 64-bit systems.

converting .net application 32 bit to 64 bit

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.

Can you install .NET Framework Client Profile 32 bit version on a 64 bit PC/OS?

Mainly I ask this because I don't want to distribute both versions, and if I need to instal a 64bit .NET on an x64 PC and a 32bit .NET on a 32 bit PC then I would need to make this check in my loader application to download the correct version for the correct PC.
However, if I just do a one for all, it would be easier - and i would just like to know if theree is anything I should know before doing this (ie: any repercussions?) or all good?
Also, when I compile an exe in a 64bit version of VS2010 does it compile a 32bit exe by default or a 64bit? I'm presuming 32, but just wanted to make sure.
Thanks.
If you target AnyCPU for your compilation, the app will run as 64bit on a 64bit OS, and 32bit on a 32bit OS. If you target x86, the app will run as 32bit regardless of the OS. If you target x64, the app will only run on a 64bit OS.
The 64bit version of .Net also includes the 32bit dll's.
If you have to install the runtime from the Internet, then use the web installer. It will take care of downloading and installing the correct version on the client. This way you can target AnyCPU (or x86) and be certain that the app will run regardless of the OS.
If you need to package .Net with your app, download the full file which has both 32/64bit versions included - http://download.microsoft.com/download/9/5/A/95A9616B-7A37-4AF6-BC36-D6EA96C8DAAE/dotNetFx40_Full_x86_x64.exe
Client profile web install
Client profile full install
Silent install can be done with the /q parameter and you might want to add /norestart as well and handle reboot yourself if necessary.
Check out this blog post and the MSDN documentation on what switches are available.
The .NET bootstrapper automatically installs both the 32-bit and the 64-bit versions of the .NET framework on a machine with a 64-bit operating system. Nothing you have to do to tell it to do so. Avoid distributing the .NET framework yourself, you'll have a hard time keeping up with the security updates. Just tick the option in the Setup project's Prerequisites to get the bootstrapper, that will download the latest and greatest during install on the target machine, if necessary. The option is automatically ticked when you create an installer for a managed program.
There is no 64-bit version of VS2010, no need to worry about that.
The Platform Target setting in the Project + Properties, Build tab for your EXE project is relevant. It defaults to x86 in a project that was created from scratch in VS2010. There is no great reason to change it to AnyCPU for the Release build unless you need the extra virtual memory space that a 64-bit process can provide. If you do change it then do make sure to test it thoroughly. I know you've been tinkering with unmanaged COM servers, x86 is probably a hard requirement.

App with many assemblies forcing 32-bit

I have a VS solution with many assemblies and third-party utilities. I need to force the app to run 32-bit when running on a 64-bit machine. The app runs just fine on a 32-bit machine. I forced the .exe file to be only 32-bit required and when run on the 64-bit machine, I am getting "an attempt was made to load a program with an incorrect format" error. It was my understanding that changing the exe would force all the assemblies to load as 32-bit. What is going on?
I know this is an old question; maybe you already found your answer.
I'm not familiar with setting ILONLY and 32BITREQUIRED... usually choosing x86 instead of ANYCPU in the compiler drop-down box before compiling takes care of everything you need. You can verify that all your apps are set to compile to x86 in the configuration manager, as well.
Most likely, what you're running into is that one of your third-party utilities installed a 64-bit DLL on the 64-bit machine, and your forced-32-bit application is trying to load a 64-bit DLL. If a third-party DLL has a 32-bit and 64-bit version, chances are the installer is smart enough to know which one to lay down.
Two places you can go on the 64-bit machine to check:
If the program installed to C:\Program Files\, it's a 64-bit DLL; otherwise it would have been installed to C:\Program Files (x86)\
Navigate to the GAC from the command line: c:\Windows\assembly and look under GAC_32 vs. GAC_64. If you find it under GAC_64, you're trying to load the 64-bit DLL
HTH!
James

Categories