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.
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 know how to change the Platform target of my C# project from here: http://msdn.microsoft.com/en-us/library/ms185328.aspx But my question is: Is it possible to target platforms x86 and x64 at the same time in visual studio 2012, so i will have two folders in my Debug directory like this:
Bin\Debug\x86(x86 dlls & exe)
Bin\Debug\x64(x64 dlls & exe)
So i always have the two platforms assemblies available on every build of my project.
EDIT:
using Any CPU: When build my application using "Any CPU" platform and run it on a 64-bit operating system, the process has the extension 32* in Task Manager which means that it is a 32-bit assembly not 64-bit
I tried to build my application using "Any CPU" and when i run it on x64 windows, i found that the process in Task Manager has the extension 32*
You are being confuzzled by the solution configuration name. It defaults to "AnyCPU" for managed projects in VS2012 and up. Which is a fairly accurate name, a .NET project can run on any CPU thanks to the jitter. These configuration names are however only relevant to native projects (C and C++), they pick the kind of compiler that is used to build the project. Since they get built straight to machine code, a different compiler is needed to generate x64 code.
You can select the kind of jitter that's used at runtime, a modern version of Windows is able to run both 32-bit and 64-bit processes. But that's an entirely different setting, it doesn't have anything to do with the configuration name.
Right-click your EXE project, Properties, Build tab. Ensure that the Platform target setting is AnyCPU, untick the "Prefer 32-bit" checkbox if you see it. That removes the jitter choice forcing, your process will now be a 64-bit process on a 64-bit version of Windows. And still run on a 32-bit version, thanks to the jitter. Repeat this setting change for the Release configuration.
Do beware that you'll have to test this, there are various subtleties involved, related to the file system and the registry views that are different depending on the bitness. Having to test both flavors is the one of the reasons why .NET projects default to 32-bit mode.
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"
We have some code that uses Entity Framework against a DB2 database.
When we try to use transaction scope, we get a message "The Under lying provider failed on Open".
We only get this error when to run from the WPF client.
We do not get this error when we run from a unit test.
The DB2 provider is 64bit
The difference that we have been able to find is that the unit test is configured as Any CPU, but the WPF project is configured as x86.
The problem is that the Visual Studion UI does not allow us to select anything other than x86 for the WPF project.
Is this a limitation of WPF projects? If not how do we configure a WPF project as Any CPU?
Perhaps you are confusing the Visual Studio C# Platform with the Platform target?
Each Visual Studio C# project can be built to one of several platforms. This allows you to use the same project to build to several hardware platforms like 32 and 64 bit Intel/AMD CPU or even a different CPU like Itanium.
However, when you create a new project it will by default only contain a single platform, and in your case you also want to build to only a single platform, i.e. x64. For new projects the platforms used by Visual Studio are these:
A library project (including a test project) will have the Any CPU platform.
An executable project (including a WPF project) will have the x86 platform.
What is slightly confusing is that these platforms are just names hinting at what is actually built. You control what is emitted by the compiler in the Build tab of the project settings. Here you can set the Platform target to values like Any CPU, x86 or x64.
You will have to set the Platform target to x64 in your WPF project.
To fully configure your platforms you will have to use the Configuration Manager which is on the menu Build -> Configuration Manager.
There is no such limitation. You can select target in Platform Target combobox on Build page of project properties
The only x86 I wasn't able to change was the Platform, which to be honest I have no Idea what it is. but as you can see I can select x64 as the Platform target, are you sure you don't have such option?
In the latest version of Visual Studio (at least 2019) in the project properties, in the build settings, there is an option for the platform target to prefer 32-bit.
You might want to uncheck it otherwise your app will run as x32 even on a x64 machine.
The solution to this problem is very simple.
We have copied copied 64 bit console PowerShell.exe to debug folder of the current VisualStudio Project and provided the same path (.\debug RR .\debug) to trigger the powershell script, and it works fine.
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.