Problem with compilations projects in x86 and x64 - c#

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.

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.

Building two .exe files in C# One 32 bit and the other 64 bit

I am working on something that requires the program to build as 32bit and 64 bit. So basically I want a 32bit MyProgram.exe and then MyProgram.x64.exe in my folder when I build the whole thing. Is this possible? I am not sure how to do this. When I just build it, it just builds a 64 bit MyProgram.exe because I am running on a 64 bit machine, but I want two exe files. Is this even possible? I am using Visual Studio 2013 express, I am not sure how to mess with the settings to do this. Or something that has to do inside my code?
You can build 64 bit or 32 bit versions of programs by setting up several build configurations:
Build -> Configuration Manager ...
Set the "Active solution platform:" to either x86 or x64 as appropriate.
Each build will have to go into it's own set of output folders but you can create a post build step to copy the exe (and any other files) where ever you need it to be.
Then, while developing and debugging you can pick the appropriate target and build both configurations when you want to release a new version.
If you want to do it by the click of the button, you need to specify to build it as a post-build event.
If you use Visual Studio Premier+, you can use Build->Batch Build to achieve this.
When you're using a JIT'd language, you can tell the JIT compiler which platform you prefer, but it's technically up to the JIT compiler. The .exe files on your disk are [MS]IL and not an actual executable in any specific platform as you might get with a C/C++ compiler.
This of course assumes you haven't done anything special such as run NGen or other post-processor.

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"

Simple C++ .dll called with pinvoke; Works for me, but no one else

I do not know anything about C++, but I figured out enough to get a .dll written for a specific purpose, because there was some code I could not get C# to do.
So I created this DLL using Visual Studio 2013 -> Win32 Project -> Dynamic Link Library as the type, selected "Empty Project", etc.
Now I go over to my C# program and I have pinvoke sections to call this dll by name (Legacy.dll). I compile the DLL from C++, and copy/paste it from the /release folder to the /bin/release and /bin/debug folder of my C# application, and run the C# application.
It works fine. I have no issues.
However, when I send the files - the .dll and the .exe to other people, it tells them it cannot find the very same DLL. But it is clearly there, it is clearly working for me....
So what could be the problem? I am compiling both the C# program and the DLL to 32-bit.
UPDATE
The problem was that my users had the C++ libraries, but it had been sneakily updated to need the 2013 ones, which did not appear in my first search. I had to do an EXPLICITLY specific search to find this.
What's your operating system? Are you running a 32 bit or a 64 bit version of Windows? For .NET programs to load 32 bit native DLLs you'll have to ensure that you set the architecture of your .NET project to "32 bit" as well. By default it's on "Any CPU", which will pick the architecture based on the computer running the program. If you run the program on a 64 bit system, it will expect the native DLL to be 64 bit as well (which will cause the problem).
I know this sounds silly, but are you checking for the DLL in your C# program? (Sometimes users can be... 'interesting')
For example:
void Initialize()
{
var path = Path.Combine(Environment.CurrentDirectory, "Legacy.dll");
if(!File.Exists(path))
{
// Alert the user that the accompanying DLL is missing...
}
}
Other than that I would check architecture. Are you on 32-bit while they are on 64-bit OSes?

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