El próximo lanzamiento de netcore 3.0 le permite ejecutar wpf en netcore. El procedimiento de traducción para un proyecto simple lleva de uno a dos días. Cada uno posterior es mucho más rápido.

Preparación y conversión de proyectos.
El primer paso en la preparación es instalar y ejecutar Portability Analyzer. En la salida, obtenemos una placa de Excel en la que vemos cuánto cumple nuestro código los nuevos requisitos.

El procedimiento para convertir proyectos antiguos se convirtió en varias etapas.
- Microsoft recomienda actualizar la versión de marco a .Net Framework 4.7.3 para proyectos más antiguos.
- Convierta la estructura de proyectos antiguos a un nuevo formato. Reemplace los paquetes.config con PackageReference.
- En tercer lugar, ajuste la estructura del archivo csproj al formato netcore.
Quiero agradecer a Emil Yangirov con su informe sobre la migración a netcore, que fue muy útil. Enlace a su informe.
Resultó que decidimos saltarnos la primera etapa. La segunda etapa implicó la necesidad de convertir más de 100 proyectos. Cómo se lleva a cabo este proceso se puede leer en detalle aquí .
Entendimos que no se podía evitar la automatización. Utiliza la solución preparada : CsprojToVs2017 . Deje que el nombre del proyecto no le moleste: la utilidad también se convierte para Visual Studio 2019.
Que va a pasar
El tamaño de los archivos csproj disminuirá. ¿Por qué? Todos los archivos conectados con código fuente dejarán csproj, se eliminarán las líneas adicionales, etc.
- <Compile Include="Models\ViewModels\HistoryViewModel.cs" /> - <Compile Include="Properties\Settings.Designer.cs"> - <AutoGen>True</AutoGen> - <DependentUpon>Settings.settings</DependentUpon> - <DesignTimeSharedInput>True</DesignTimeSharedInput> - </Compile>
La biblioteca conectada y las entradas de subproyecto se reducirán.
- <Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL"> - <HintPath>..\packages\NLog.4.3.3\lib\net45\NLog.dll</HintPath> - <Private>False</Private> - </Reference> - <ProjectReference Include="..\WpfCommon\WpfCommon.csproj"> - <Project>{7ce118f6-2978-42a7-9e6a-ee5cd3057e29}</Project> - <Name>WpfCommon</Name> - </ProjectReference> + <PackageReference Include="NLog" Version="4.6.7" /> + <ProjectReference Include="..\WpfCommon\WpfCommon.csproj" />
La configuración general para varios proyectos se puede llevar a cabo en Directory.BuildProps. Este es un archivo tan especial que MsBuild analiza.
Por analogía con .gitignore y .editorconfig, tenemos un archivo global con configuraciones generales.
Agregamos la configuración privada de PropertyGroup para subdirectorios / proyectos a archivos específicos de csproj. Los detalles se pueden encontrar aquí.
Dependencias
Las dependencias antiguas serán para netframework. Tendrá que encontrar una alternativa o paquetes similares para nuget. Para muchos proyectos, ya existe un paquete Nuget que admite netcore o netstandard.
Por ejemplo, el proyecto usó una versión anterior de DI Unity. Al cambiar a una nueva versión, tuve que actualizar usando y arreglar el código en dos o tres lugares.
using Microsoft.Practices.Unity -> using Unity;
Y puede ser suficiente para actualizar todas las versiones de paquetes. Y por si acaso, reinicie el estudio.
Cambiar csproj para usar netcore
En proyectos que utilizan controles WPF, debe cambiar el formato a Microsoft.NET.Sdk.WindowsDesktop:
-<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> - <PropertyGroup/>
+<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop"> + <PropertyGroup> + <TargetFramework>netcoreapp3.0</TargetFramework> + <AssemblyTitle>MyEnterpriseLibrary</AssemblyTitle> + <Product>MyEnterpriseLibrary</Product> + <OutputPath>..\bin\$(Configuration)\</OutputPath> + <UseWPF>true</UseWPF> + + <GenerateAssemblyInfo>false</GenerateAssemblyInfo> </Project>
Para ClassLibrary, simplemente deje el tipo Microsoft.NET.Sdk:
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>netcoreapp3.0</TargetFramework> <AssemblyTitle>MyEnterpriseLibrary</AssemblyTitle> <Product>MyEnterpriseLibrary</Product> <OutputPath>..\bin\$(Configuration)\</OutputPath> </PropertyGroup> </Project>
Quizás, en algunos proyectos que usan los controles de formularios Windows Forms, también tendrá que mantener una llamada a UseWindowsForms:
<UseWindowsForms>true</UseWindowsForms>
Csproj ha cambiado su enfoque al flujo de compilación de recursos. Anteriormente, el formato le permitía conectar el archivo a recursos y contenido,
e incluso donde.
Ahora, si el archivo está en algún tipo de colección, debe eliminarlo y solo luego incluirlo en el grupo deseado.
Aquí está el código que extrae file.json de la colección None y lo conecta a la colección Resource.
<ItemGroup> <None Exclude="file.json" /> <Resource Include="file.json" /> </ItemGroup>
En consecuencia, todos los archivos que no son fuente deben eliminarse de la colección None y conectarse a los recursos. Por ejemplo, así:
<ItemGroup Condition="'$(UseWPF)' == 'true' And $(UseWindowsForms) != 'true'"> <None Exclude="**\*.xml;**\*.xsl;**\*.xslt;**\*.txt;**\*.bmp;**\*.ico;**\*.cur;**\*.gif;**\*.jpeg;**\*.jpe;**\*.jpg;**\*.png;**\*.dib;**\*.tiff;**\*.tif;**\*.inf;**\*.compositefont;**\*.otf;**\*.ttf;**\*.ttc;**\*.tte" /> <Resource Include="**\*.xml;**\*.xsl;**\*.xslt;**\*.txt;**\*.bmp;**\*.ico;**\*.cur;**\*.gif;**\*.jpeg;**\*.jpe;**\*.jpg;**\*.png;**\*.dib;**\*.tiff;**\*.tif;**\*.inf;**\*.compositefont;**\*.otf;**\*.ttf;**\*.ttc;**\*.tte" /> </ItemGroup>
Algunas líneas tendrán que eliminarse, ya que eliminan la versión de framework en .net framework 4.0.
Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets"
En algunos lugares después de la conversión, permanecerán entradas extrañas que impiden que el proyecto se compile. Aquí hay ejemplos de tales construcciones:
- <ItemGroup> - <EmbeddedResource Include="**\*.resx" /> - </ItemGroup> - <Compile Remove="something.cs">
Clientes WCF
Si usó WCF, tendrá que regenerar los enlaces. Cómo hacerlo correctamente se puede leer aquí: docs.microsoft.com/en-us/dotnet/desktop-wpf/migration/convert-project-from-net-framework#updating-wcf-client-usage
¿Qué no despegará?
Stylecop y análisis de código.
Algunos de nuestros proyectos utilizaron analizadores de código estático. Al cambiar a las ediciones modernas de MsBuild, el recopilador sugiere explícitamente el uso de nuevos analizadores Roslyn en lugar de los antiguos analizadores de código estático.
Tuve que traducir las viejas reglas para usar los paquetes Stylecop.Analyzers y FxCop.Analyzers Nuget siguiendo esta guía de Microsoft. .
Si tiene varios proyectos en diferentes carpetas (mono-repositorio), es mucho más conveniente desconectar la conexión de los analizadores en Build.props y configurarlos con un conjunto de reglas uniforme.
Esto es lo que sucedió:
- <RunCodeAnalysis>true</RunCodeAnalysis> + <PackageReference Include="FxCop.Analyzers" Version="2.9.4" />
Archivos - Huérfanos
El antiguo formato csproj implicaba una conexión explícita de archivos .cs. Al mismo tiempo, a veces, al renombrar o refactorizar archivos antiguos se eliminaban de csproj, pero no se eliminaban explícitamente del sistema de archivos. En el nuevo formato csproj, todos los archivos que están en la carpeta del proyecto se recogerán automáticamente, solo los que no se hayan eliminado antes. Lo más probable es que haya errores en ellos, apelaciones a clases, métodos y recursos que ya no existen. Resultará en errores comunes durante el ensamblaje.
Recursos
En uno de los proyectos, se utilizó SplashScreen, uno de los cuales se seleccionó al azar al inicio. La instancia de SplashScreen se inicializó con la ruta al recurso. Por alguna razón, no fue posible ganar en netcore 3: jura por la falta de un recurso.
Código que parece funcionar
Es probable que el código que funcionó en .Net Framework también funcione en netcore. Pero puede haber secciones de código a las que el compilador cerró los ojos. En este caso, si el código llega a instrucciones que no están implementadas en netcore, detectaremos PlatformException.
Para buscar dichos lugares, hay un analizador especial: github.com/dotnet/platform-compat .
¿Por qué todo esto si el proyecto está funcionando?
No hay muchas ventajas, pero sin embargo, lo son.
- Su código recibirá todas las optimizaciones agregadas a netcore.
- La velocidad de inicio de la aplicación aumentará.
- Dirigido a futuras versiones de C #.
- Tiempo de compilación reducido para proyectos gracias a las nuevas versiones de csproj.
- Embalaje en single exe.
Microsoft no está empujando la aplicación a una nueva base. Sin embargo, si su aplicación es un complemento de otra más grande, entonces tiene sentido apuntar a futuras versiones, que también pueden estar en netcore.
Enlaces utiles