reading excel files from C# working well in 32 bit version server. It is not working in 64 bit version (Windows 2003 server), because excel data connection dll not supported in 64 bit version.
Is any other option available ?
In your project properties set the target platform from 'Any' to 'x86'.
Details:
In Windows x64 a process may be started as 32bit or 64bit process. A 64bit process can only load 64bit dlls and a 32bit process only 32bit dlls.
If your platform target (e.g. specified in the project properties) of your .Net application is set to "Any CPU", the intermediate code will be compiled to 32bit or 64bit code depending on the target platform, i.e. on a x64 system 64bit code will be generated.
Therefore the code can no longer load a 32bit dll.
If your code loads unmanaged assemblies you should always specify the target platform explicitly
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 recently started testing on a C# (4.0) app that uses ODP.NET (Oracle.DataAccess 4.112.3)
I set this project to target any platform and publish the app.
When I run the program on the client machine I receive:
Could not load file or assembly 'Oracle.DataAccess, Version=4.112.3.0,Culture=neutral,
PublicKeyToken=89b483f429c47342' or one of its dependencies. An attempt was made to load
a program with an incorrect format.
Like I said I've targeted 'Any CPU' and I've also embedded the Oracle.DataAccess assembly with the app.
I get this error on machines that have the Oracle client installed as well as machines that do not.
Any help is appreciated.
Like I said I've targeted 'Any CPU'
This is likely the problem.
The Oracle.DataAccess has separate versions for 32bit and 64bit systems. If you are developing on a 32bit machine, and then deploying on a 64bit OS, you will receive this message.
You could easily work around this by building your application to target x86, and deploying the 32bit version of the data access components.
As Reed Copsey said, there are two different DLLs. When you target ANYCpu, your app will run in 64 bit on a 64 bit machine, and 32 bit on a 32 bit machine. Therefore, if you want your app to work on 32 or 64 bit and run in AnyCPU mode, you should change the reference of Oracle.DataAccess to Specific Version=false and copy local = false. When you deploy to a client, they should have the oracle dll in the their GAC and it should pick up the correct version automagically.
You should perhaps check if the Oracle.DataAccess assembly has any dependencies in your machine and that it is missing in the client machine.
From debug Any cpu at top change the optin to debug X64, though internally Any CPu points to X64 only but that does not work, try to change it to x64 and it should work like a charm
I am developing application which uses ODP.NET to connect to Oracle DB. I would like to have one version for both 32bit and 64bit machines. The problem is that I couldn't figure out how to build projetc with anycpu target, seems it requires the target to be the same as ODP driver version. So it means that I need to have to versions of the same application one for 32bit and other for 64bit. But the same was not problem while using MS .NET Oracle client (System.Data.OracleClient). Is there a way to have the same behavior using ODP.NET as on MS .NET client?
Just update few years later: Oracle released managed ODP.NET client, so there's no need to bother with x64/x86 in .NET applications any more. You can find more information on Oracle website: http://www.oracle.com/technetwork/topics/dotnet/index-085163.html
The root cause is the ODP.NET's reliance on native OCI DLLs, which of course cannot be "Any CPU".
Theoretically, ODP.NET could detect the "bit-ness" of the current execution in the .NET code and then dynamically load either 32-bit or 64-bit native DLLs accordingly, but that's not how it is currently implemented.
Oracle corporation is currently in the process of implementing a fully managed provider. But until then, we are stuck with having to do separate builds for each "bit-ness".
The default option for any C# project is it will work on both x64 and x86 operating systems.
So it means that I need to have to versions of the same application
one for 32bit and other for 64bit. But the same was not problem while
using MS .NET Oracle client (System.Data.OracleClient).
This is expected....You need to release a x86 version and a x64 version, please take note, x86 application cannot reference a x64 assembly and vice-versa.
The reason the Microsoft reference was different was because its part of the .NET Framework by default.
I cannot download the file where I am at, I do believe that, ODP.NET has a x86 assembly and a x64 assembly.
The correct way is to release a x86 version and a x64 version of your program.
ODP.NET is specifically built for either 32-bit or 64-bit platform. They could have built a single library for AnyCPU which would allow it to be used in a 32-bit or 64-bit process. However, as Branko Dimitrijevic alluded to, the ODP.NET managed dll uses native libraries behind the scenes. Native libraries are platform-specific; thus requiring Oracle to build separate ODP.NET library for each platform. There is no alternative.
I have a C# application that makes use of a DLL as I need C++ to access some unmanaged functionalities of the user32 API (I cannot use PInvoke for that). I compile both the application and the DLL for x86 architectures, and everything works fine on Windows 7 32 bits. Now the problem is, on Windows 7 64 bits, the application crashes when I try to use the feature that relies on the DLL (but all the rest works fine).
I suspect that this is a 32/64 bits issue, so I tried re-compiling the DLL for x64 architectures, and now I can choose at runtime which DLL to load between the x86 and the x64. But it still crashes when I try to use the feature that relies on the DLL (which makes sense as I try to load a 64-bit DLL into a 32-bit program). I haven't tried yet to compile both the application and the DLL for x64. I suspect it would work, however it would require me to have two different installers, and I don't want to go there. Any clue?
When interoping with unmanaged code, you need to ensure your .Net app runs on the same subsystem (32-bit or 64-bit). As you've stated the DLL you're loading is for x86, force the .Net to build for only the x86 platform. This setting is found in your project's properties, on the build tab. The default is any CPU, change the setting to x86 to match your unmanaged DLL and you should be fine regardless if you run on a 64-bit or 32-bit OS.
To complete some testing I need to load the 64 bit version of an assembly even though I am running a 32 bit version of Windows. Is this possible?
I'm not sure why you would want to do this, but I suppose you could. If you don't do anything to tell it otherwise, the CLR will load the version of the assembly that is specific to the CPU you are using. That's usually what you want. But I have had an occasion where I needed to load the neutral IL version of an assembly. I used the Load method to specify the version. I haven't tried it (and others here suggest it won't work for an executable assembly), but I suppose you can do the same to specify you want to load the 64 bit version. (You'll have to specify if you want the AMD64 or IA64 version.)
From CLR Via C# (Jeff Richter):
"If your assembly files contain only type-safe managed code,
you are writing code that should work on both 32-bit and 64-bit versions of Windows. No
source code changes are required for your code to run on either version of Windows.
In fact,
the resulting EXE/DLL file produced by the compiler will run on 32-bit Windows as well as
the x64 and IA64 versions of 64-bit Windows! In other words, the one file will run on any
machine that has a version of the .NET Framework installed on it."
" The C# compiler offers a /platform command-line switch. This switch allows you to specify
whether the resulting assembly can run on x86 machines running 32-bit Windows versions
only, x64 machines running 64-bit Windows only, or Intel Itanium machines running 64-bit
Windows only. If you don't specify a platform, the default is anycpu, which indicates that the
resulting assembly can run on any version of Windows.
32 bit Windows can not run 64 bit executables without a VM/emutalor
32 bit Windows can compile for execution on 64 bit Windows
No, you cannot run assemblies that are compiled for 64-bit on a system running the 32-bit version of Windows.