Multi Targeting in C#.NET for 32 bit and 64 bit - c#

Supposing I have a windows app developed based on C#. I want to ensure that it works on 32 bit and 64 bit both. But I don't want to change the config settings or application settings time and again. Is there a way to test both variants?

There are a couple of options.
You can target AnyCPU. If you're program is 100% C#/managed code, with no native dependencies, this will cause it to run 64bit on 64bit Operating systems and 32bit on 32bit Operating systems.
Target x86. This will cause it to run 32bit everywhere, which works properly on 64bit Windows (via WOW64). This works properly if you're using native (32bit) libraries, as well.
Make two builds, and two separate deployments. This allows you to use native code and still run 64bit on 64bit operating systems, but is far more work.
Since 32bit applications run well on 64bit operating systems, there is rarely reason to run the program natively in 64bit. This is typically only really beneficial if you're processing large amounts of data and truly need access to larger memory space than you can get in 32bit processes. In .NET, this typically means you'll want to build 64bit if you're going to use more than 1.2-1.6gb of RAM for your program. Otherwise, 32bit will work fine everywhere.

If you target AnyCPU, most .NET programs will run unaltered on 32-bit or 64-bit machines. The code will be jitted to 32-bit or 64-bit code as appropriate for the target operating system.
The exception where you need to use care is when using interop to unmanaged code.
If you do interop to unmanaged code and require to run as 64-bit on a 64-bit platform, you will have to make two builds.
If you do interop to unmanaged code and can accept running as a 32-bit process, target x86. That avoids two builds, and will run your .NET code as a 32-bit process in 32-bit and 64-bit platforms.

Related

C# : how to use x64 and x86 libraries on same project [duplicate]

My application is built as a x64 application. After moving to VS2010 I got some problems which seems to be related to some x64/x86 mismatch in referenced dlls. Now I'm moving to target .NET4, and I get even more similar problems.
My question is: What precautions do I need to take regarding mixing x64 and x86. Can it be done at all? I thought x64 applications should be able to use x86 dlls without problems. No? What about the other way? Can a x86 application reference an x64 dll - as long as it is being run on an x64 platform? What are the pitfalls I need to be aware of?
No, a 64-bit process can only load 64-bit DLLs and a 32-bit process can only load 32-bit DLLs. What you're probably thinking of is that a 64-bit operating system can run 32-bit processes.
The main issue with .NET is that - prior to VS2010 - executable projects defaulted to "AnyCPU" which means it would load in the "native" format of the OS it's running on (so 32-bit for 32-bit versions of Windows and 64-bit for 64-bit versions of Windows). The problem with that is that if you tested your application on 32-bit Windows (say) then it could break if you load 32-bit DLLs and tried to run on 64-bit Windows.
In VS2010, they defaulted all executable projects to be "x86" (that is, 32-bit) by default which (for the most part) mitigates the problem.
You can run x86 apps on a 64 bit OS using WOW32 emulation. Some pitfalls that I have encountered - you can't mix and match 32/64 in the same process. So if you intend to run IIS as 64 all the assemblies need to be 64 otherwise you'll have to run In 32 bit mode. 64 bit helps some apps more than others. Running SQL sever's 64 bit version provides several advantages over the 32 bit version, biggest advantage being that yo can install more than 4 GB of memory on the target server and that SQL will be able to use more than 4 GB of memory. It does not benefit IIS as much because IIS typically can't use more than 3 gb of memory. My advice would be to make sure your SQL server/os/version are 64 if possible. It's not going to make a. Huge dfference if the other servers are 64 but typically it's easier to work with and find 32 bit versions.

x64 x86 DLL AnyCPU

I'm trying to hook a simple process using EasyHook. I'm programming/debugging in a x64 environment and compiling my DLL with AnyCpu config on Visual Studio C#.
The problem is that when trying to use this DLL (in another project, same Solution, compiling with AnyCpu too) in the inject library function:
RemoteHooking.Inject(TargetPID, "DivisionInject.dll", "DivisionInject.dll", ChannelName);
(2nd parameter is for 32-bit system. 3rd is for 64 bit.)
I don't know why this line is throwing an exception:
System.ArgumentException: the given 64-Bit library does not exist!
I thought that AnyCpu used to create my DLL, i could use the same file (DLL) in 32bits system and on 64 bits too. Is this wrong?
Thanks.
The AnyCpu setting basically means that the determination of how the process or library will be loaded or executed will be based at/on the point of execution/load. A library compiled as AnyCpu will be loadable by both a 32bit and a 64bit calling process. An executable compiled as AnyCpu will run a 64bit process on a 64bit machine and 32bit on a 32bit machine. See this thread for a discussion on the concept of the AnyCpu target.
If your caller is compiled as 64bit and set to AnyCpu, it will be attempting to load the 64bit library.
While it is now less common, it is possible to install Windows 32-bit on a 64-bit machine. In this case, only exe's built for 32-bit/AnyCpu will run. The converse is obvious. 32-bit machines can only run Windows 32-bit.
Thus the O/S bitness is the determining factor, not the hardware.
Windows 32-bit on a 64-bit machine was more common in enterprise shops, that didn't want to support both O/S's or 32-bit legacy applications running on Windows-64.

Com calls to 32bit application on 64bit server slow

I have an application that I have just migrated to Windows 2008 R2 64bit. In essence it is a C# .NET 4.0 WCF application that makes a dynamic call to a 32bit COM application written in VC6 C++.
When I was running this on my desktop which is Windows 7 32bit the COM calls were considerably faster.
The server ought to be an order of magnitude more powerful (although in a HOSTED environment)
Are there any quick/easy things I can check to try and get to the bottom of this? I am due today to get alook at the resources allocated to the virtual machine but in the mean time..
Is this a 64bit calling 32bit COM thing?
Thank you!
Running 32-bit code from 64-bit processes is very time-consuming, because it involves the Windows on Windows subsystem (WoW). 64-bit code and 32-bit code cannot be run within the same process, which means that all calls from your code to the 32-bit dll must pass process and architecture boundaries, which involves some heavy data marshalling and function call marshalling.
http://blog.mattmags.com/2007/06/30/accessing-32-bit-dlls-from-64-bit-code/
Do some profiling to measure the performance of your app in different situations.
Compile to Any-CPU, run on x64
Compile to x64, run on x64
Compile to x86, run on x64
Then do what gives you the most performance.
However...
If you have access to the COM library source code, the very best thing would be to recompile it on the x64 platform.

Differences between 32 and 64-bit .NET (4) applications

What are the differences between 32 and 64-bit .NET (4) applications?
Often 32-bit applications have problems running on 64-bit machines and conversely. I know I can declare an integer as int32 and int64 (certainly int64 on 32-bit systems make problems). Are there other differences between programming an 32 OR 64-bit or a both 32 AND 64-bit compatible application?
Some differences:
32-bit and 64-bit applications can only load DLLs of the same bitness. This can be an issue for managed projects if your platform target is "Any CPU" and you reference or P/Invoke 32-bit native DLLs. The issue arises when your "Any CPU" program runs on a 64-bit machine, since your application runs as a 64-bit process. When it tries to load the 32-bit native DLL dependency, it will throw an exception (BadImageFormatException) and likely crash.
There are also filesystem and registry issues. A WOW64 process that tries to read from C:\Program Files will end up getting redirected to C:\Program Files (x86) unless it first disables Windows filesystem redirection (see Wow64DisableWow64FsRedirection). For versions of Windows before Windows 7, there were also registry reflection issues that were similar to the filesystem redirection issues mentioned above. The MSDN article Registry Reflection explains it well.
Platform-specific types like IntPtr will have different sizes. This could be an issue in code that assumes a fixed size (serialization, marshaling).
There are separate physical directories for the 32- and 64-bit files in the GAC. For my system, they are at C:\Windows\Microsoft.NET\assembly\GAC_32 and C:\Windows\Microsoft.NET\assembly\GAC_64.
The virtual address space size of 32- and 64-bit applications is different. For 32-bit applications, the size is either 2 GB (default) or 3 GB (with 4GT enabled). For 64-bit applications, the size is 8 TB. The 32-bit address space can be a limitation for very large applications.
A little more obscure, but a lot of interprocess Win32 calls won't work between a 32- and 64-bit process. For example, a 32-bit process can fail when trying to call ReadProcessMemory on a 64-bit process. The same goes for WriteProcessMemory, EnumProcessModules, and a lot of similar methods. This can be seen in C# applications if you try to enumerate the modules of a 64-bit application from a 32-bit application using the System.Diagnostics.Process.Modules API.
In general, I think you should not have any problems with managed code.
Potential problems can come from unmanaged code. For example, because variable sizes are different in 32-bit and 64-bit systems, pointers are different, etc. For example, the size of the int variable in C/C++ depends on the system. As for managed code as already mentioned, WoW can handle that.
x64 managed code will use Streaming SIMD Extensions (SSE) for double/float computation instead of x87 Floating Point Unit (FPU) when using x86 managed code.
In addition to other answers, I would like to add one more thing: we can run software of 32-bit system on 64 but conversely is not possible!

Will a .NET Windows Forms application work in a 64-bit OS or does it need to be modified?

Generally speaking, will a .NET Windows Forms application work in a 64-bit OS or does it need to be modified?
If it doesn't rely on a 32 bit external library (e.g. COM component), it'll work perfectly as a 64 bit process and will leverage its benefits (large address space, x64 instruction set, ...). If it relies on 32 bit stuff, most of the time, you can still run it as a 32 bit application by setting the target platform to x86.
Most .NET applications should work unmodified in 64 bits if they target x86 instead of Any CPU which is the VS.NET default.
According to this link: MSDN - Migrating 32-bit Managed Code to 64-bit.
If you have 100% type safe managed code then you really can just copy it to the 64-bit platform and run it successfully under the 64-bit CLR.
But if you are using any of the following features:
Invoking platform APIs via p/invoke
Invoking COM objects
Making use of unsafe code
Using marshaling as a mechanism for sharing information
Using serialization as a way of persisting state
it indicates that the application might not be completely compatible.
For the most part it should work just fine. You should be careful if you are doing anything with native code, whether it be unsafe managed code, or interop/PInvoke, but if all of your code is managed you shouldn't have any problems.
A pure .NET application will run on a 64-bit operating system with no modifications.
If you use a C++/CLI library, use architecture specific COM components, or do any P/Invoke calls, you may need to update your application for a 64-bit environment.
Most 64-bit OS's are able to handle 32-bit apps without problems. This is why you see a Program Files (x86) folder on your 64-bit OS to handle a lot of your old 32-bit apps.
As long as you don't mix and match library platforms, you'll be fine. Target x86 when you compile and you should be good to go.

Categories