Monday, November 29, 2010

Наступая на первые грабли

Не так давно я занялся разработкой приложений под Android с помощью Eclipse IDE. Первый же демо проект преподнёс мне парочку граблей, на которые я успешно наступил и хотел бы поделиться решением. Итак, по порядку:

Грабли №1 "No resource identifier found for attribute 'targetSdkVersion' in package 'android'"
AndroidManifest.xml содержит атрибут targetSdkVersion, появившийся только в Android 1.6 в то время как проект собирается для более ранней версии. В моём случае, это была версия 1.5.

Как лечится: Поскольку в моём демо проекте версия SDK не играет принципиальной роли, я просто указал чтобы проект собирался для Android 1.6. ( Project > Properties > Android > Project Build Target = Android 1.6 > Ok ).

Грабли №2 Project '<название проекта>' is missing required source folder: 'gen'
Иногда, при очистке проекта ( Project > Clean ) папка 'gen' удаляется. Причины по которым это происходит иногда, а не всегда, мне пока не ясны, но факт остаётся фактом.
Так вот, эта папка содержит автоматически сгенерированный java класс-обвёртку для доступа к ресурсам. Он генерируется компилятором ресурсов (aka Android Resource Manager) в самом начале сборки проекта лишь в том случае, если ресурсы приложения изменились. Если же ресурсы не менялись, то он не пересоздаётся, и соответственно папка gen, в которой он должен находится также. При этом отсутствие этой папки приводит к указанной ошибке.

Как лечится: Необходимо измените любые ресурсы, например, добавив дополнительный пункт меню, который позже можно удалить ( res > menu > menu.xml > add > item > ctrl + s > ctrl > + b ).

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 (Ссылка на источник):