We have a WebService that's been running for a while, there's about 6~ projects on it.
Recently, we had to support a C++ 32 bit library, I tested and I had to set the project's target platform to x86 or I'd get the BadImageFormatException. So this new project is set to compile on x86, but everything else is set to AnyCPU.
After publishing the WebService, I get the error Unable to find ?.dll when calling the function.
Is there anyway I can add this new project as x86 without having to set my WCF to x86 as well, or am I doing something wrong and this should've worked?
It is possible but all binaries (.exe-s and .dll-s) must share the same target platform for it to work. You cannot load a 32-bit DLL into a 64-bit process or the other way around.
If you're hosting your web service under IIS, the target platform of the app pool determines what kind of DLL-s you can load.
If you have exported functions in your unmanaged DLL-s, your P/Invoke declarations must also match the target platform - specifically, if you pass pointers, those will have to be correctly mapped to 32/64-bit pointers. (Usually IntPtr takes care of this.) P/Invoke declarations really turn into possible problems if you support both platforms with a single source base (compiled into platform-specific binaries).
Depending on what you're trying to do, you may also need to deal with handling platform-specific references. This question has more detail about that.
Related
I have compiled a c natives 32bit DLL with Dev-C++, create the reference on my asp.net project, write a dllImport directives and use my new DLL. When launch my DEBUG session all work very well but when deploy my project on Web Server the runtime not load my DLL.
My IIS 7.0 w3wp.exe runs as a 64 bit process (to check if your process running as a 32 bit process under WOW64, open the task manager's Process tab and see if the process name contains "*32").
I believe that a 64 bit process can only load 64 bit native DLLs (and managed DLLs built for "Any CPU" or "X64"). Perhaps your debug session is a 32 bit session? If this is the cause, take a look at Using a 32bit or 64bit dll in C# DllImport .
For those of you who still cannot find a proper way to use a 32-bit DLL under a 64-bit IIS Application Pool, either by tweaking the registry, or by trying how to deal with the "COM+ Components Services", I have found a perfectly working solution : "Encapsulating" the 32-bit component into a new COM object as described on this page did the job perfectly, and I think that a lot of you will be interested to solve the problem this way ;)
http://www.chestysoft.com/component-services.asp
In my case, that allowed me to use the "XStandard.Zip" free Component from XStandard, which is sadly only available as a 32-bit ASP component, and that have an "InProcServer32" Key in the registry apparently preventing it to work by tweaking the registry, as described here : https://techtalk.gfi.com/32bit-object-64bit-environment/
In this post, a lot of comments reported that "InProcServer32-IDs are not reflected because Microsoft assumes that these are only InProc-Calls and not Out-Of-Proc-Calls".
And that was my case too, leading me to the situation where the registry tweaking solution described in the previous post was not working in my case, as other users.
Hoping having saved some days... or nights !
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 am trying to get registration-free COM interop between a 64-bit COM dll and a C# app to work.
In the answers to a previous question of mine, I got help that allowed me to successfully call a HelloWorld method on the 64-bit COM dll for C#.
However, this was only possible by registering the COM dll globally using regsrv32.exe.
Based on this answer to a related question, I think that I need to set the Isolated flag on the reference of the COM dll to true. However, this leads to the following build error:
Problem isolating COM reference 'ComLibInteropLib':
No registered classes were detected for this component.
The answer to a question on MSDN social seems to indicate that there is a solution for this problem if one can compile a 32-bit version of the dll.
However, my COM interop library needs to link to a 'normal' C++ dll, for which I do not have the source and that is only available as x64.
So my question is: How can I enable the Isolated flag (or otherwise get side-by-side to work) between a 64-bit COM dll and a C# application?
I am happy to use regsrv32.exe on my machine or other developer's machine, but we cannot register any COM dlls on production machines, where the final application must run.
This is a side-effect of the original problem you had, the COM server wasn't getting registered properly. When you Isolated option to true, the build system auto-generates the required manifest entries for you. But the content of the manifest needs to come from somewhere, it uses the registry keys. Since they are not there, it can't generate the manifest.
You can write the manifest yourself but that requires enough insight in what the manifest should look like. With very high odds of making mistakes, the incantations are quite obscure. So avoid that, you just need to get the COM server registered to get ahead. Just on your build machine, it doesn't have to be registered on the client's machine since it will use the manifest.
You mentioned a 64-bit COM server, that's another possible failure mode. The build system is still 32-bit so you'll have high odds that it looks at the wrong keys. HKLM\Software\Wow6432Node instead of HKLM\Software. Battle that problem by building both flavors of the COM server. Beware of having the same kind of problem when you use Regsvr32.exe yourself, there are two of them. The one in c:\windows\syswow64 should be used to register the 32-bit version of the server, the one in c:\windows\system32 for the 64-bit version.
My small application does 2 things seem conflict:
1) Use VFPOLEDB.1 to talk to Visual Foxpro database to get some data --> It require app builder in x86 or 'Any CPU'
2) However there is another function to call a powershell script to access IIS of the server and it requires project build in x64. (or when .Net launch powershell, it gets confused about which version and will throw some COM object class not register error)
How can I handle this conflict issue?
I'm not entirely sure, but perhaps you can do this by splitting your project. One project is x86 and does the FoxPro call, the other one is x64 and calls Powershell, a third one would be the main project that calls the two.
Per Microsoft:
The VFP oledb driver is 32 bit and can not be used with the NET 2.0 CLR running in 64 bit mode. It is my understanding that there are no plans to provide a 64 bit version of the VFP oledb driver. [Source]
In short, you're not going to ever be able to use it in 64-bit mode; work out trying to solve your COM object error and build for x86. Your other option might be to generate a standalone executable for the FoxPro section and have your main app execute it independently (it would end up being virtualized though).
I think another option for this would be to use COM+ and a late-bound execution model, where the COM objects are actually managed by a COM+ server rather than your application directly.
Is there a way to leverage NLREG in C#, or from any other .NET language? Currently, we only can find it as a COM object, which gives us issues when we change platforms (32 to 64 and the like).
Unless you actually need the 64-bit memory space in your NLREG client, just set the target platform in your client project to x86 (not AnyCPU), then it'll always work regardless of 32- or 64-bit OS.
Your question wasn't clear if you were changing the target compiled platform for your client, or if you're trying to run on a 64-bit OS- I'm assuming the latter.