So there are couple of questions asked on this matter. There's x86, x64 secondary project that references another project created on x86 and based on a third party .dll built on x86.
The entire DLLImport and marshal call com wrapper was created using an upgrader tool. It upgraded VB6.0 into .Net code. The final .exe is installed and run in every PC as long as it is released using a x86 build. But it fails when build is on AnyCPU configuration.
When AnyCPU build is done and programme is executed the code keeps throwing an error on third party .dll and complaints it can't find the .dll. None of these issues persists when build is on x86. This is a practical issue as the application is meant for a device on Windows Embedded Standard OS and most Windows OSs from Windows XP onwards.
Error :
System.DllNotFoundException was unhandled HResult=-2146233052
Message=Unable to load DLL 'posLTD.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E)
Source=ProjectOne TypeName="" StackTrace:
at PorjectOne.PInvoke.UnsafeNative.POSLTD.ConnectToDevice(Int32 nMachineNo, String& strIpAddress, Int32 nNetPort, Int32 nTimeOut, Int32 nProtocolType, Int32 nNetPassword, Int32 nLicense)
What can be done to solve this? Could this be the device OS compatibility issue?
Some of the third party libraries are created in such way, that they can not be compiled for any other architecture.
For example, at least theoretically you could use exactly same part of code in x86, x86_64 and ARM(eg. Universal App), if you wrote it from scratch using .NET. But if the library is compiled only for x86(be it bad will of developer or optimalization), it can only be used by applications with same architecture. A fine example of this is SQLite, which is a pain in the back for any Windows Phone 8 developer - you must have both x86 for debug in emulator and ARM for production(AFAIK, at least we never found a way to have only one).
Related
I've been chasing this problem for a few days now. I've developed a .NET 5 solution which works perfectly on my develop laptop. It consists of 3 projects (2 class libraries and a wpf project). Deployment is made via a Visual Studio 2022 installer project.
One of the class libraries references some third-party 64 bit dlls for which I have no control. Deployment target on all projects and installer project is x64 (even the "TargetPlatform" property on the installer project).
The program behaves as expected on Windows 10 Desktop OS (my dev laptop and 2 other co-workers laptops), however, when installing the program on a Windows Server 2019, I get the following exception (with xyz.123.abc being one of the third-party dlls):
System.BadImageFormatException: Could not load file or assembly 'xyz.123.abc, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. An attempt was made to load a program with an incorrect format.
Note that the exception message does not include the "or one of its dependencies" part that I've read on other questions.
As I have no direct access to the deployment server, I set up my own Windows Server 2019 instance (with the same conditions as the deployment server) on VirtualBox and was able to reproduce the problem. It also reproduced on a Windows 11 Desktop OS.
The third-party dlls are exposed via the installation of a Program, which for testing purposes I also installed on my VM OS, but still getting the same problem.
I've made sure the .NET 5 desktop runtime is 5.0.17 on both dev, VM and deployment PCs. All environments are 64 bits as well.
As a side note, all other features of my program work as expected on all environments.
1st edit: I was able to reproduce on my dev PC by changing target platform to x86... Expected behavior since the third-party dlls are 64 bit, makes no sense to fail at runtime x64 still.
If anyone runs into this problem, check if your 3rd party dlls rely on VC++ redistributables.
In my case, I was missing VC++ 2013 redist. Which I downloaded from Microsoft directly.
Managed to find out using Dependencies
I'm developing an application that uses a plugin mechanism to load libraries. Usually the hosting application runs as 64bit application.
So far everything worked as expected. x64 assemblies could be loaded, AnyCPU could be loaded and x86 assemblies failed. That is - until someone came up with the idea and created an x86 Console Application - and it could be loaded as well.
Why is it possible to load an x86 console application assembly (exe) from a 64bit host process, but it fails to load an x86 library (dll)? Just for clarification - I'm not trying to load x86 dll's and not intend to - just curious why it's allowed to load x86 applications.
(If anyone is interested I can attach the sample code that I used)
The response to this was given in Microsoft Connect some time ago... however I can't seem to find the link.
I did, however, find a thread where they reference it with the response here.
Quoting:
Hi. Thank you for reporting the issue. It looks like you stumbled on an implementation detail - we do not use LoadLibrary for executables and it looks like in this case it does a validation that we do not. I cannot say this difference was the intended behavior, however if we were to to add an additional check now we could break someone, and the issue does not seem serious enough to take the risk.
I have a 32bit compiled dll that contains vb6 code. On my previous os, which was windows 7 64bit, i was able to register and run this dll fine within my c# application. Now, running windows 8.1, when i try to register the same dll, it registers fine, however when i try to read the dll in my code, i get:
Retrieving the COM class factory for component with CLSID
{D19A00C4-A7F9-4E14-A5E1-D060B7EB57F3} failed due to the following
error: 80040154 Class not registered (Exception from HRESULT:
0x80040154 (REGDB_E_CLASSNOTREG)).
The 32bit dll (compiled as Interop.VB6Class) is used in a c# class
that is build against x86.
I have tried both regasm from my 64bit folder and the 32bit folder, no luck
When i run Dependency Walker (a nice little application that checks if all your dll's dependencies are available and that your cpu version for the dll and its dependencies match), I still get the message "Modules with different CPU were found".
I have followed numerous links and advice, so if anyone can help me, I would accept you as my savior and forever call you king.
Just a suggestion, but are you 100% sure that your project settings are correct. Your Platform Target should be x86 and the Prefer 32-bit check box should be ticked. Also are you running the Debug version or the release version?. You need to set your 32 bit settings for both environments. For the command line version print out the following to ensure your environment is correct.
Console.WriteLine("OS {0}, Process {1}", System.Environment.Is64BitOperatingSystem, System.Environment.Is64BitProcess);
I know it's a long shot but it might help in finding the root cause of the problem.
I have a delphi dll which i call using interop services in my web app. The The web app im calling the dll in Platform target is set to any cpu.
When i test it in my console app which Platform target is x86 it loads and calls the dll with no errors. If i change the console apps platform target to any cpu it gives that same error. I cannot change the platform target of the web app. How can i overcome this?
Is it that the delphi dll is targeted at using x86. Can i compile the delphi project to use any cpu in Borland Delphi 7. Help is much appreciated.
Here is my import statement-
[DllImport(#"Decoder.dll", CharSet = CharSet.Unicode)]
static extern Int32 CALinkDecode(
string sCode,
out int SubscriberID,
out int MailshotID,
out int LinkID
);
Int32 retvalptr = CALinkDecode(sCode, out cas,
out cam, out cal);
You have two options,
Upgrade to newer Delphi releases, so that you can recompile your library project to x64. Then it can be loaded.
Stick to x86 compilation, and force the web application to run in 32 bit. If the web application is hosted in IIS, you can change the application pool setting.
http://www.codeproject.com/Tips/325824/Running-a-32-bit-application-under-IIS-on-a-64-bit
Clearly you have a 32 bit DLL which cannot be loaded in a 64 bit process. Either make a 64 bit version of the DLL, or configure IIS to host your DLL in a 32 bit process.
However, I suspect that your DLL is not needed at all. You appear to be using it to perform some trivial text processing. It's probably going to be simpler just to port that to .net and avoid all this complexity. Once you've done this, you'll be free of this dependency for good.
I wrote an application that uses sqlite and it works great on most of the systems. It is written in C#, and the only non-framework assembly is sqlite, which is included by System.Data.SQLite.dll .
I deploy it the same way on all of the machines (copy pasting the exe file, the database file and the System.Data.SQLite file). It works great for all my PC's and most of the PC's I've tried.
But then I've got reports that for some people it throws the following exception:
Could not load file or assembly
'System.Data.SQLite, Version=1.0.65.0,
Culture=neutral,
PublicKeyToken=db937bc2d44ff139' or
one of its dependencies. An attempt
was made to load a program with an
incorrect format.
Now I've made sure the dll file is in the same folder than the application exe file. It's the same dll, with the same version as stated in the exception message above.
I was really confused by this, so I created a fresh virtual machine, installed windows 7 professional on it, and just copy pasted the files, and the thing worked. So if it works on a fresh windows, I can't imagine what the other PC's could be missing...
Note: Two of those machines where the project throws the exception are also running windows 7 proffesional.
I would really appreciate any help on this, because I'm fresh out of ideas...
Here's a possibility: Is the difference between the working and not-working machines 32-bit vs. 64-bit? Are you building for "Any CPU", when you should be building for just the bitness of your external DLL?
It is possible that the machines that throw the exception are running a 64-bit version of Windows and that your program is using the AnyCPU configuration. The System.Data.SQLite DLL is a two-faced beast: a managed part and a native-part. It could be that the native-part is responsible for the exception.
See this question for more info.
Have you checked whether the target system is 64-bit or 32-bit?
It might be that one of your dependencies requires a 32-bit version of Windows. To solve the issue you can specify a platform target in the properties of your C# project: Choose x86 instead of Any CPU.