views:

1269

answers:

4

I want to create an x64 application.

When I want to add a reference for example to system.data in window AddReference under tab .NET I see only x86 DLLs, and I need 64 bit versions.

I have Windows Server 2008 x64 with Visual Studio 2008.

I created a project and I set x64 under Configuration Manager.

What can I do to force Visual Studio to point to the correct DLLs (from C:\WINDOWS\Microsoft.NET\Framework64 instead of C:\WINDOWS\Microsoft.NET\Framework)?

+1  A: 

Short answer: Don't worry about that - just add the reference and .NET will load the correct assembly at runtime.

Long answer: Pure .NET assemblies (such as all the system ones) are not actually x86 or x64. They are in an intermediate language (MSIL), which gets compiled ("just in time") to native x86 or x64 code when run. The path you see in the Add References dialog is not actually added to the project (well, it might be, but only as a "hint"). The project actually refers to the strong name of the assembly - its name, version, culture and public key. At runtime .NET will use this information to locate the assembly and it may well be loaded from a different path than where you added the reference from. It's a bit counter-intuitive, but that's how it works.

You can check this for yourself if you watch the debug output window when you start the application: you will see something like:

Loaded 'C:\WINDOWS\assembly\GAC_64\System.Data\2.0.0.0__b77a5c561934e089\System.Data.dll', Skipped loading symbols.

... even though the reference path was probably something like c:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\System.Data.dll

Evgeny
Well I could live with warning but I use sgen during compilation and it throws an error when I point to x86 dlls.
Darqer
+1  A: 

The compiler uses reference assemblies only to load type information. That comes from the assembly's metadata. The metadata for x64 specific assemblies is identical to that for x86 assemblies. So, it doesn't matter. The compiler does generate a warning for it, you can freely ignore it if you know the 64-bit version of the assembly is installed in the GAC. It will be when you've got the 64-bit version of the framework installed.

One thing you probably should not do is select x64 as the Platform Target for your project. This is only required if you must use unmanaged code that is only available in 64-bit machine code. COM servers, usually. That is very rare, the typical problem is only having the 32-bit version available. Leaving the target set to Any CPU is the better choice, your binary will run on either platform. And the compiler warning will disappear.

Hans Passant
Well I could live with warning but I use sgen during compilation and it throws an error when I point to x86 dlls. I want code to run in x64 when I set to any CPU and deploy on x64 bit server will I run in this mode?
Darqer
Why on Earth would you not mention this in your question? I can't guess what the error looks like.
Hans Passant
I should mention but I thought that it doesn't matter at this time. It looks like:SGEN : error : An attempt was made to load an assembly with an incorrect format
Darqer
Use the 64-bit version of sgen.exe, it located in the bin\x64 folder of the Windows SDK install directory. Setting Platform Target to Any CPU is the generic workaround, you haven't yet given any evidence that you require x64.
Hans Passant
I have 64bit 3part dlls so I need 64 bit code. I'm using this x64 sgen.exe and I get this error message. (There is my another question about it here http://stackoverflow.com/questions/1980278/sgen-exe-x64-net-c-fails-with-assembly-with-an-incorrect-format ). Temporary solution I found is to set path to Framework64 in project properties, but I wonder wheter it might have some influence on app deployment on client machines.
Darqer
Contact the 3rd party and ask them to isolate 64-bit specific code in its own assembly.
Hans Passant
But why it is not working I can't believe that MS has such bug in VS.
Darqer
Bug? What bug? x64 DLLs can only be loaded by x64 tools.
Hans Passant
Kind of bug because in x64 bit VS wants to give me references to x86 dlls. Here I return to my question - Why during compilation VS looks into Framework x86 dll instead of x64 and what can I do to change this behavior. I set Reference Path under project properties to (c:\windows\Microsoft .net ...\Framework64) and I can compile, but is it safe solution or is there better way to do it.
Darqer
Reference DLLs? I thought this was a problem with sgen.exe. I'm not getting good info to help you, good luck with it.
Hans Passant
Your advices were inspiring, I appreciate your help. During compilation VS uses sgen so when I say that compilation succeeded then also sgen succeeded. The problem is that sgen (x64) is not working correctly when I add System.Data to the project. By default(in Add References->.NET) I add x86 assembly (Path is set to Framework not Framework64) so I get this warning and later sgen error during compilation. Question is there a way to force VS to point to the x64 assemblies by default.
Darqer
+2  A: 

Running into the same problem, and yes I also consider it a bug from MS. You'd think either the x64 or x86 sgen.exe could handle msil assemblies, especially when you have to reference framework assemblies.

I would prefer building msil assemblies myself, but have a native-built 3rd party assembly tossed into my mix. When the project tries to generate the serialization assemblies using the x86 sgen.exe, it complains that the 3rd party assembly is "the wrong format."

When I use the x64 sgen.exe, it complains that System.Data is "the wrong format". But I don't have the option of pointing at the Framework64 version in the .csproj file.

Mark
Through trial and error, I eventually found that System.Data, System.Web, and System.EnterpriseServices (and possibly many more I'm not using) are framework assemblies with platform dependencies. Copying the sgen line from the solution build output, changing it to the x64 sgen, and then changing the /reference: entries to Framework64 one at a time, I eventually got x64 sgen to work, but man what a nuisance.
Mark
I think that adding framework64 directory into ProjectProperties->Reference Paths might also help.
Darqer
+1  A: 
<Reference Include="32bit.dll" Condition="'$(Platform)'=='x86'"/>
<Reference Include="64bit.dll" Condition="'$(Platform)'=='x64'"/>

Look at this answer:

http://stackoverflow.com/questions/1997268/how-to-reference-different-version-of-dll-with-msbuild

Bertvan