x86 DLL Works But Not x64 DLL - c#

I'm trying to include System.Data.SQLite with my project which is coded in C# and uses .NET Framework v4. I'm a little confused... I'm running Windows 8.1 x64 and the platform target for the project is set to Any CPU. If I include the x64 version of System.Data.SQLite.dll then I get an error saying The type or namespace name 'SQLite' does not exist in the namespace 'System.Data' (are you missing an assembly reference?). However, if I include the x86 version of System.Data.SQLite.dll then it compiles fine. Shouldn't it be the other way around (shouldn't the x86 version not compile)? Since the x86 version works, then can I include just the x86 version with the compiled project? If I need to include both the x86 and x64 version of System.Data.SQLite.dll (as well as SQLite.Interop.dll) then how might I go about doing that? I should also note the version of System.Data.SQLite is v1.0.94.0 (and is for .NET Framework 4).

Unless you need the x64 version you can include just the x86 version and build your project as x86. This is safe for most projects, unless you need the 64-bit address space.
You should use AnyCPU only when your app is purely managed and doesn't have any dependencies on a specific architecture. When using native code such as SQLite the app should always set the specific platform target.
The reason the x86 version of SQLite works rather than the x64 is that in modern versions of Visual Studio the AnyCPU configuration defaults to /platform:anycpu32bitpreferred rather than to /platform:anycpu. With anycpu32bitpreferred the app will use 32-bit mode if possible and will use 64-bit mode only if 32-bit mode is not available.

For such cases, there's no better technology than Nuget ! You can use directly the SqlLite nuget package, which is explicitly compatible for x86/x64. I tried it in AnyCpu, x86 and x64, and I have no compilation error at all in both cases.
So you just have to remove your old references, and right-click on the project references, and choose "Manage NuGet Packages", then search for System.Data.SQLite.
And moreover, you will be forever up-to-date :)

Related

Requirement of 64-bit version DLLs in a .NET project

Introduction
I'm working on a .net project, in which I'm using some 32-bit version DLLs. The list of DLLs are:
System.*
Microsoft.*
AWSSDK.*
Npgsql.dll
Newtonsoft.Json.dll
Some other dlls from other vendors
(The list of DLLs is actually too long to be attached in this post without making it too long.)
Requirement
I require 64-bit version DLLs only and at the moment, I only have 32-bit version DLLs in our hand.
Things that I have tried
I verified the DLLs' version using a tool named SigCheck.
I tried to find/convert the DLL version using the following methods:
I searched on the internet and NuGet Package Manager but, I was not able to find 64-bit DLLs.
I tried recompiling the project to 64 bit by changing below setting under project properties:
- Build -> Platform Target -> x64
After compilation, the project DLL got converted to 64-bit. However, the remaining project DLLs' version didn't change.
Question
I would be grateful if someone could share documentation links/steps to convert 32-bit version DLLs to a 64-bit version?
or
Could someone please send us a link to find recompiled 64-bit version of the given DLLs?
Please note that I'm using .NET framework 4.6
Managed .Net dlls are usually platform agnostic. So for most of the libraries you do not need to worry about it, just use nuget to refer to the libraries and you should be good to go. The JIT compiler will take care of compiling the assemblies to 64/32 bit depending on the platform.
The platform target you specify when compiling a dll only sets a flag in the dll. This flag can be changed with CorFlags, but if it has a 32-bit flag it might be for a reason.
The big problem usually occurs when you need to use native assemblies (i.e. c++ dlls). These need to be platform specific. The best solution is to get 64-bit versions of these DLLs, but you would need to get them from the vendor of the libray and update the references in your projects. The most common workaround if you can not get a 64-bit version is to run the library in a separate 32-bit process.

Microsoft .NET Framework missing during making exe setup file form project

During making setup file i am getting these errors i think all problem is due to missing of .net Framework in dependencies folder
The problem is not with your .net framework. Its with your version of log4net. The version you have included is exclusive to x64 systems while you are trying to make a installer that works with x86 systems.
Either switch your project architecture to x64 (you can do this in the build properties of your project file). Or find a version of log4net that allows for x86 execution.

How do .NET Framework classes reference native Windows DLLs without becoming bitness-specific?

I've read many questions and answers indicating that if I want to link my C# project against native libraries, I can't use AnyCPU platform target but must make separate 32- and 64-bit builds, each linked against the native DLL of the appropriate bitness.
This makes me wonder how the .NET Framework assemblies themselves are, or at least appear to be, built for AnyCPU. That is, when adding a reference to my GUI application, why don't I have to pick the 32-bit or 64-bit version of System.Windows.Forms? I thought this might just be some Visual Studio magic that would resolve to the appropriate GAC subdirectory (GAC_32 or GAC_64), but I searched for System.Windows.Forms.dll in the GAC and found it in:
C:\Windows\Microsoft.NET\assembly\GAC_MSIL\System.Windows.Forms\v4.0_4.0.0.0__b77a5c561934e089\System.Windows.Forms.dll
Note the "GAC_MSIL". So how does this DLL manage to wrap a native 32-bit API yet remain linkable in a 64-bit application? And why can't I use a similar strategy to make a single C# DLL that links against a native 32-bit library yet remains runnable in 64-bit mode?
Option 1: In GAC you may register 2 versions of assembly one 32 and one 64 bit with exactly same names. Oracle DB Driver for .NET uses this strategy.
Option 2: With your assembly that will be AnyCPU deploy two versions of native DLL and choose proper DLL at runtime (SQLite works like that). As it turns out .NET Framework is intelligent enough to load proper version of native DLL via P/Invoke (Using a 32bit or 64bit dll in C# DllImport)
I had the same problem and ended up using Fody Costura
DLL Files will be shipped as embedded ressources and the lib takes care of the bitness.
You could find an example for SQLite here
The problem I have encountered was that your application needs to have access to the Windows Temp folder to create the assemblies from the ressource. If you dont need it, you could disable it using a config setting createtemporaryassemblies

Does changing build options move where an application is located in the Local Machine Software registry key?

I have a solution where the executable's target platform was initially set to x86, many other projects were set to AnyCPU, and included 3 projects in .Net 3.5 (everything else .Net 4.0). I presume this is why the installer wrote to the HKEY_LOCAL_MACHINE\SOFTWARE registry key.
Recently, I fixed some issues and now all projects are .Net 4.0. Additionally, I set the executable target platform to AnyCPU. I found the application was now installed in HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node.
[sidebar - we have p/invokes - DllImport attributes - that did not
specify a CallingConvention. When this was modified both in
managed and unmanaged code to specifiy Cdecl and __cdecl, we were able to
upgrade dependent projects to .Net 4.0 without receiving a PInvokeStackImbalance exception.]
We develop currently with VS2010 on Windows 7 (64-bit) machines.
My question is: Did the installer write to \SOFTWARE\ initially because some of the projects were .Net 3.5?
Also, if this application is intended to be installed on WindowsXP (32-bit is expected to be supported) machines, is the registry key problematic? Better yet, what should I look for in build options that ensures compatibility on WinXp 32-bit systems?
Only a 64-bit installer will avoid Wow6432Node on a 64-bit operating system. In a Setup project, that's set by the TargetPlatform property of the installer, it defaults to "x86". Change it to "x64" if you changed the C# EXE project's Target platform to AnyCPU. This will also ensure that your program is installed to c:\program files and not c:\program files (x86).
You will thus need to maintain two installers. Bit of a headache, you can avoid it by setting the C# EXE project's Target platform to x86 so both the installer and your program access the key in Wow6432Node.
The pinvoke problem is normally the other way around, 64-bit code has only one calling convention and there's no difference between cdecl and stdcall.

Compiling x64 on 32bits version of windows (Teamcity)

Our Teamcity agent is running on a 32bits OS for now and this was not an issue up until now (we now have an x64 applications to build in there).
I heard its possible to compile x64 applications on a 32bit OS but I've never did it. What would be the step required to have Teamcity build a specific project in x64 - Ideally using MSBuild?
When I set my project's MSBuild property "Run Platform" to x64 my agent give me the following warning: "Unmet requirements: DotNetFramework4.0_x64 exists"
As a side note: we will eventually move the agent to a 64bits OS but I would like a short term solution.
I think the Run Platform for MSBuild in TeamCity is for what version of MSBuild to use, it's looking for MSBuild.exe in the C:\Windows\Microsoft.NET\Framework64\v4.0.30319 folder, when you're on a 32-bit version of Windows, and that framework isn't installed. However, the 32-bit version of MSBuild can invoke the C# Compiler that can still produce x64 assemblies, even on your 32-bit machine.
What you want to do is do a Run Platform for x86, but pass /property:Platform=x64 as one of your commands. If you don't have a x64 Configuration, you may considering trying to pass it /property:Platform="Any CPU". However, Any CPU would only be guaranteed to work if all the assemblies you reference in your project are set the Any CPU as well. Alternative, you can create a custom configuration where all your assemblies are specified x64, and pass that via command line to MSBuild.
Keep in mind if any of your projects are C++, you will need to make sure you have the x64 compilers installed, as I don't think they're installed by default.

Categories

Resources