x86 TargetPlatform with XBAPs - c#

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.

Related

InterlockedExchange method of kernel32 not found when linking a dll to a c# project

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.

Console App Platform always "Active(x86)"

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"

Monodevelop crashes on Windows using nunit test due to | character

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.

Configure WPF client to run 64bit

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.

Deploying a .Net App Source Control (SVN) over 32-bit AND 64-bit dev stations

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.

Categories

Resources