BadImageFormatException with WcfSvcHost and IIS WCF Host

Creating a WCF service library in Visual Studio 2008 on Vista x64 is problematic when accessing the x86 DLL. The service that calls the 32-bit DLL must have the x86 target platform to run on the 64-bit OS. When you do this, WcfSvcHost throws a BadImageFormatException when trying to debug a service. There is an error report in the MS connection. The workaround I used was in the coreflag WcfSvcHost as 32-bit .

Manifest issue

The main problem that I encountered is that this 32-bit third-party DLL does not load using specific WCF hosts. I get the following error when a service operation that uses a third-party DLL is called :

System.TypeInitializationException: type initializer for '' made an exception.

.ModuleLoadExceptionHandlerException: A nested exception occurred after a primary exception that caused the C ++ module to not load.

System.BadImageFormatException: The module should have contained a collection manifest. (Exception from HRESULT: 0x80131018)

NestedException:

Invalid handle. (Exception from HRESULT: 0x80070006 (E_HANDLE))

This exception does not occur when WcfSvcHost is started, it occurs when a service operation is called that references a 32-bit DLL. Which is very interesting, if you have the same service with the same app.config in the console application, there are no exceptions and works fine:

using (ServiceHost host = new ServiceHost (typeof (MsgBrokerService))) { host.Open (); Console.WriteLine ("running"); Console.ReadLine (); 

This exception occurs immediately after:

'WcfSvcHost.exe' (managed): loaded 'C: \ Windows \ WinSxS \ x86_microsoft.vc80.crt_1fc8b3b9a1e18e3b_8.0.50727.3053_ none_d08d7bba442a9b36 \ msvcm80.dll'

Again, the console application has no exception and loads the same DLL:

'ConsoleApp.vshost.exe' (managed): loaded 'C: \ Windows \ WinSxS \ x86_microsoft.vc80.crt_1fc8b3b9a1e18e3b_8.0.50727.3053_ none_d08d7bba442a9b36 \ msvcm80.dll'

See the answer from Microsoft Product Support Services .

Update # 1: both the console application and the WcfSvcHost.exe host process work under the same session and the logged in user (me). I copied WcfSvcHost.exe to the service directory, started manually, and got the same result. I also checked the Windows event log for more information and used sxstrace, but nothing was logged.

Starting the process handler, I checked that between the two processes the same thing:

  • Image: 32-bit
  • Current directory
  • User / SID
  • Session
  • Security (groups are denied, privileges are disabled)

Running Process Monitor and character settings , I see that WcfSvcHost is looking for the following registry and files, but the console host is not. Process Monitor logs a lot of data, and I'm not sure what I'm looking for: (.

HKLM \ SOFTWARE \ Microsoft \ Fusion \ PublisherPolicy \ Default \ policy.8.0.msvcm80__b03f5f7f11d50a3a C: \ Windows \ build \ GAC_32 \ msvcm80 \ 8.0.50727.3053__b03f5f7f11d50a3a C: \ Windows \ build \ Gaf507505.50f30.50fgfs Windows \ Assembly \ GAC \ msvcm80 \ 8.0.50727.3053__b03f5f7f11d50a3a

Update # 2: The same exception occurs when a service is hosted in production on IIS 6 / Windows Server 2003.

Update No. 3: 32-bit .NET assembly of the 3rd-party version - StreamBase API :

  • sbclient.dll (managed)
  • monitor.netmodule (managed)
  • dotnetapi.dll (unmanaged)
  • pthreads-vc8.dll (unmanaged)

Update # 4: Added manifestos without success:

  • Checked that dotnetapi.dll and pthreads-vc8.dll have RT_MANIFEST. The sbclient.dll.NET compilation did not have a manifest
  • Removed sbclient.dll from GAC
  • Registered sbclient.dll for pass checks
  • Added manifest using mt.exe for both sbclient.dll and monitor.netmodule
  • A proven manifest has been added and that the expected files were uploaded during testing (through the Visual Studio window - debugging modules)
  • The same BadImageFormatException is thrown in BackgroundWorker.OnDoWork (), and the call stack shows the call to dotnetapi.dll ... DefaultDomain.Initalize ().

I checked that msvcm80.dll does not have a manifest, I believe that this is the only downloaded file that does not have a manifest :)

Interesting find

When I load monitor.netmodule in Reflector , it says:

'monitor.netmodule' does not contain an assembly manifest.

Although it displays an error, Reflector is still able to parse the managed code.

+4
source share
6 answers

Microsoft product support has resolved this issue: it is by design. Unmanaged code does not load into AppDomain by default when using WcfSvcHost or the IIS WCF host.

A clean image will use the CLR version of the C runtime library. However, CRT is not verifiable, so you cannot use CRT when compiling with / CLR: safe. See C Runtime Libraries for more information.

http://msdn.microsoft.com/en-us/library/k8d11d4s.aspx

+1
source

a little late, but you can also change the application pool setting "Enable 32-bit applications" to true in the advanced settings.

+4
source

I can’t explain the cause of the error, only my initial suspicion is that there is a difference in resolution between the context in which your code runs as a service and the context in which it runs when you put it in a console application, E_HANDLE HRESULT is my hint . Assuming that you are running the console application as a registered user, you can try to configure the service to run as this user. If it works in this configuration, you can try to narrow down which resource is unavailable when it does not work.

I can suggest a workaround. If there is some strangeness of the DLL under consideration that prevents it from working in the hosted service, you can use the sacrificial process approach, so named, because it is usually used to isolate the DLL, which often fails. In short, you are creating a proxy program whose sole purpose is to load and call the DLL on behalf of your main process, using named pipes or some other IPC method to transmit requests and results. If the DLL crashes, you start a new instance of the proxy program. In your case, this will have the added benefit that only the wrapper should be 32-bit.

0
source

Do you see anything special in the event viewer ?.

In Vista, if there is a clear problem, you will see its traces in the event viewer, it will tell you to use SxsTrace .

0
source

Could you manually add the manifest to this DLL yourself using the mt.exe file?

MSDN article on using mt.exe

0
source

This may seem a little silly; but make sure your service is running in the correct application pool.

0
source

All Articles