Creating a WCF Service Library in Visual Studio 2008 on Vista x64 is troublesome when referencing an x86 DLL. A service that calls a 32-bit DLL is required to have a platform target of x86 to run on a 64-bit OS. When you do this, the WcfSvcHost throws a BadImageFormatException when you attempt to debug the service. There is a bug report on MS connect. The workaround I used was to coreflag WcfSvcHost as 32-bit.
Manifest Problem
The main issue I've run in to is this third-party native 32-bit DLL fails to load using certain WCF hosts. I receive the following error when a service operation is invoked that uses the third-party DLL:
System.TypeInitializationException: The type initializer for
'' threw an exception.
.ModuleLoadExceptionHandlerException:
A nested exception occurred after the
primary exception that caused the C++
module to fail to load.
System.BadImageFormatException: The module was expected to contain an
assembly manifest. (Exception from
HRESULT: 0x80131018)
NestedException:
The handle is invalid. (Exception from HRESULT: 0x80070006 (E_HANDLE))
This exception is not raised when WcfSvcHost starts, it's raised when the a service operation is invoked that references the 32-bit DLL. What's very interesting, hosting this same service with the same app.config on a console app has no exceptions and works perfectly:
using (ServiceHost host = new ServiceHost (typeof (MsgBrokerService))) {
host.Open ();
Console.WriteLine ("running");
Console.ReadLine ();
This exception occurs right after:
'WcfSvcHost.exe' (Managed): Loaded
'C:\Windows\WinSxS\x86_microsoft.vc80.crt_1fc8b3b9a1e18e3b_8.0.50727.3053_
none_d08d7bba442a9b36\msvcm80.dll'
Again, the console app does not have an 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 answer from Microsoft Product Support.
Update #1: Both the console application and the WcfSvcHost.exe host process runs under the same session and logged-in user (me). I've copied WcfSvcHost.exe to the directory of the service, manually launched and experienced the same result. I've also checked the Windows Event Log for additional information and used sxstrace, but nothing was logged.
Running Process Explorer, I've verified the following are the same between the two processes:
Image: 32-bit
Current Directory
User/SID
Session
Security (groups denied, privileges disabled)
Running Process Monitor, and configuring symbols, I see WcfSvcHost looks for the following registry and files, while the console host does 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\assembly\GAC_32\msvcm80\8.0.50727.3053__b03f5f7f11d50a3a
C:\Windows\assembly\GAC_MSIL\msvcm80\8.0.50727.3053__b03f5f7f11d50a3a
C:\Windows\assembly\GAC\msvcm80\8.0.50727.3053__b03f5f7f11d50a3a
Update #2: This same exception occurs when the service is hosted in production on IIS 6 / Windows Server 2003.
Update #3: The 3rd-party 32-bit .NET assembly is the StreamBase API:
sbclient.dll (managed)
monitor.netmodule (managed)
dotnetapi.dll (unmanaged)
pthreads-vc8.dll (unmanaged)
Update #4: Added manifests without success:
Verified that dotnetapi.dll and pthreads-vc8.dll have RT_MANIFEST. The sbclient.dll .NET assembly did not have a manifest
Removed sbclient.dll from the GAC
Registered sbclient.dll for verification skipping
Added a manifest via mt.exe to both sbclient.dll and monitor.netmodule
Verified manifest was added and that the expected files were loaded during testing (via Visual Studio - debug modules window)
The same BadImageFormatException is thrown under BackgroundWorker.OnDoWork(), and the call stack shows a call to dotnetapi.dll...DefaultDomain.Initalize().
I have verified that msvcm80.dll does not have a manifest, I believe this is the only file loaded that doesn't have a manifest :)
Interesting find
When I load monitor.netmodule in Reflector, it says:
'monitor.netmodule' does not contain
an assembly manifest.
Even though it displays an error, Reflector is still able to disassemble the managed code.
a bit late but you can also change the app pool setting "Enable 32-bit Applications" to true in advanced settings.
Microsoft Product Support has resolved this question: It's by design. The unmanaged code is not loaded in the default AppDomain when using WcfSvcHost or the IIS WCF host.
A pure image will use a CLR version of
the C run-time library. However, the
CRT is not verifiable, so you cannot
use the CRT when compiling with
/clr:safe. For more information, see C
Run-Time Libraries.
http://msdn.microsoft.com/en-us/library/k8d11d4s.aspx
I cannot provide an explanation for the error, only my initial suspicion that there is a permission difference between the context in which your code is run as a service and the context in which it is run when you place it in a console application. The E_HANDLE HRESULT is my clue here. Assuming that you run the console application as your logged-in user, you could try configuring the service to start as that user as well. If it works in that configuration, then you can attempt to narrow down what required resource is unavailable when it fails.
I can suggest a workaround. If there is an oddity of the DLL in question that prevents it from working in a hosted service, you can take the sacrificial process approach, so named because it is typically used to isolate a DLL that crashes often. Briefly, you create a proxy program whose only purpose is to load and call the DLL on behalf of your main process, using named pipes or some other IPC method to pass requests and results. If the DLL crashes, you start a new instance of the proxy program. In your case it would have the added benefit that only the wrapper program would need to be 32-bit.
Do you see anything special in the Event viewer?.
In Vista if there a manifest problem you will see traces of it in the Event Viewer, it will tell you to use SxsTrace.
Could you manually add a manifest to this DLL yourself, using the mt.exe file?
MSDN Article on using mt.exe
This may seem a bit dumb; but make sure your service is running in the correct application pool.
Ran into this issue myself. I found a helpful post. As noted in other posts, Microsoft stated this is by design. Basically you need to:
Locate your version of WcfSvcHost.exe. (for me and visual studio
2017: C:\Program Files (x86)\Microsoft Visual
Studio\2017\Professional\Common7\IDE)
Launch developer command prompt
Execute cmd: copy C:\SourcePath\WcfSvcHost.exe
C:\DestinationPath\WcfSvcHost32.exe (Destination doesn't matter)
cmd: corflags /32BIT+ /Force WcfSvcHost32.exe (may need to cd to DestinationPath
In visual studio open the WCF project properties > Debug tab > Start External program: C:\DestinationPath\WcfSvcHost32.exe
Also add your command line arguments:
/service:MyWCFProjectName.dll
/config:MyWCFProjectName.dll.config
Note: You do not need to use ($ProjectDir) here
Launch the app. You are now free to launch WcfServiceHost.exe seperately.
Optionally go to solution > Set Startup Projects > Multiple Startup Projects > Choose the Wcf project and the client project.
Related
I'm debuggin on started Visual Studio 2017 after remotely logged into the server (Windows 2012 R2, 64-bit) via RDP. Note: so this is a "local debugging after remote login" issue, not a "remote debugging" issue.
Normal C++ project debugging is fine. But I'm working on an Excel plugin, so set the project's property at debugging > command = ...excel.exe. By right, after I started VS debugging, VS shall trigger excel instead, then, if excel loads the project as a plugin and make calls to it, VS can trap the break points.
However, this is now not working: Excel started then exited, before any of my c++ code is called. VS output says there’s an Roaming::RoamingCacheException error:
Exception thrown at 0x00007FFAB71968D8 in EXCEL.EXE: Microsoft C++ exception: Roaming::RoamingCacheException at memory location 0x000000D00613A3E0.
If I start excel first, then attach VS to the process by in vs menu debug > attach to process, then VS can successfully hook to excel -- this is now my work-around -- just to say VS or my code has nothing wrong.
As the exception happends during loading Excel, calling ntdll.dll, I suspect, something is wrong with the user profile caching for remote login (roaming).
But I'm not familiar with this part, any suggestion?
I working on an ATL Service project, an exe (out of process) NOT a DLL, and have created my COM object. When I test the Server in Visual Studio 2015 with a test client application it works with no problems.
When I install the server using, as recommended by MSDN,
YourEXE.exe /Service
The server installs and is visible in Services however when I use the same test client application I get the REGDB_E_CLASSNOTREG Class not registered error (Please note Question does not solve this).
Any ideas on a potential problems? I have only added the COM object and have not modified the rest of template in anyway. Have I possibly missed something?
We found the problem. The .rgs file had the wrong GUID in it.
This is unusual as the file was auto generated.
I am using one dll in my application for including the functionality provided by that dll . This dll i am getting after installing one msi .
But in my application i have a requirement like if the user has not installed that msi then we have to show one warning message(e.g msi has not installed , code for this i have implemented in the main() of my application ) and have to exit from the application .
But the problem is if the user has not installed the msi , then while launching the application itself its showing one error message since its not able to get the dll and this time control not even coming to my main() where i have written the code for this msi checking (through registry entry).
Is there any efficient way to resolve this issue ..
Consider delay-loading the DLL (Project -> Options -> Advanced Linker).
This will allow your app to load when the DLL is missing.
Does anyone know how to debug the LSP sample provided with Microsoft platform SDK? I read about this topic and found that the sample dt_dll generate a DLL file that can be used with a checked version of ws2_32.dll.
The problem is that they are not saying how to do it. How to use the dt_dll.dll file? How to include it? How to debug it? The whole process is not clear.
Also, I tried to created a log file in the code of the LSP sample. The file was not created even though the LSP was loaded and the networking operations are functional as normal.
I need a way to check what I am doing (using a log file, or debugging the LSP).
I am using Windows XP with Visual C++ 2008 Express.
Any ideas?
Let's assume that your LSP and its installer have been built successfully. And assume that the installer has successfully installed the LSP. Let's call it lsp.dll.
Then all applications using winsock, eg ws2_32.dll will also load your lsp.dll.
Verify it by open the command line console and type:
tasklist /m lsp.dll
If your browser is running you should see it in the list outputted by the above command. Attach your debugger to your running browser, you should be able to debug your LSP dll.
In Visual Studio, go to Debug->Attach Process->Select your running browser, eg IE.
You can certainly write to a log file from your LSP. However, please note that your lsp has the same privilege as the host application and it might not have permission to write file.
all, I have a rather frustrating issue. The application in question has an MFC GUI that uses the classes available in the MFC Featurepack. This GUI uses an DLL that is developed in C++\CLI. Our company uses Cruise Control. NET (1.4.4 SP1) on Windows Server 2008 SP2 for continuous integration. Cruise Control is setup to use the version of MSBuild that comes with the 3.5 version on the framework.
The issue in question is that if I use the build that Cruise Controls creates, I receive the following error: "Unhandled exception at 0x7642fbae (kernel32.dll) in FormView.exe: 0xE0434F4D: 0xe0434f4d." After some digging, the issue seems to be that the GUI doesn't like the C++\CLI assembly.
The "gotcha" is that if I log on to the server, and, using PowerShell, execute the same MSBuild command, the build works. Any one have ideas?
The issue was how I was building the installer. It was a separate solution from the project's main solution, and was thus a separate task from the primary build. Therefore, the output assemblies got signed twice, and loader complained because the one the application wanted was no longer valid.
you could try and attach the process to the visual studio debugger.