How to build a x64 and x86 executable at the same time - c#

In dotnet core/.net 5 is there the possibility to have a project that builds executable for x86 and x64?
An obvious option would be to work with two separate project files as suggested here: Build both x86 and x64 at.
Is there an alternative? Neither <PlatformTargets>x64;x86</PlatformTargets> nor <RuntimeIdentifiers>win-x86;win-x64</RuntimeIdentifiers> in .csproj file yield the desired result. I even tried with a publish-profile using<RuntimeIdentifiers>win-x64;win-x86</RuntimeIdentifiers> which seems not to have the desired effect.
I would like to have both files as native items in the nuget package so I think it would be nice if I could do everything with just one project.
Update: I cannot use AnyCPU because it might be shipped as 32-bit bundle together with 32-bit native libraries. The AnyCPU might run as 64-bit then (there is no constraint the JIT could detect) and be incompatible with the native files and fail as a consequence.

Have you tried to build with 2 build scripts, then you can specify the "PlatformTargets" separately.

Related

OpenCvSharp only starts with all OpenCvDlls

I'm using OpenCvSharp with visual studio 2013. I've installed it through Nuget and it is working fine.
But when I deploy the application it has a DLL directory that has 128M. 128M for x86 and 128M for 64 indeed.
I'm using basically the functions from HighGui and Core. When I remove the DLLs, OpenCvSharp throws an exception when loaded.
I've tried recompile OpenCvSharp without success (this is another question) and even Recompile OpenCV to get smaller DLLs.
Is there any way of loading only the needed DLLs and point out which one can be removed?
The size of your deployment sounds quite large...
When I create a test project with Nuget package OpenCvSharp-AnyCPU 2.4.10 I get:
1.22MB for the net40 assemblies
32MB for the x64 dlls
29MB for the x86 dlls
OpenCvSharp loads the native dlls on demand (i.e. when the C# code needs the native code) so you could remove dlls which your code never uses, but you'd have to check the source or find this out by trial and error.
By default your C# app will build targeting Any CPU which means both sets of dlls are needed, but you could set Platform target: x86 in build properties and just not deploy the x64 dlls.

Bad Image Exception while loading SQLite DLL

I have a project that is build on Any CPU configuration, .Net Framework 2.0, vs2008 with 32bit version of SQLite dll used in it.
Well this works fine on my 32 processor environment, but when i ran this project on 64bit processor environment i experienced
"Could not load file or assembly 'System.Data.SQLite, Version=1.0.66.0, Culture-neutral,
PublicKeyToken=db937bc2d44ff139' or one of its dependencies.
An attempt was made to load a program with an incorrect format."
I even tried adding 64 bit dll on my project but it did not work.
I have tried all the solutions but that did not work for me. Since i am bound to build the project on 32 bit machine, i need a way to run this tool on my 64 bit environment too.
Any suggestions/comments/improvements means a lot for me.
Thanks in Advance.
Compile your application using x86 configuration.
When dealing with dlls like SQLLite that are compiled for x86, your process must be running in x86 mode.
I find these steps can be used to deal with sqlite.
Download NuGet
open cmd and type nuget install System.Data.Sqlite -- note it will create a folder in your current directory
copy dlls from net20 folders to your solution like so.
Add a reference to System.Data.SQLite.dll
Make sure you copy both SQLite.Interop.dlls to your output dir
Hope it helps.

How to build x64 and x86 projects that reference same projects

I have three projects, ProjectA (exe), ProjectB (exe) and ProjectD (class library)
Project A references the System.Data.OracleClient.dll and ProjectD. Project B just references ProjectD. The 32-bit client version of oracle is installed and therefore ProjectA has to be a 32-bit application. Project B can be built as a 64-bit application.
Project A build settings:
Platform: Active (x86)
Platform target: x86
Project B build settings:
Platform: Active (Any CPU)
Platform target: Any CPU
My questions are what should the build settings be for ProjectD (the class library) and when ProjectA and ProjectB get built does it build ProjectD differently? A deeper explanation of the CLR would be great in terms of communications of the projects.
ProjectA and ProjectB are to be used on 64-bit Windows Server 2008. No installation, just standalone exe's.
Only the Platform target setting for the EXE project matters. That's the assembly that gets loaded first and determines the bitness of the entire process.
A DLL doesn't get a choice, it must be compatible with whatever was selected by the EXE project. Picking AnyCPU for a DLL project is therefore almost always the correct selection.
There are just a few cases where you'd use an explicit setting. You'd only do so if you know that the class library has a dependency on some kind of native code, like the Oracle provider, and that trying to run that native code in the wrong bitness produces a completely inscrutable exception. You can avoid that exception and get a (slightly) better one by picking the Platform target for the DLL, the program will fail with a BadImageFormatException early when it tries to load the assembly. Albeit that this exception isn't exactly a very informative one either. Some odds that an admin is going to try to reinstall the DLL a couple of times before deciding that the real problem is elsewhere.
So basic ground rules: pick x86 for the EXE project, AnyCPU for all other class library projects, a nastygram to Oracle for doing nothing to make this easy.
My questions are what should the build settings be for ProjectD (the
class library) and when ProjectA and ProjectB get built does it build
ProjectD differently? A deeper explanation of the CLR would be great
in terms of communications of the projects.
Just use Any CPU for your lib. It'll build a unique assembly that can be executed in both 32-bit en 64-bit environments.
Technically, the just in time compilation with either produce 32-bit code or 64-bit code at runtime.

Need 64-bit SQLite DLL for managed C# application

I'm trying to embed SQLite into my portable C# .NET 2.0 application rather than having the DLL files included in the distribution folder. However, to embed SQLite, I cannot use the Mixed-Mode libraries provided by PHXSoftware. Instead, I am using their 'Managed Only' version.
This works fine on 32-bit computers, but when it's running on a 64-bit machine, it throws a format exception. As I found out from here: http://sqlite.phxsoftware.com/forums/p/2564/9939.aspx I need to load the unmanaged sqlite3.dll manually in the required architecture format first before I use the managed libraries.
That's where I fall short. I cannot find a 64-bit version of SQLite to include along with the 32-bit one. Can anyone help? Dare I say, does anyone have any better ideas?
I'd recommend you build the source yourself. It's very straight-forward to do. Especially considering Sqlite offers amalgamation source.
Here are the compiler pre-processor defines I use for a 64-bit release build:
WIN64 NDEBUG
_WINDOWS
_USRDLL
NO_TCL
_CRT_SECURE_NO_DEPRECATE
THREADSAFE=1
TEMP_STORE=1
SQLITE_MAX_EXPR_DEPTH=0
Here are the compiler pre-processor defines I use for a 32-bit release build:
WIN32
NDEBUG
_WINDOWS
_USRDLL
NO_TCL
_CRT_SECURE_NO_DEPRECATE
THREADSAFE=1
TEMP_STORE=1
SQLITE_MAX_EXPR_DEPTH=0
The System.Data.SQLite fork has x86/x64 binaries for .Net 2, 3.5, and 4. Downloads are here.
Update:
Another possible solution is to target your application for x86 platform and just use the x86 SQLite libraries. If your application doesn't require x64 features targeting the x86 platform will greatly reduce the complexity of your deployment.

Setup targeting both x86 and x64?

I have a program that requires both x64 and x86 dlls (it figures out which ones it needs at run time), but when trying to create a setup, it complains:
File AlphaVSS.WinXP.x64.dll' targeting 'AMD64' is not compatible with th project's target platform 'x86'
File AlphaVSS.Win2003.x64.dll' targeting 'AMD64' is not compatible with th project's target platform 'x86'
File AlphaVSS.Win2008.x64.dll' targeting 'AMD64' is not compatible with th project's target platform 'x86'
How can I make my setup target both platforms like my program does?
The MSI created by the setup project (in Visual Studio) can only target one platform at a time. Your option is to either make 2 MSI's, merge them together and make a custom setup boot strapper that choose between the two.
There are some 3rd party products,like Advanced Installer for example, that can do this for you.
I ran into this too and wrote a blog post about my solution:
deflate the file using deflate.exe, naming it with a different extension (e.g. .x64)
add it to your main project as a content file
add a custom action project to your solution
add the custom action to the setup projects "Install" custom actions
inflate the file inside the custom actions Install method using
System.IO.Compression.DeflateStream (see code above)
do a little dance around your desk, down the hall, and past as many coworkers as you care to annoy :)
The deflate.exe file can be downloaded from its repository on google code.
.Net has an "Any CPU" option. It's tempting to think of it as more of a "generic" option that's going to only use the lesser x86 features, but really it lets the JIT compiler on each machine pick the appropriate cpu type for that machine.
The only time you shouldn't use it is if you know you have dependencies or requirements that aren't good for one architecture or the other. For example: you know you need a lot of ram, you have a dependancy on a 32-bit native dll, or you want to pre-compile the app.
There's a danger here because you have a platform-specific dll dependancy. But you have dlls for both types and it sounds like you know how to pick the right one at runtime. So will the 'Any CPU' option work for you?
Open a deployment project.
In the Solution Explorer, select the deployment project.
In the Properties window, select the TargetPlatform property.
Choose either Itanium for an Intel Itanium 64-bit platform, or x64 for any other 64-bit platform (such as AMD64 and EM64T instruction sets).
At installation time, an error will be raised and installation will be halted if the target computer is not compatible with the specified platform.

Categories