Создание библиотеки служб WCF в Visual Studio 2008 в Vista x64 проблематично при обращении к библиотеке x86. Служба, которая вызывает 32-разрядную библиотеку DLL, должна иметь целевую платформу x86 для работы в 64-разрядной ОС. Когда вы делаете это, WcfSvcHost выдает исключение BadImageFormatException при попытке отладки службы. На MS Connect есть отчет об ошибке . Обходной путь, который я использовал, был coreflag WcfSvcHost как 32-битный .
Проблема с манифестом
Основная проблема, с которой я столкнулся, заключается в том, что эту стороннюю 32-битную DLL не удается загрузить с использованием определенных хостов WCF. Я получаю следующую ошибку, когда вызывается операция службы , использующая стороннюю DLL:
System.TypeInitializationException: инициализатор типа для
выкинул исключение.
.ModuleLoadExceptionHandlerException:
Вложенное исключение произошло после
Основное исключение, вызвавшее C ++
модуль не загружается.
System.BadImageFormatException: модуль должен содержать
сборочный манифест. (Исключение из
HRESULT: 0x80131018)
NestedException:
Указатель недействителен. (Исключение из HRESULT: 0x80070006 (E_HANDLE))
Это исключение не вызывается при запуске WcfSvcHost, оно вызывается при вызове сервисной операции, которая ссылается на 32-битную DLL. Что очень интересно, размещение этого же сервиса с тем же app.config в консольном приложении не имеет исключений и работает отлично:
using (ServiceHost host = new ServiceHost (typeof (MsgBrokerService))) {
host.Open ();
Console.WriteLine ("running");
Console.ReadLine ();
Это исключение возникает сразу после:
'WcfSvcHost.exe' (управляемый): загружен
«C: \ Windows \ WinSxS \ x86_microsoft.vc80.crt_1fc8b3b9a1e18e3b_8.0.50727.3053_
none_d08d7bba442a9b36 \ msvcm80.dll '
Опять же, консольное приложение не имеет исключения и загружает ту же DLL:
'ConsoleApp.vshost.exe' (Управляется):
нагруженный
«C: \ Windows \ WinSxS \ x86_microsoft.vc80.crt_1fc8b3b9a1e18e3b_8.0.50727.3053_
none_d08d7bba442a9b36 \ msvcm80.dll '
См. Ответ от службы поддержки продуктов Microsoft .
Обновление № 1: и консольное приложение, и хост-процесс WcfSvcHost.exe выполняются в одном сеансе и вошли в систему (я). Я скопировал WcfSvcHost.exe в каталог службы, запустил вручную и получил тот же результат. Я также проверил журнал событий Windows для получения дополнительной информации и использовал sxstrace , но ничего не было зарегистрировано.
Запустив Process Explorer, я убедился, что между двумя процессами одинаковые:
- Изображение: 32-разрядное
- Текущий каталог
- Пользователь / SID
- Session
- Безопасность (группы запрещены, привилегии отключены)
Запуск Process Monitor и настройка символов , я вижу, WcfSvcHost ищет следующий реестр и файлы, а консольный хост - нет. Process Monitor регистрирует много данных, и я не уверен, что я ищу: (.
HKLM \ SOFTWARE \ Microsoft \ Fusion \ PublisherPolicy \ Default \ policy.8.0.msvcm80__b03f5f7f11d50a3a
C: \ Windows \ сборка \ GAC_32 \ msvcm80 \ 8.0.50727.3053__b03f5f7f11d50a3a
C: \ Windows \ сборка \ GAC_MSIL \ msvcm80 \ 8.0.50727.3053__b03f5f7f11d50a3a
C: \ Windows \ Assembly \ GAC \ msvcm80 \ 8.0.50727.3053__b03f5f7f11d50a3a
Обновление № 2: это же исключение возникает, когда служба размещена в рабочей на IIS 6 / Windows Server 2003.
Обновление № 3: 32-разрядная сборка .NET стороннего производителя - это StreamBase API :
- sbclient.dll (управляемый)
- monitor.netmodule (управляемый)
- dotnetapi.dll (неуправляемый)
- pthreads-vc8.dll (неуправляемый)
Обновление № 4: добавлены манифесты без успеха:
- Проверено, что dotnetapi.dll и pthreads-vc8.dll имеют RT_MANIFEST. Сборка sbclient.dll .NET не имеет манифеста
- Удален sbclient.dll из GAC
- Зарегистрированный sbclient.dll для проверки пропуска
- Добавлен манифест через mt.exe как для sbclient.dll, так и для monitor.netmodule
- Добавлен проверенный манифест и что ожидаемые файлы были загружены во время тестирования (через Visual Studio - окно отладочных модулей)
- Та же исключительная ситуация BadImageFormatException создается в BackgroundWorker.OnDoWork (), и в стеке вызовов отображается вызов dotnetapi.dll ... DefaultDomain.Initalize ().
Я проверил, что msvcm80.dll не имеет манифеста, я считаю, что это единственный загруженный файл, у которого нет манифеста:)
Интересная находка
Когда я загружаю модуль monitor.net в Отражатель , он говорит:
'monitor.netmodule' не содержит
сборочный манифест.
Несмотря на то, что он отображает ошибку, Reflector все еще может разобрать управляемый код.