Compiling a C# .NET x64 binary on an x86 system - c#

I have a C# project which contains a reference to ScintillaNET. Unfortunately ScintillaNET likes to detect the architecture of the machine and loads the native DLL based on the running architecture. That means that my project must be pre-compiled into x86 and x64 versions (I can not use Any CPU due to the above detection).
The problem is that my build server is x86-only. Is there a way I can compile a .NET assembly in x64 mode on an x86 machine? As far as I am aware the toggle simply forces the computer to load the assembly for the required architecture and doesn't actually output any architecture-dependent code at compile-time, however, when compiling under Mono 2.10.6 on the build server I get errors such as:
"error CS0016: Could not write to file `ScintillaNet', cause: AMD64"
I can't use CorFlags.exe to change the PE headers as this is a Linux-based build server. Is there any way to do this?

I ended up solving this issue by switching the project back to Any CPU. Since Scintilla will only work in the native architecture regardless of .NET settings, I had to run it as 64-bit on my machine. Originally I had intended to force the architecture to 32-bit to get Edit and Continue and this lead to confusion to how Scintilla detected architectures.
In reality, Scintilla will force itself to the native architecture, but if you build and run under Any CPU the .NET application will work fine. In addition, since I can't run a .NET application w/ Scintilla in 32-bit mode (for Edit and Continue to work) I get no advantage to forcing 64-bit mode on my machine either.

Related

How do I get the proper SQLite assemblies for a project configured for x86 CPU?

Background:
Working in C# using the 2.0 framework and setting up an application to use sqlite. When deployed to certain customer machines I get:
Could not load file or assembly System.Data.SQLite.dll
I am under the impression that there should be no client install of SQLite as long as you've placed the above DLL in the runtime directory. I have tried multiple configurations (x86 DLL compiled into a project targeting x86 cpu - failed on both x86 machines and x64 machines | x64 DLL compiled into a project targeting x64 CPU - failed on both x86 machines and x64 machines | both architecture versions of the DLL targeting Any CPU - failed on both x64 and x86).
I am using SQLite version 1.0.98.0. I'm not sure what relevant code I could post as this is an issue with a DLL reference, but I am happy to upload anything needed to foster a reasonable answer. I have no client computer cpu in mind so if I could get this running as x86 targeting x86 CPU that would be great. Any yes, I have already tried that combination using the correct DLL while making sure it ends up in the runtime folder and it still fails. If I could post more than two screen caps I would show the file as well, but alas I cannot.
I have been searching for quite a while and cannot seem to find an example that exactly fits what I want to do. The question has been asked but not solved. I read that the configuration of the DLL is what causes this and that is why I tried both DLL's targeting both processors. Seeing that this question is asked a lot and I still couldn't find my answer I have to assume a lot of people are in the same position as me so maybe we can work this one out together and give the community a great post on solving this issue.
Assembly information for the x86 configuration
Configuration Manager for x86 CPU
Make sure your dll are deployed properly on target machine. Some time setup compiler (Inno Setup) puts all the files in directory structure in same root folder hence .net can not file dll for expected path and hence it throws file not found exception

Confused about building for 32- or 64-bit

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?

Can't set platform to x86 in Visual Studio 2008 C# Express Edition

I want to set the target platform of my project to x86, but there is no such option in the "Platform" dropdown list.
How can I fix it?
Click on <New ...> to define a new x86 only configuration.
This is a very common mistake and very hard to eradicate. Haven't quite given up hope yet.
The Platform name of a project only matters to C++ projects. Where it is a big deal, different compilers are used to generate the program since unmanaged code is machine code that is directly executed by the processor. So it is very important that you properly select between x86, x64 and ARM when you build the program. The Platform selection determines what compiler is used.
It is a non-issue for managed code. Compilers don't generate machine code, they generate MSIL. The Just In Time compiler at runtime generates the machine code. And will do so based on the kind of operating system you execute your code on. A Windows RT slate or a phone will use the ARM jitter. If you run it on the 64-bit version of Windows on a desktop machine or server then the x64 jitter gets the job done. And the x86 jitter takes care of a 32-bit operating system. Nobody cares about Itanium anymore.
So it doesn't matter what the platform name is when you build the program, the assemblies generated by the compiler are identical whatever name you pick. If you want to pick a name for the Platform, VS requires one, then "AnyCPU" is a very appropriate name. Don't change it.
You do have the option to force the CLR to use a different jitter than the default one. Which works in exactly one case, you can force the x86 jitter to be used on a 64-bit operating system. Purely because the 64-bit version of Windows does support executing x86 programs. There only one scenario where that is necessary, you may have a dependency on a DLL that contains unmanaged code that's only available as a 32-bit executable.
That forcing is done with a completely different setting, changing the Platform name does nothing. You find it back in Project + Properties, Compile tab for a C# project. Only the setting for the EXE project matters.
See
Go Build->Configuration Manager...
Change 'Active Solution Platform' to x86 (if it's there. If only AnyCPU is there, then use that.)
For each offending project, in the Platform column, select 'New'
Choose New Platform as 'x86', Copy Settings from 'Any CPU', and make sure the check box is NOT ticked.

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.

How to run .Net Win-Forms application on a 64 Bit OS?

I have made a .Net win-forms application in C#, on a 32 bit OS (Windows 7).
It doesn't work on the deployed client-terminal/machine which has a 64 bit OS (Server 2008).
What should I do?
Thank you.
Go to the Build tab of the project's properties and make sure the platform target is set to x86. (This is just my first guess based on the vague information provided. The problem might be caused by something completely else, e.g. the terminal server environment as such.)
You should only change this setting if you need your application to address a large amount of memory or you definitely want to make sure it runs as a 64-bit process.
The AnyCPU setting can hardly be recommended as it may cause you all sorts of pain with respect to native dependencies (I'm not saying it should never be used, but it should be very well considered whether the additional overhead required for deployment and testing is worth the trouble).
Probably you have used some feature that is not available while running the app in x64. Change the build configuration to x86.
If it does work now, you have used some libraries (COM, ActiveX, Office 2007, WinAPI, ...) that does not like to be called from 64 bit.
If it works now, ask yourself: why do I want my app to run using x64 bit? What do I gain? Does it really need to use that much memory?
There is no problem with running a x86 bit app on a x64 bit platform.
If you are using ActiveX controls inside your application or anything else that is not portable to x64, you might have to change the build target to "x86".
If it's a genuine x86 application your x64 environment shouldn't have any problem running it. So make sure all your libraries and your own binary are x86 compatible and don't use x86 exclusive features like specific COM libraries.
You should ensure that you project is being built with the "Any CPU" platform.
The default is sometimes to build for "x86".
Check your build config. I think VS will default to building the app for x86 platforms if you develop in a 32-bit environment. Either change to x64 or AnyCPU, rebuild and try again.
.stompp

Categories