I see the following error when running csi.exe:
System.BadImageFormatException: Could not load file or assembly
'xyz.dll' or one of its dependencies. is not a valid Win32
application. (Exception from HRESULT: 0x800700C1)
Compiling in Visual Studio raises a warning but compiles and runs without problems:
There was a mismatch between the processor architecture of the project
being built "MSIL" and the processor architecture of the reference
"xyz", "x86". This mismatch may cause runtime failures. Please
consider changing the targeted processor architecture of your project
through the Configuration Manager so as to align the processor
architectures between your project and references, or take a
dependency on references with a processor architecture that matches
the targeted processor architecture of your project.
So it seems I have to specify processor architecture when running csi.exe? How to do that?
Your assembly xyz.dll is compiled to only run in a 32bit process. This might be for a good reason (such as for example loading another native dll that is available with 32bit code only). In this case, use the solution presented below. It may also be for no good reason. In this case, change the target platform of xyz.dll.
The program CSI.exe (C# Interactive Compiler) is built in a way so that it will run as a 32bit executable on a 32bit version of Windows and it will run as a 64bit executable in a 64bit version of Windows.
When running as a 64bit executable, it will not be able to load an assembly that is built to only run in a 32bit process (such as your xyz.dll).
In order to change this, you can create a version of CSI.exe that runs as a 32bit process even on a 64bit version of Windows. Follow these steps:
Locate the file csi.exe, make a copy of it in the same directory and rename the copy to csi32.exe. You can find csi.exe in a path similar to "C:\Program Files (x86)\MSBuild\14.0\Bin\csi.exe"
Locate the file CorFlags.exe. You can find CorFlags.exe in a path similar to "C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.2 Tools\CorFlags.exe"
Open a commandline window as administrator.
Execute the following command using the correct paths for the two executable files
C:\Path\To\CorFlags.exe /32bit+ /force C:\Path\To\csi32.exe
You can now use csi32.exe in the place of csi.exe to run scripts that require assemblies/dlls which are only available in 32bit versions.
Related
I have a .NET 5 WPF application built for AnyCPU platform.
In the project file i have:
WinExe
net5.0-windows
The output folder contains all dll and an exe but when i run the exe on a 32 bits windows i get this message:
This version of software.exe is not compatible with the version of windows
you're running. Check your computer's system information to see
whether you need a x86 (32-bit) or x64 (64-bit) version of the
program, and then contact the software publisher.
To ease deployment and run, I want to have only 1 build and 1 shortcut no matter the target system.
So my initial solution was to run the application using dotnet.exe and having the core dll as a parameter.
dotnet.exe software.dll
The WPF application start and run fine but the console with the dotnet command line is kept open during the application lifetime.
Is there a solution to get rid of the console when I start the WPF application using dotnet.exe ?
No solution without exe file at this time, so as a workaround I found a way to produce both 32bit and 64bit exe.
In the Visual Studio build configuration manager, I added x86 and x64 platforms.
Which updated the csproj with
<Platforms>AnyCPU;x86;x64</Platforms>
Then I added in csproj
<AssemblyName>MySoftware-$(Platform)</AssemblyName>
When I build the solution, it automatically append the targeted platform to the exe and dll for the platform.
MySoftware-x86.exe
MySoftware-x86.dll
MySoftware-x64.exe
MySoftware-x64.dll
Finally, I call "dotnet.exe build" twice for both x86 and x64 using a script.
To put all this together, a 32-bit machine can run anything with a PE
set to PE32, but nothing with a PE of PE32+. A 64-bit machine can run
your file in 64-bit mode as long as 32BIT is 0, but if 32BIT is 1 then
it must use WOW64.
https://illuminatedcomputing.com/posts/2010/02/sorting-out-the-confusion-32-vs-64-bit-clr-vs-native-cs-vs-cpp/
Why would you want to compile a .NET assembly specific to 32-bit or
X64, or IA? Usually because you're P/Invok'ing into a x64 specific
native dll.
The interesting things that corflags tell us are these:
CLR Header: The compiler version...2.0 is .NET 1.1, 2.5 is .NET 2.0
and 3.0 is .NET 3.5. Don't ask. ;)
PE (Portable Executable): PE32 is 32bit and PE32+ is 64-bit.
32BIT: Are we asking to force 32-bit
execution or not?
www.hanselman.com/blog/32bitness-and-64bitness-and-migrating-dasblog-on-iis7-and-aspnet-under-vista64
I'm creating mixed 32-bit/64-bit installers using advance installer, according to this guide Advance Installer Guide for 32-bit/64-bit installers I should seperate 32-bit and 64-bit assemblies. My question is what if my visual studio build is set to "Any CPU", can I use single assembly file for both 32-bit and 64-bit or do I have to create seperate 32-bit and 64-bit assemblies and put them in 32-bit and 64-bit folders in advanced installer.
Additional Information:
My application does not use any DLL references.
You can leave your project building as AnyCPU, and deploy the same assembly to x86 or x64. Advanced Installer's wizard for creating a Mixed Package will ask for files that are x64 only, x86 only, and shared files. Your AnyCPU assembly would be a shared file to deploy for both x86 and x64. Advanced installer puts the shared files in a common component, and the others in their respective 64-bit and 32-bit components.
The Mixed Package uses bootstrapper that contains both an x86 and x64 msi. Another option for deploying your AnyCPU assembly is to create an x86 msi as it would run on both platforms. The x86 msi would deploy your AnyCPU assembly to Program Files (x86), but when run on an x64 machine it would run as an x64 process.
If the assembly uses unmanaged 32- or 64-bit code, you have to compile two respective versions. Otherwise, with "Any CPU" you can use the same assembly for both platforms.
Your project shouldn't go under either of them and should instead likely be put under MainFeature.
The important thing is under Install Parameters you have set the Package Type to "Mixed 32/64-bit matching the platform"
I want to develop an embedded application using Colibri iMX6 module (Linux OS). I have Ubuntu 16.04 running on virtual machine and have monodevelop installed. I want to write my application in C# and cross compile it using mono for arm processor.
Can someone guide me through the process of creating an arm executable file using mono?
Thank you in advance.
One of the great things about .NET is that you don't need to cross-compile anything. CIL assemblies are, by nature, platform- and architecture-independent -- unless your assemblies link against platform-specific assemblies (such as the WPF assemblies on Windows), or if the project file build settings target specific processor architectures (like x86 or x64/x86-64). If you don't link to any platform-dependent assemblies (unless they exist on your target platform) and target the AnyCPU architecture, then assemblies you build on one system should run anywhere that mono is available.
Our Teamcity agent is running on a 32bits OS for now and this was not an issue up until now (we now have an x64 applications to build in there).
I heard its possible to compile x64 applications on a 32bit OS but I've never did it. What would be the step required to have Teamcity build a specific project in x64 - Ideally using MSBuild?
When I set my project's MSBuild property "Run Platform" to x64 my agent give me the following warning: "Unmet requirements: DotNetFramework4.0_x64 exists"
As a side note: we will eventually move the agent to a 64bits OS but I would like a short term solution.
I think the Run Platform for MSBuild in TeamCity is for what version of MSBuild to use, it's looking for MSBuild.exe in the C:\Windows\Microsoft.NET\Framework64\v4.0.30319 folder, when you're on a 32-bit version of Windows, and that framework isn't installed. However, the 32-bit version of MSBuild can invoke the C# Compiler that can still produce x64 assemblies, even on your 32-bit machine.
What you want to do is do a Run Platform for x86, but pass /property:Platform=x64 as one of your commands. If you don't have a x64 Configuration, you may considering trying to pass it /property:Platform="Any CPU". However, Any CPU would only be guaranteed to work if all the assemblies you reference in your project are set the Any CPU as well. Alternative, you can create a custom configuration where all your assemblies are specified x64, and pass that via command line to MSBuild.
Keep in mind if any of your projects are C++, you will need to make sure you have the x64 compilers installed, as I don't think they're installed by default.
My program (a console application) references several other assemblies (many open-source libraries). I built the assembly with the "Any CPU" option set (using VS2008). When I start the assembly from a 64-bit command prompt on a Windows Server 2008 x64 machine the process always starts as a 32-bit process!
I looked through my references and it appears as though I have a reference for a 32-bit assembly referenced. Could this single reference cause the entire assembly to start as 32-bit?
Also, I use ILMerge to merge all of the referenced assemblies into a single assembly. Maybe that has something to do with it?
Could someone help me figure out what is going on here?
If you need to load a 32bit assembly, the entire process will need to be 32bit. You could target "Any CPU" for your main application, but then it will run 64bit, and fail at runtime when it tries to load the 32bit assembly.
ILMerge is smart enough to switch the main entry assembly from AnyCPU to x86 if you have an x86 assembly as part of your merge, to prevent this from being a problem.
If you want to run 64bit - you'll need to have all of the assemblies be 64bit or AnyCPU.
Yes, this is likely your problem. I would rebuild the assembly as "Any CPU".