суббота, 21 марта 2015 г.

Как собрать проект под .Net 2.0 с помощью VS 2013 CE

Чем только не приходилось мне пользоваться в течении карьеры программиста. Начинал я с перевода программы, написанной на Fortran-е для IBM-360, на Pascal для СМ-10. Затем был PL/1 - это на мейнфреймах. После, наступила эра персоналок. Ну как персоналок. В то время персоналка - это не тогда, когда у тебя и дома, и на работе, в твоем личном пользовании, твой, или, по крайней мере, выделенный тебе, компьютер. Это - когда приходишь к определенному времени, тебе освобождают место за компьютером и ты работаешь,  до тех пор, пока не придет следующий работник, или не попросит освободить место кто-нибудь с более высоким статусом. Тогда тоже был Pascal.

Потом на рабочем столе появился действительно персональный компьютер - советский, собранный в Минске, ЕС-1840. Тут все было вперемешку - C, Pascal, продукты Borland с приставкой Turbo. Доходило даже до такой экзотики, как Prolog, тоже, кстати, Turbo. Потом C стал преобладать. Начинают использоваться десктопные базы данных, в основном Paradox, но случаются и работы с dBase.

Затем DOS сменился Windows, замаячила первая версия Delphi. На смену Windows 3.1 выходит Windows 95 и второй Delphi прочно занимает место в качестве основного инструмента программирования. Десктопные базы заменяются серверной, да не какой-нибудь, а Oracle. Идет время, меняются версии Delphi, Oracle. И тут, как гром среди ясного неба - первый проект на Java. Но, чуть раньше, в свободное от работы время, изучение .Net, еще версии 1.1, C# и первый пилотный проект на ASP.NET, но уже версии 2.0, тоже в свободное от работы время, с использованием API карт Google, AJAX, web сервисов, JSON, XML.

Потом смена работы. Знакомство с Firebird. Постепенно Java вытесняет Delphi. Опять же, в качестве факультатива, по вечерам, выполняется подвернувшаяся интересная работа по переводу серверной части, написанной с использованием ASP.NET и работающей на IIS, на Java, которая должна крутиться на Tomcat-е, Тут тоже была БД - довольно экзотическая PostgreSQL. Ну а на рабочем месте Java теперь доминирует практически полностью. И вновь неожиданность - первое рабочее, не факультативное, задание с использованием C# - надо слегка расширить функциональность десктопного приложения.

Вот так, в нескольких строчках умещается три десятилетия непрерывной работы. Многое, конечно, оставлено за рамками. Да только четыре (или пять?) написанных за это время фреймворков чего стоят, компоненты для Delphi, некоторое подобие шины. А сколько пришлось решать проблем? Разве все упомнишь.

Вот. Проблемы. Это - одна из причин, побудившая меня завести блог. И вся эта длинная прелюдия лишь для того, чтобы я описал парочку маленьких нюансов, которые у меня возникли сейчас, когда на меня свалилась работа на любимом мною C#.
 
Как известно, нюансы, проблемы, особенности - все это проявляется не тогда, когда вы используете инструменты для написания "Hello, world!". Чаще всего, у вас возникнет вероятность столкнуться с неприятностями, когда вы начнете сходить с накатанной дорожки обыденного использования инструмента или технологии. То есть, начнете использовать возможности, которые, в принципе, предусмотрены, запрограммированы и анонсированы, но редко бывают востребованы. Хотя "редко" - это не совсем правильное слово. Достаточно посмотреть, например, на stackoverflow. Но, хватит прелюдий, перейдем к сути.

Десктопное приложение, которое надо было несколько модифицировать, разрабатывалось для платформы .Net 2.0 на Visual Studio 2005. Нет, все нормально, примеров использования старых, проверенных временем технологий и инструментов - море. Проблема была лишь в том, что у меня не сохранилось 2005-ой студии. Можно было, конечно, попробовать скачать ее с торрентов, но...

Совсем недавно Microsoft абсолютно бесплатно стал раздавать версию Visual Studio 2013, так называемый, Community Edition. По своим возможностям этот набор, вроде, эквивалентен Visual Studio Professional Edition. Может, конечно, с оговорками, но, по функционалу, он явно значительно мощнее так называемых Express Edition, которые и ранее раздавались бесплатно. Одна возможность использовать расширения чего стоит.

А тут еще моя, проснувшаяся в последнее время, щепетильность в вопросах лицензионной чистоты. Нет, я, конечно, не юрист, и все нюансы лицензионных соглашений не понимаю, и особо никогда в них не вчитывался, но, по минимуму, закон теперь стараюсь соблюдать. Минимум заключается в том, что, если ПО продается, и оно мне нужно, я его стараюсь купить. Если же считаю, что стоит оно слишком дорого, то стараюсь подыскать ему бесплатную замену.

Из всего сказанного выше вывод напрашивается сам собой. Да, я скачал Visual Studio 2013 Community Edition (или вот прямая ссылка на закачку, но, осторожнее, там траффика почти 7 гигабайт) и установил его на виртуалку, которая заранее была подготовлена для разработки для .Net. Установил на нее же .Net Framework 4.52 Developer Pack.

Автор программы поделился исходниками и мы с ним обговорили, как проект должен будет собираться для релиза. Как я уже говорил, сам проект довольно возрастной, разрабатывается на Visual Studio 2005 под .Net 2.0. И, хотя, автор и выразил желание попробовать перенести его под более современную среду разработки и попробовать собрать его под какую-нибудь более свежую версию .Net, у него, как, впрочем, и у меня, оставались сомнения, по поводу безболезненности и адекватности таких подвижек. Поэтому мы решили, что да, попробуем, но в этот раз релиз, все-таки, будем собирать по устоявшемуся сценарию. Саму же разработку я попробую вести в новой среде, но конечную платформу менять не буду.

К счастью, новые студии позволяют выбирать платформу, для которой должна производиться сборка проектов. Появилось это новшество, по моему, в 2010 студии, но настаивать на точности не буду. Главное, что в 2013-ой выбор платформы сборки присутствует.

Помятуя о том, что конечную сборку будем производить на старой версии, решил, что, при необходимости, будет повод опробовать утилиту по конвертации проектов Visual Studio. К сожалению, она работает только до версии студии 2012. Но я, тем не менее, предположил, что, наверное, между проектами версии 2013 и 2012 разница будет не такой большой, а с 2012 конвертировать в 2005 с помощью утилиты, вроде, возможно.

Для начала же, я решил сконвертировать при помощи этой утилиты проекты из 2005 в 2013, несмотря на то, что студия сама поддерживает (безвозвратную) конвертацию. Просто, хотелось посмотреть, как все это функционирует. 


Скачал утилиту, запустил ее. Интерфейс достаточно интуитивный. Выбрал solution для конвертирования, указал версию студии, для которой хочу получить сконвертированный проект, запустил конвертацию. Утилитка сообщила, что все прошло успешно, все проекты, входящие в solution успешно сконвертированы. Дело за малым - открыть solution в новой студии.


Первая осечка - студия не согласна, что это вообще solution, с которым она может работать. Посмотрел, как выглядят родные solution-ы 2013-ой студии и внес вот такое исправление:
было:

Microsoft Visual Studio Solution File, Format Version 11
# Visual Studio 2010


стало

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013

После этого solution открылся без проблем. То есть, утилитка, вроде, и работает, но явно сыровата - в готовом продукте вряд ли пришлось исправлять результаты вручную.

Что ж, продолжим. Пытаюсь построить приложение и тут - вторая засада:
 

Как видим, пара-тройка предупреждений и несколько ошибок. Даже поверхностного взгляда достаточно, чтобы предположить, что ошибки как-то связаны с предупреждениями, и, если я избавлюсь от предупреждений, то, скорее всего, ошибки тоже пропадут.

Что же нам сообщают предупреждения? Они жалуются на то, что парочка сборок, на которые напрямую ссылается один из проектов solution-а, опосредствованно зависят от системной сборки .Net фреймворка с названием System.Core, которая отсутствует на платформе, для которой собирается solution. А как же им не жаловаться на это? Ведь мы строим приложение для пратформы .Net 2.0, а указанная системная сборка появилась в .Net, начиная с версии 3.5, если мне не изменяет память.

Когда смысл происходящего становится более-менее понятен, начинает вырисовываться и возможное решение. Оно состоит в том, чтобы заставить компилятор не обращать внимание на эту опосредствованную зависимость. И, к счастью, в Visual Studio есть возможность повлиять на поведение компилятора в этом аспекте.


Если открыть в дереве проектов нужный проект (для которого были сгенерированы предупреждения), и в узле References (Ссылки) выбарть нужную сборку (которая упоминается в предупреждении), то в свойствах этой сборки можно обнаружить элемент Specific Version, значение которого равно False.

Eсли почитать подсказку по этому элементу, то становится понятным, что с его помощью можно включать и выключать некие правила, управляющие процессом нахождения нужных сборок (это я так перевел assembly resolution). В MSDN можно найти вот такое описание этого элемента. Я специально приведу выдержку из этой информации здесь:

When a project targets a .NET Framework version and references an assembly compiled for a higher .NET Framework version, the reference resolves only if it has SpecificVersion set to true.

When a project targets a profile and references an assembly that is not in the profile, the reference resolves only if it has SpecificVersion set to true.

Вот. Похоже, что для того, чтобы проект скомпилировался, надо, чтобы у двух упомянутых сборок это свойство имело бы значение True, а не False. Что я делаю? Правильно, радостно меняю значение и запускаю компиляцию. И что я вижу? Правильно, ничего не изменилось, предупреждения там же, где и были, ошибки, также, на месте. И возникает логичный вопрос: почему?

Чтобы ответить на этот вопрос надо посмотреть в первоисточник. Первоисточником является, конечно же, сам файл проекта, вернее, его содержимое. Я не буду рассказывать все перипетии того пути, который мне пришлось пройти, покажу лишь результаты. Изначально файл проекта, в части, касающейся интересующих нас значений свойств, выглядел примерно так:


После того, как я изменил значение свойства в Visual Studio, содержимое файла изменилось, но, я бы сказал, несколько неожиданным образом. То есть, я то ожидал увидеть установленные в True значения свойств, но, вместо этого, свойства оказались просто выпилены из файла проекта полностью.


Тогда я отредактировал файл проекта вручную, для чего выгрузил проект, и выбрал в контекстном меню пункт Edit <имя_файла_проекта>.


Внеся нужные мне изменения, я перегрузил проект и вновь попытался его откомпилировать. И что вы думаете? На этот раз все замечательно сработало. Никаких предупреждений и связанных с ними наведенных ошибок. Более того, приложение даже запустилось. Но, как и предполагалось, приключения не закончились. Продолжение следует...

Комментариев нет:

Отправить комментарий