Ошибка «модуль не найден» с компонентом C ++ / CLI в ASP.NET - PullRequest
9 голосов
/ 09 февраля 2012

Я должен включить (управляемый) компонент C ++ / CLI в один из моих проектов ASP.NET, который ссылается на некоторые другие (неуправляемые) библиотеки C ++. Должно быть никаких проблем - .NET 3.5 доволен при компиляции проекта, все вроде нормально. Компонент C ++ / CLI и другие библиотеки DLL C ++ компилируются другим отделом как версия выпуска с «Любой ЦП» в Visual Studio 2005. Установлен распространяемый пакет VC ++ 2005. И тот же код работает без проблем, когда я запускаю его внутри обычного консольного приложения .NET.

Теперь, когда этот код работает в консольном приложении, он не правильно размещается в ASP.NET - он приводит к ошибке при начальной загрузке страницы (даже до входа в Global.asax). Для тестирования и отладки я использовал две конфигурации машины:

  1. Локальный ПК разработчика : Windows XP, 32-разрядная версия, Redist-пакет VC ++ 2005, Visual Studio 2010, ASP.NET 3.5, компиляция «любого процессора», хостинг на сервере веб-разработки (Cassini)
  2. Тестовый сервер (целевой компьютер): Windows 7, 64-разрядная версия, Redist-пакет VC ++ 2005, хостинг в IIS 7, AppPool имеет «Включить 32-разрядные приложения»

На обеих машинах при запуске приложения ASP.NET возникает одна и та же ошибка:

Exception Details: System.IO.FileNotFoundException: The specified module could not be found. (Exception from HRESULT: 0x8007007E)

Source Error:
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.

Stack Trace:
[FileNotFoundException: The specified module could not be found. (Exception from HRESULT: 0x8007007E)]
 System.Reflection.Assembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, Assembly locationHint, StackCrawlMark& stackMark, Boolean throwOnFileNotFound, Boolean forIntrospection) +0
 System.Reflection.Assembly.nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, Assembly locationHint, StackCrawlMark& stackMark, Boolean throwOnFileNotFound, Boolean forIntrospection) +43
 System.Reflection.Assembly.InternalLoad(AssemblyName assemblyRef, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection) +127
 System.Reflection.Assembly.InternalLoad(String assemblyString, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection) +142
 System.Reflection.Assembly.Load(String assemblyString) +28
 System.Web.Configuration.CompilationSection.LoadAssemblyHelper(String assemblyName, Boolean starDirective) +46

[ConfigurationErrorsException: The specified module could not be found. (Exception from HRESULT: 0x8007007E)]
 System.Web.Configuration.CompilationSection.LoadAssemblyHelper(String assemblyName, Boolean starDirective) +613
 System.Web.Configuration.CompilationSection.LoadAllAssembliesFromAppDomainBinDirectory() +203
 System.Web.Configuration.CompilationSection.LoadAssembly(AssemblyInfo ai) +105
 System.Web.Compilation.BuildManager.GetReferencedAssemblies(CompilationSection compConfig) +178
 System.Web.Compilation.WebDirectoryBatchCompiler..ctor(VirtualDirectory vdir) +163
 System.Web.Compilation.BuildManager.BatchCompileWebDirectoryInternal(VirtualDirectory vdir, Boolean ignoreErrors) +53
 System.Web.Compilation.BuildManager.BatchCompileWebDirectory(VirtualDirectory vdir, VirtualPath virtualDir, Boolean ignoreErrors) +175
 System.Web.Compilation.BuildManager.CompileWebFile(VirtualPath virtualPath) +86
 System.Web.Compilation.BuildManager.GetVPathBuildResultInternal(VirtualPath virtualPath, Boolean noBuild, Boolean allowCrossApp, Boolean allowBuildInPrecompile) +261
 System.Web.Compilation.BuildManager.GetVPathBuildResultWithNoAssert(HttpContext context, VirtualPath virtualPath, Boolean noBuild, Boolean allowCrossApp, Boolean allowBuildInPrecompile) +101
 System.Web.Compilation.BuildManager.GetVirtualPathObjectFactory(VirtualPath virtualPath, HttpContext context, Boolean allowCrossApp, Boolean noAssert) +126
 System.Web.Compilation.BuildManager.CreateInstanceFromVirtualPath(VirtualPath virtualPath, Type requiredBaseType, HttpContext context, Boolean allowCrossApp, Boolean noAssert) +62
 System.Web.UI.PageHandlerFactory.GetHandlerHelper(HttpContext context, String requestType, VirtualPath virtualPath, String physicalPath) +33
 System.Web.UI.PageHandlerFactory.System.Web.IHttpHandlerFactory2.GetHandler(HttpContext context, String requestType, VirtualPath virtualPath, String physicalPath) +40
 System.Web.HttpApplication.MapHttpHandler(HttpContext context, String requestType, VirtualPath path, String pathTranslated, Boolean useAppConfig) +160
 System.Web.MapHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +93
 System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155

Теперь это странно ... Это ничего не говорит о о том, что сборка отсутствует, даже Fuslogvw.exe или sxstrace.exe ничего не регистрируют. Кроме того, очевидно, что ошибка зависит от сборки C ++ / CLI или от неуправляемых библиотек C ++. Если я удаляю ссылку на сборку C ++ / CLI из моего проекта ASP.NET и кода, он работает нормально. Теперь, поскольку сборка C ++ / CLI зависит от собственных библиотек C ++, на которые нет ссылок в проекте ASP.NET, я скопировал все зависимые библиотеки C ++ в папку «bin» выходной папки проекта ASP.NET (так же, как и для консоли Workgin. приложение). Несмотря на то, что все компоненты C ++ были скомпилированы в режиме Release с установленным верным Redist Package VC ++, все зависимости должны быть на месте. Конечно, я знаю, что есть FileNotFoundException, но я не могу понять, чего не хватает ...

Как уже говорилось: один и тот же код для доступа к компоненту C ++ / CLI работает в консольном приложении .NET 3.5 на обоих тестовых ПК (где у меня развернуты одинаковые зависимости) с одинаковыми зависимыми DLL C ++, развернутыми в выходной папке, просто в ASP.NET я получаю вышеуказанную ошибку.

Любые предложения, как мне избавиться от проблемы или как отследить ее дальше?

(Конечно, я искал проблему в StackOverflow и Google, например, я нашел эти ссылки, но они не помогли:
- Ошибка «Указанный модуль не найден» при запуске веб-службы C # ASP.NET со ссылкой на C ++ dll
- Доступ к x86 COM из x64 .NET
- Приложение ASP.NET, разработанное в 32-битной среде, не работает в 64-битной среде
- Исключение модуля не найдено из веб-службы .NET 2.0 в Windows Server 2008 R2 )

Ответы [ 2 ]

5 голосов
/ 24 июля 2012

ProcMon спас меня.

Путь тоже был моей проблемой.Кажется, что IIS создает теневую копию каждого управляемого dll в папке C: \ Windows \ System32 \ inetsrv.Но это не относится к неуправляемому коду.Когда он должен загрузить неуправляемую DLL, он ищет путь к среде, а не каталог bin приложения в IIS.

Большое спасибо, Аристос !!

4 голосов
/ 09 февраля 2012

Ваш код достигает _nLoad, и это хорошо, потому что он прошел все проверки на загрузку и переместился в ядро, чтобы фактически загрузить dll, и там он не работает.

Для начала скачайте Dependency Walker из http://www.dependencywalker.com/ и используйте его на dll, чтобы выяснить, какой другой ресурс необходим для запуска dll. Я подозреваю, что не может загрузить некоторые другие файлы DLL.

Дополнительно может быть, это dll для поиска других файлов, которые не могут найти и поэтому не могут загрузить. Второй способ - использовать File Monitor или Process Monitor от sysinternals, чтобы найти то, что не удалось загрузить.

http://technet.microsoft.com/en-us/sysinternals
http://technet.microsoft.com/en-us/sysinternals/bb896645

...