Tuesday, July 20, 2010

Запуск 32-битных ASP.NET веб приложений под IIS x64

По умолчанию, IIS установленный на 64-битной операционной системе не хостит веб приложения, которые скомпилированы под платформу x86. При попытке обратится к странице такого веб приложения вылетает следющее исключение:

Could not load file or assembly 'Web32' or one of its dependencies. An attempt was made to load a program with an incorrect format.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.BadImageFormatException: Could not load file or assembly 'Web32' or one of its dependencies. An attempt was made to load a program with an incorrect format.



Это происходит по причине того что IIS запущен как процесс c 64-битным адресным пространством и не может загрузить 32-битную динамическую библиотеку. Для того чтобы обойти данную проблему нужно выполнить следующий скрипт (Ссылка на источник):


cscript.exe %SystemDrive%\Inetpub\AdminScripts\adsutil.vbs set W3SVC/AppPools/Enable32BitAppOnWin64 true



После того как скрипт отработает, для обслуживания всех сайтов на сервере будeт запускаться 32-битная версия IIS, которая в свою очередь будет исполняться подсистемой эмуляции 32-битных приложений WOW64. Досадно, что эта настройка является глобальной и теперь для всех пулов будут запущенны 32-битные копии w3wp.exe из C:\Windows\SysWOW64\inetsrv\. 
Вообще, чтобы не сталкиваться с данной проблемой, лучше указать Any CPU в настройках проекта. Так не придётся заморачиваться с разрядностью и приложение будет работать как из-под 64-битной версии IIS, так и из 32-битной. Но к сожалению, это не всегда возможно и в крайне редких ситуациях без указания конкретной платформы не обойтись и здесь такое решение просто необходимо. Однако, использовать его нужно крайне осторожно, ведь оно может повлиять на работу других приложений на веб сервере. 


В IIS 7, данная настройка также может указываться для каждого  пула веб приложений отдельно. Сделать это можно либо через командную строку (Ссылка на источник):


%windir%\system32\inetsrv\appcmd set config -section:applicationPools -applicationPoolDefaults.enable32BitAppOnWin64:true


Либо с помощью редактирования Advanced Settings для пула приложений в консоли управления IIS (Ссылка на источник):

Tuesday, November 17, 2009

Версия VC90 runtime

На прошлой неделе я совершенно случайно натолкнулся на то что C++ приложения скомпилированные на Visual Studio 2008 SP1 по умолчанию используют RTM версию VC90 runtime. Как описано в блоге одного из разработчиков VC++ в Visual Studio 2008 изменилась стратегия привязки к верии runtime.

Это могло быть оставлено незамеченным, если бы мы не решили использовать регулярные выражения из TR1 которые появились в VC++ c выходом Visual Studio 2008 SP1.

В следствии, приложение начало выдавать ошибку при запуске в тестовой среде.

Сначала оказалось, что при инсталяции нашего приложения, мы использовали инсталяционный модуль Microsoft_VC90_CRT_x86.msm предыдущей версии 9.0.21022.8. Но после того как это было исправлено и мы добавили модуль версии 9.0.30729.1 приложение перестало запускаться вовсе. В Event Viewer появились ошибки о том что не найдена сборка Microsoft.VC90.CRT версии 9.0.21022.8. Проблема оказалась в том, что в манифесте приложения указана RTM (9.0.21022.8) версия Runtime компонент.

В результате поиска решения, было найдено два варианта:

  1. Использовать директиву компиляции _BIND_TO_CURRENT_CRT_VERSION. Тогда в манифест попадёт версия того Runtime который используется студией при сборке проекта.
  2. Добавить в инсталяцию модуль policy_9_0_Microsoft_VC90_CRT_x86.msm. В этом случае, приложение будет использовать более новую версию Runtime, по отношению к той что указана в манифесте.

Wednesday, September 30, 2009

Microsoft готовит средства миграции приложений c LINQ to SQL на ADO.NET Entity Framework

Как известно, в последней версии .Net Framerork Microsoft предлагает два ORM решения: LINQ to SQL и ADO.NET Entity Framework. Первое появилось с выходом .Net 3.5 и Visual Studio 2008, в то время как ADO.NET Entity Framework вошёл в .NET 3.5 SP1 с поддержкой в Visual Studio 2008 SP1.

Но, несмотря на то, что ADO.NET Entity Framework появился позже LINQ to SQL и в функциональном плане пока уступает, он развивается более динамично и уже в следующей версии фреймворка будет значительно расширен новыми фитчами.

Более того, Microsoft уже выпустила первую версию шаблонов Visual Studio 2010 для миграции метаданных LINQ to SQL ( .dbml ) в метаданные ADO.NET Entity Framework ( .edmx ). Что подтверждает намерения Microsoft в ближайших версиях отказаться от LINQ to SQL в пользу ADO.NET Entity Framework.

Это вовсе не означает, что в один прекрасный момент, всё то что было написано с использованием LINQ to SQL перестанет работать, однако может оказаться серьёзным препядствием для миграции приложения на новые версии .Net Framerork. С этой точки зрения ADO.NET Entity Framework является более привлекательным для использования в реальных Enterprise проектах.