If I go to project properties of a C# Console Application, its Platform is always set to Active(x86) where Platform target is x64, as shown in the img:
Can somebody tell what's the difference and how to create an app whose Platform is x64.
Microsoft made a couple of drastic design mistakes in VS2010, this is one of them. The Platform name for managed projects always used to be "AnyCPU". It is again in V2012 and up. But the default name in VS2010 is "x86".
That was a horrible choice, given that the Platform name is completely irrelevant to a managed project. Managed code runs on any platform, it is the Just-In-Time compiler that automatically converts the MSIL that the compiler generates to machine code. At runtime, not build time. So "AnyCPU" is a much more descriptive name, the jitter truly does make it run on "any cpu".
This momentary lapse of good thinking was induced by a significant change in the C++ project build model. VS2010 is the first version of Visual Studio where C and C++ projects are built with MSBuild instead of the custom build engine (VCBuild) used in previous versions. The Project selection is a Really Big deal for such projects, it selects the compiler that's used to compile the source code. Different cpus require different compilers because C++ code is directly translated into machine code.
So just ignore this, the name just doesn't matter. And above all, it has no effect at all on what the jitter does. Which requires a different setting if you want to force it to only generate 32-bit code. You found the setting that does that.
The platform refers to if you want to compile/build the project on x86 which is 32Bit architecture or x64 which is 64 Bit architecture. 64 bit app will run on 64 bit architecture, while 32 bit app can run on 64/32 Bit architecture,
regarding how to create an x64 app, you just choose x64 in your configuartion manager. refer to the following documnet for detailed explaination http://visualstudiohacks.com/articles/visual-studio-net-platform-target-explained/
Ok, Sorry in advance for the length of this answer but your question very neatly scratches on the surface of quite a lot of complexity.
Producing assemblies and native code
From the bottom up, Visual Studio/MSBuild do not produce the code that finally runs on machines that run your code. Instead they produce an assembly full of MSIL (MicroSoft Intermediary Language) which is translated at run time by CLR into native code for that machine. For assemblies that you use regularly the machine can also cache the native code in advance by using NGEN.
Every assembly can have a platform target. As Hans points out this doesn't actually do very much other than identify to the jitter what flavour your native code should be in. This indication is just a couple of bytes in the header of your assembly, and can actually be changed post-msbuild by using the corflags tool. Don't worry you don't need to ever use this. Normally during the build process, msbuild/VS will look at the platform target for each project and produce an assembly with the correct header.
Run time consumption of assemblies
Let's consider what happens when you now run your complied assembly. First, Windows identifies it as DotNet from its header and uses the CLR as a host environment for it. That environment will vary due to the version of DotNet, e.g. 2.0, 4.0, 4.5 etc and also for 32 or 64 bit. The environment will then start generating native runnable code from your MSIL assembly and start executing it.
Now all applications then call into other assemblies (at least System/mscorlib). The CLR will do its best to ensure that the correct version of these is loaded in. This can be from the their installed location (e.g. C:\Windows\Microsoft.Net\Framework...), the GAC (including NGEN versions), or from the applications current directory (see How the runtime locates assemblies). Sometimes this process will fail, because for example it can't find a required version of an assembly (i.e. can only find v1.0 when it needs v2.0) or it finds a 64bit when it needs a 32bit.
Producing applications
Back in Visual Studio there is something that most people miss. It's called configuration manager and its hidden on the bottom of the Solution Configurations dropdown in the Standard toolbar.
It basically provides us with a way to select the various flavours of attributes for all the assemblies we are building. For example here is a default Debug AnyCPU build.
At the top of the dialog there are two drops downs, the 2nd one lets you select the Active Platform.
But no-one knows about configuration manager
I assume the problem is most people don't know about this dialog and so instead if they want to create a 64bit build they will usually go into each project and change the AnyCPU build over to x64. In the past 10 yrs, I have never yet come across a code base that supports 64bit where somebody hasn't done this.
Also note, there is a special configuration that can appear called Mixed Platforms. It is supposed to handle a solution where you either have a native (e.g. C++) assembly as well as your DotNet, or when you are targetting multiple platforms such as Phone and Desktop. It can also get produced if you mix up your 32bit, 64but and AnyCPU etc.
Recommendations
Instead I recommend you do the following,
Go into configuration manager and remove all platform configurations that you aren't using. Ideally pare it back to just Debug and Release for AnyCPU. Use the Edit... on the drop downs then select and hit Remove.
Create a new Platform by selecting New... from the platform drop down. Copy it from AnyCPU.
Now for the fun bit, go through every project you have, and for each Platform ensure that it is building the correct Platform target.
And finally, Building
You can now build your codebase in one of three ways
Use the configuration manager to switch your active platform and press F5.
Use the Batch Build dialog (bottom of the Build Menu) to build the platforms you want to build.
Or use the devenv command line devenv.com myApp.sln /build "Debug|AnyCPU"
Related
I have a Program in C# under visual studio that was targeting the .NET Framework 4.5.2
It is linked with another C# project (a plugin ) that target 4.5.2. This plugin has a dll in its references, (32 bit).
The programm and the plugin build configuration are set to Any CPU
Now I changed the targeted Framework for both of them to 4.7.1.
When I launch the Programm, it fails to load the Plugin.
Looking at the dll with dependency walker it looks like it does not find two methods in the kernel32 library.
See the screenshot
I am a bit new to C# and I find it weird, and don't really understand what is happening. (How could those method have been found before and not now anymore)..?
If you reference a 32-bit DLL, you should not be compiling to "Any CPU". If you run this on a 64-bit machine, your process will run as a 64-bit process and will not be able to load the 32-bit dll. Compile at least the EXE as 32-bit. If one module in your process is restricted to 32-bit, then every module in your process needs to be 32-bit (and, if one module is 64-bit, then every module must be 64-bit).
The InterlockedExchange stuff is likely a canard sending you off in the wrong direction (see the note from #HansPassant above).
Don't host screen-shots on remote locations, that web-site is blocked for me, and likely for others as well.
Both Hans Passant and Flydog 57 answer are correct. Giving credit to Flydog57 since it was a bit clearer for a newcomer like me.
Problem I had was eventhough I activate the target Platform as x86 for the whole solution, some subproject stayed as AnyCPU. (They had no x86 Platform and I could not create one for abstruse reasons).
However, forcing everyone to x86 did it.
DependencyWalker was a bit confusing to be, as it keeps writing 64 next to the system librairies name. Coming from Linux world I interpreted it as Problem during the linking, but I understand better now.
Thank you.
I'm using Monodevelop 2.8.6.5 and trying to run unit tests constantly returns an internal error:
`ArgumentException`: Illegal characters in path
at System.IO.Path.CheckInvalidPathChars(string)
at ...
at ...
at MonoDevelop.NUnit.XmlResultsStore.GetRootRecord(string configuration...)
Basically the problem is that MonoDevelop.NUnit.XmlResultsStore.GetRootRecord is passing "Debug|x86" as the configuration, which it is then trying to create a path or folder for, and gets an exception because | is illegal. I can create a configuration that doesn't have the |, but MonoDevelop gets horribly confused. Because it assumes that means "Any Platform", so I can't make an x86 build. That means I can't run the program, but I can Unit Test it.
My current options are text hacking the .sln and .csproj files until both work or just having two solution configurations, I suppose.
More confoundingly I have yet to see a single question about this online, which seems like a guaranteed issue.
Anyone know what to do? If there's a solution - "file a bug report" is perfectly fine too.
That's definitely a bug, and your diagnosis of the issue looks correct. Please file it at http://bugzilla.xamarin.com.
Note that a solution configuration is a map to a set of projects to include in the build and their configurations to use. The name of the solution configuration doesn't have to match the project configuration. This means you may be able to work around it the bug by having the Debug|x86 solution configuration use the Debug|AnyCPU configuration of the unit test project.
There probably isn't anything wrong with this, because you probably don't actually need the platform set to x86 anyway. The explanation is rather complicated, but I'll give it a shot.
New desktop executable projects in MonoDevelop have "Debug|x86" and "Release|x86" configurations, for compatibility with Visual Studio. Having "x86" as the platform component of the configuration name doesn't actually have any direct effect on the compilation or execution of the binaries, but these particular configurations also set the C# compiler options' platform value to "x86", which sets a flag in the compiled binary. For executables, this flag means that when Windows x64 executes the binary, it uses the x86 .NET runtime instead of the default x64 runtime. For libraries, it means that the x64 .NET runtime will refuse to load the library. The Mono runtime ignores the flag completely.
AFAIK, by making executable projects target x86 by default, MS made it so that developers wouldn't have problems problems P/Invoking libraries that only existed on 32-bit Windows. Since most programs don't need to run in x64 mode, this was presumably worth the trade-off.
An x86 process can load AnyCPU libraries just fine, so new library projects always have the AnyCPU configuration name, and don't set the compiler flag. VS generally creates "Mixed" solution configurations that map to the x86 executable project configurations and the AnyCPU library project configurations.
Unfortunately, MonoDevelop is overzealous about creating matching-named configurations in all proejcts, even when they aren't needed or don't make sense. Chances are that MD created x86-named configurations for your library projects, including the NUnit test project. They wouldn't have the x86 compiler flag set, and you wouldn't need it anyway, so you could delete them and map all the solution configurations to the AnyCPU library configurations.
Note also that when MD runs the NUnit tests, it loads the test library using its own remote host process executable, which is marked as x86. So the tests will run in x86 anyway, even on 64-bit Windows.
I work with the application that has to be run in 64 bit Windows and I use OCX control that should be run in 32 bit emulation mode. I can embed this control in Windows Forms Control Library and then add reference to this library to main application in order to set another emulation mode for this control and another for whole application, but it generate another problem. In this case I get an error "Exception of type InvalidActiveXStateException was thrown". I tried to use this Windows Forms Control Library with the project that was also run in x86 and everything was ok.
Do you know in which way I can run application which contains two or more projects that one project would be run in x86 and one in x64? (Right know when each project is in another mode it can't find some assemblies)
You can't mix 32 and 64 bit code in the same process. If you absolutely must run this 32 bit control from a 64 bit app then you'd need to do it as an out of process server. Whilst this is probably feasible I don't believe it to be trivial.
Anyway, you may very well not need to do this. Since 64 bit Windows runs 32 bit apps you can make sure that your app targets x86 instead of AnyCPU and then it will run on 64 bit Windows.
I'm not very sure if this is what you're looking for, but you can create two projects for any of your current projects.
Source code lives in one of the pairs and so on, and the X64 or X86 adds all files using Visual Studio symbolic links.
Then, you don't need to maintain duplicate code and you'll only need to configure one project for X86, and the counterpart for X64 and so on.
Symbolic links are created when you try to add an existing item, and you press in the arrow and you choose "add link".
I found that this is not a solution for you (and almost wrong). Thanks to commenters.
Here is the situation : Our Dev Team has heterogeneous OS systems, scattered between 32-bit and 64-bit. This is not ideal, we are actually planning to homogenize our infrastructure, but in the meantime we have to deal with it.
The issue is that when a 32-bit developer checks out a 64-bit solution on SVN, he has to manually change the target platforms all over again to get it compiled (not to mention other side problems)
My question is : What clean (though temporary) solution could be addressed in such situation, permitting each developer to keep his default project/platform settings while checking out and in from SVN.
I guess that -at least for the first time a project/solution is checked out, a dev still has to tweak the setting manually to compile it properly. After that, according to relevant SVN filters, it is possible to ignore some settings files (which ones, by the way?)
I am open to all clever and detailed suggestions.
Thanks.
Are you checking in .suo and .user files into source control? As these should be developer specific and should not be included. Pretty sure the suo maintains the build state of the project for each user.
Another option, is execute builds from scripts. For example I have 4 different build script files wired up with autohotkey to build in the background release and debug mode version of a project. This can be configured via msbuild or nant on how you want the project's configuration to look.
This has a benefit of not tying up visual studio.
It has a downside of further work customizing your solution, but long term I think you're in a better situation.
Is there a reason you're specifically targeting solutions at 32bit and 64bit?
eg: Native, unmanaged DLLs?
If you use the "Any CPU" platform option, then .NET will natively run it in either 64bit or 32bit mode depending on what's available on the machine.
Edit:
The other option if you must set the CPU Mode statically is to set up an x86-32 and x86-64 build configuration, and then have your developers select the appropriate build configuration on their end.
I would strongly suggest figuring out what's wrong with your AnyCPU mode though, as if you don't - you need two install packages for your users based on their OS mode.
As long as you are using only managed dotnet-code (no native 32/64bit code) every body can work with 32Bit solution only on 64bit and on 32bit dev-stations. On win7-64 visual studio also is a 32 bit app.
I've got a XAML Browser Hosted Application (XBAP) project that has a dependency on another project that is x86 only. All sorts of hell breaks loose at runtime (with respect to grabbing the DLLs) if I leave the target platform as "Any CPU". However, if I switch the XBAP project to target x86, I get the following compile time error:
Error 7 - Cannot build a
platform-specific XAML Browser
Application. If HostInBrowser property
is set to 'True', either do not set
the PlatformTarget property or set it
to 'AnyCpu'.
Is there a work around for this? Or am I going to have to figure out some horrific multi-process + IPC solution for this*?
*The mere thought of which fills me with terror
If your dependent .dll don't have any links to win32 native dll's you could dissasemble it in Reflector and recompile it as Any CPU, or get an Any CPU version if possible. If it has win32 links, then I think you have to split it into multi procs as you suggest.