Перенос консольного приложения c .NET Framework 4.7.2 на NET Core 3.1

По мере изучения основ C# я пробую также переписать один из моих проектов с Delphi на C#.  Пишу я пока без всяких изысков вроде визуального интерфейса, так как программа хоть и большая, но максимум, что пока от неё требуется — это собрать csv-файл из рассчитанных данных и визуализировать кое-какие моменты работы в Google Earth при помощи kml-файла. Когда я писал часть про логические операции, то мне понравилось использование выражения switch вместо одноименной конструкции — коротко,  понятно и лаконично.  Однако , эта  возможность доступна для использования только с версии  C# 8.0, а у меня приложение разрабатывалось на .NET Framework 4.7.2 и C# 7.3, соответственно. А так как кода было написано уже достаточно много, то пришлось думать над тем, как перенести моё консольное приложение с .NET Framework 4.7.2 на NET Core 3.1.

Смена версий языка C# в Visual Studio 2019 не работает

Первое, что я предпринял для того, чтобы как можно более безболезненно сменить C# 7.3 на C# 8.0 — это попробовал  изменить версию языка в Visual Studio. Судя по найденным на просторах Интернет инструкциям, делалось это через свойства проекта: надо было дважды кликнуть по Properties в обозревателе решений, затем, в открывшемся окне перейти на вкладку «Сборка», кликнуть кнопку «Дополнительно…» и, в открывшемся окне выбрать необходимую версию языка. Однако, в Visual Studio 2019 такой «фокус»не прошел:

Microsoft позаботился о том,  чтобы разместить под неактивным списком выбора версии C# пояснение того, почему на данный момент нельзя сменить версию языка. Судя по полученной информации, компилятор C# последней версии определяет версию языка по умолчанию на основе целевой платформы или платформ проекта, интерфейс смены версии C# теперь не работает, а новые функции C# 8.0 поддерживаются только на .NET Core 3.x. Так что, чтобы «пощупать» новинки в C# 8.0 пришлось искать вариант того, как быстро мигрировать с .NET Framework 4.7.2 на NET Core 3.1.

Простой вариант переноса консольного приложения с .NET Framework 4.7.2 на NET Core 3.1

Вариант перехода с .NET Framework 4.7.2 на NET Core 3.1 нашелся относительно быстро на Хабре в блоге Microsoft (кто бы подумал), правда для консольного приложения пришлось его совсем чуточку доработать и добавить в этот вариант ещё один шаг. В конце этой статьи я приведу ссылку на первоисточник информации, чтобы соблюсти все правила цитирования.

Шаг 1. Запуск Portability Analyzer

Portability Analyzer — это небольшая утилита, которая анализирует код вашего проекта с целью выявления возможных проблем при переносе проекта на другую платформу. Скачать Portability Analyzer можно с вот этой странички.

Запускаем Portability Analyzer и указываем расположение исходного кода проекта:

Portability Analyzer
Portability Analyzer

После этого откроется файл Excel с отчётом по проверке. У меня этот файл выглядел следующим образом:

Portability Summary
Лист Portability Summary

Оказалось, что используемая в моем проекте сборка SharpKml не на все 100% поддерживается в .NET Standard 1.2, но для .NET Core 3.1 подходит. Значит всё хорошо, можно переходить к следующему шагу. Если бы анализатор показал меньше 100% совместимости с .NET Core 3.1, то пришлось бы искать либо другую версию SharpKml или же искать альтернативу.

Шаг 2. Миграция .csproj в SDK-стиле

В Обозревателе решений  необходимо кликнуть правой кнопкой мыши по своему проект и посмотреть есть ли в контекстном меню пункт «Изменить файл проекта». Вот так выглядит этот пункт в Visual Studio 2019:

А вот так будет выглядеть контекстное меню проекта без пункта:

Если пункт «Изменить файл проекта» имеется, то можно переходить к следующему шагу. Если же пункта нет, то делаем следующее:

  1. Смотрим, есть ли в проекта файл packages.config. В «Обозревателе решений» он выглядит вот так:

Если файл имеется, то кликаем на нем правой кнопкой мыши и выбираем пункт «Перенести packages.config в PackageReference…«:

Появится окно в котором необходимо нажать «Ok»

2. Выгружаем проект. Для этого кликаем по названию проекта правой кнопкой мыши и выбираем пункт «Выгрузить проект»

После выгрузки проект в «Обозревателе решений» будет выглядеть вот так:

Снова кликаем по названию проекта правой кнопкой мыши и выбираем пункт «Изменить название_проекта.cproj«. В моем случае этот пункт выглядел вот так:

Откроется XML-файл примерно такого содержания:

Содержимое этого файла необходимо скопировать в «Блокнот».  Теперь необходимо удалить всё из файла в Visual Studio. Согласен с автором первоисточника данной инструкции, что звучит такой пункт, мягко говоря, угрожающе. Но, на деле, ничего страшного не произойдет. Удаляйте — не переживайте (копия лежит в «Блокноте»).

Вместо только что удаленного текста вставьте следующий код необходимый для консольного приложения(здесь небольшое расхождение с первоисточником):

<Project Sdk="Microsoft.NET.Sdk">
    <PropertyGroup>
        <OutputType>Exe</OutputType>
        <TargetFramework>netcoreapp3.1</TargetFramework>
    </PropertyGroup>
</Project>

Теперь переходим в Блокнот и ищем там строку PackageReference. Если ничего не нашли — двигаемся дальше. Если нашли PackageReference, то копируем весь узел ItemGroup, содержащий PackageReference, в файл проекта, открытого в Visual Studio. Вставлять скопированный текст необходимо перед закрывающим тегом </Project>, а не в конец файла, как это было сказано в первоисточнике. Скопированный блок должен выглядеть так:

<ItemGroup>
    <PackageReference Include="SharpKml.Core">
        <Version>5.1.2</Version>
    </PackageReference>
    <PackageReference Include="System.Runtime.WindowsRuntime" Version="4.7.0" />
</ItemGroup>

У меня такой блок оказался всего один, поэтом итоговый файл *.cproj стал выглядеть вот так:

<Project Sdk="Microsoft.NET.Sdk">
    <PropertyGroup>
        <OutputType>Exe</OutputType>
        <TargetFramework>netcoreapp3.1</TargetFramework>
    </PropertyGroup>
    <ItemGroup>
        <PackageReference Include="SharpKml.Core">
            <Version>5.1.2</Version>
        </PackageReference>
    </ItemGroup>
</Project>

Теперь делаем то же самое, что и выше, но только для ProjectReference. Нашли  ProjectReference — копируем весь ItemGroup в конец файла перед закрывающим тегом </Project>. У меня в Блокноте таких строк не оказалось, поэтому я перешел к следующему шагу — сохраняем все и перезагружаем проект кликнув правой кнопкой мыши по названию проекта и выбрав пункт «Перезагрузить проект». Теперь наш проект в «Обозревателе решений» стал выглядеть немного по другому:

В принципе, на этом переход с .NET Framework 4.7.2 на NET Core 3.1 закончен — можно попробовать запустить проект и убедиться, что все работает. Однако у меня при попытке запуска приложения посыпались ошибки вида:

Ошибка CS0579 Повторяющийся атрибут «System.Reflection.AssemblyCompanyAttribute» ConsoleApp3 J:\CSharp Sources\Mrr2017_recovery\Mrr2017\ConsoleApp3\obj\Debug\netcoreapp3.1\ConsoleApp3.AssemblyInfo.cs

Помогло удаление файла AssemblyInfo.cs

То, что удаление файла AssemblyInfo.cs помогло мне — не значит, что поможет вам. Если не жалко проект — можете повторить мои действия, но лучше проконсультироваться со специалистами.

После этого проект запустился, работоспособность не нарушилась. Однако встретилась другая проблема.

Использование System.Windows в .NET Core

До перехода на .NET Core для работы с координатами точек, полигонами и так далее я использовал стандартные классы Windows из пространства имен System.Windows (добавив предварительно ссылку в Зависимости). Однако, в .NET Core Visual Studio «ругнулась» на то, что в этом пространстве имен классов типа Point и Rect не существует и пометила using System.Windows  серым цветом с предложением удалить неиспользуемые директивы:

Решение нашлось на StackOverflow. Для того, чтобы использовать стандартные примитивы из Windows типа Point и Rect для приложения на .NET Core 3.x необходимо установить пакет System.Runtime.WindowsRuntimeчерез менеджер пакетов NuGet. Для этого кликаем по названию проекта правой кнопкой мыши и выбираем пункт «Управление пакетами NuGet»

В окне менеджера пакетов переходим на вкладку «Обзор» и забиваем в строку поиска System.Runtime.WindowsRuntime.

Жмем кнопку установить и ждем пока NuGet установит пакет. После установки пакета проект в «Обозревателе решений» станет выглядеть вот так:

Теперь необходимо добавить в проект пространство имен:

using Windows.Foundation;

И можно пользоваться классами Point и Rect:

Вот так простое человеческое желание использовать в работе новейшие возможности языка C# привели к переносу проекта c .NET Framework 4.7.2 на NET Core 3.1. Надеюсь, что вам эта небольшая инструкция пригодиться.

Источники информации:

  1. Статья на Хабре: Перенос десктопных приложений на .NET Core
  2. StackOverflow: Using System.Windows in .NET Core
Подписаться
Уведомить о
guest
1 Комментарий
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии