方法: WPF デスクトップ アプリを .NET Core に移植するHow to: Port a WPF desktop app to .NET Core

この記事では、Windows Presentation Foundation (WPF) ベースのデスクトップ アプリを .NET Framework から .NET Core 3.0 に移植する方法について説明します。This article describes how to port your Windows Presentation Foundation-based (WPF) desktop app from .NET Framework to .NET Core 3.0. .NET Core 3.0 SDK には、WPF アプリケーションのサポートが含まれています。The .NET Core 3.0 SDK includes support for WPF applications. WPF は、まだ Windows 専用のフレームワークであるため、Windows 上でのみ実行されます。WPF is still a Windows-only framework and only runs on Windows. この例では、.NET Core CLI を使用して、プロジェクトの作成と管理を行います。This example uses the .NET Core SDK CLI to create and manage your project.

この記事では、さまざまな名前が使用して、移行で使用されるファイルの種類を識別しています。In this article, various names are used to identify types of files used for migration. 実際のファイルの名前とは異なっているため、自分のプロジェクトを移行するときは、次の一覧の名前に置き換えて説明をお読みください。When migrating your project, your files will be named differently, so mentally match them to the ones listed below:

ファイルFile 説明Description
MyApps.slnMyApps.sln ソリューション ファイルの名前。The name of the solution file.
MyWPF.csprojMyWPF.csproj 移植する .NET Framework WPF プロジェクトの名前。The name of the .NET Framework WPF project to port.
MyWPFCore.csprojMyWPFCore.csproj 作成する新しい .NET Core プロジェクトの名前。The name of the new .NET Core project you create.
MyAppCore.exeMyAppCore.exe .NET Core WPF アプリの実行可能ファイル。The .NET Core WPF app executable.

重要

この記事では C# をターゲット言語として使用しますが、VB.NET でも手順は同じです。ただし、VB.NET では、 .csproj ファイルと .cs ファイルの代わりに、それぞれ .vbproj ファイルと .vb ファイルを使用します。Even though this article uses C# as the target language, the steps are the same for VB.NET, except that VB.NET uses .vbproj and .vb files instead of .csproj and .cs files, respectively.

必須コンポーネントPrerequisites

  • 実行したいデザイナー作業用の Visual Studio 2019Visual Studio 2019 for any designer work you want to do.

    次の Visual Studio ワークロードをインストールします。Install the following Visual Studio workloads:

    • .NET デスクトップ開発.NET desktop development
    • .NET クロスプラットフォーム開発.NET cross-platform development
  • 問題なくビルドされて実行されているソリューション内の作業用 WPF プロジェクト。A working WPF project in a solution that builds and runs without issue.

  • 最新の .NET Core 3.0 のプレビューをインストールします。Install the latest .NET Core 3.0 preview.

注意

Visual Studio 2017 では、.NET Core 3.0 プロジェクトはサポートされていません。Visual Studio 2017 doesn't support .NET Core 3.0 projects. Visual Studio 2019 では .NET Core 3.0 プロジェクトがサポートされますが、.NET Core WPF ビジュアル デザイナーのサポートは制限されています。Visual Studio 2019 supports .NET Core 3.0 projects but has limited support for the .NET Core WPF visual designer. 完全にサポートされるビジュアル デザイナーを使用するには、.NET Core プロジェクトとそのファイルを共有するソリューション内に .NET Framework WPF プロジェクトが必要です。To use a fully-supported visual designer, you must have a .NET Framework WPF project in your solution that shares its files with the .NET Core project.

次の例を考えてみましょうConsider

.NET Framework WPF アプリケーションを移植するときは、いくつかの点を考慮する必要があります。When porting a .NET Framework WPF application, there are a few things you must consider.

  1. アプリケーションが移行に適した候補であることを確認する。Check that your application is a good candidate for migration.

    .NET Portability Analyzer を使用して、プロジェクトを .NET Core 3.0 に移行できるかどうかを判断します。Use the .NET Portability Analyzer to determine if your project will migrate to .NET Core 3.0. プロジェクトが .NET Core 3.0 では問題が発生する場合は、アナライザーによってこれらの問題を特定できます。If your project has issues with .NET Core 3.0, the analyzer helps you identify those problems.

  2. WPF の別のバージョンを使用している。You're using a different version of WPF.

    .NET Core 3.0 プレビュー 1 がリリースされたときに、WPF は GitHub でオープン ソースになりました。When .NET Core 3.0 Preview 1 was released, WPF went open-source on GitHub. .NET Core WPF のコードは、.NET Framework WPF コード ベースの 1 つの分岐です。The code for .NET Core WPF is a fork of the .NET Framework WPF code base. 違いの存在によって、アプリが移植されない可能性があります。It's possible some differences exist and your app won't port.

  3. Windows 互換機能パックが移行に役立つ可能性がある。The Windows Compatibility Pack may help you migrate.

    .NET Framework で利用できる一部の API は、.NET Core 3.0 では利用できません。Some APIs that are available in .NET Framework aren't available in .NET Core 3.0. Windows 互換機能パックによってその多くの API が追加され、WPF アプリに .NET Core との互換性を持たせるために役立つ可能性があります。The Windows Compatibility Pack adds many of these APIs and may help your WPF app become compatible with .NET Core.

  4. 自分のプロジェクトで使用されている NuGet パッケージを更新する。Update the NuGet packages used by your project.

    移行する前に、常に NuGet パッケージの最新バージョンを使用することをお勧めします。It's always a good practice to use the latest versions of NuGet packages before any migration. アプリケーションで NuGet パッケージを参照している場合は、最新バージョンに更新してください。If your application is referencing any NuGet packages, update them to the latest version. アプリケーションが正常にビルドされることを確認します。Ensure your application builds successfully. アップグレード後にパッケージ エラーが発生した場合は、コードを壊さない最新のバージョンにパッケージをダウングレードします。After upgrading, if there are any package errors, downgrade the package to the latest version that doesn't break your code.

  5. Visual Studio 2019 では、.NET Core 3.0 用の WPF デザイナーはまだサポートされていないVisual Studio 2019 doesn't yet support the WPF Designer for .NET Core 3.0

    現時点では、Visual Studio の WPF デザイナーを使用する場合は、既存の .NET Framework WPF プロジェクト ファイルを保持する必要があります。Currently, you need to keep your existing .NET Framework WPF project file if you want to use the WPF Designer from Visual Studio.

新しい SDK プロジェクトを作成するCreate a new SDK project

作成する新しい .NET Core 3.0 プロジェクトは、.NET Framework プロジェクトとは別のディレクトリに配置する必要があります。The new .NET Core 3.0 project you create must be in a different directory from your .NET Framework project. 両方が同じディレクトリに配置されている場合は、obj ディレクトリ内に生成されているファイルと競合する可能性があります。If they're both in the same directory, you may run into conflicts with the files that are generated in the obj directory. この例では、SolutionFolder ディレクトリに MyWPFAppCore という名前のディレクトリを作成します。In this example, you'll create a directory named MyWPFAppCore in the SolutionFolder directory:

SolutionFolder
├───MyApps.sln
├───MyWPFApp
│   └───MyWPF.csproj
└───MyWPFAppCore      <--- New folder for core project

次に、MyWPFAppCore ディレクトリに MyWPFCore.csproj プロジェクトを作成する必要があります。Next, you need to create the MyWPFCore.csproj project in the MyWPFAppCore directory. このファイルは、任意のテキスト エディターを使用して手動で作成できます。You can create this file manually by using the text editor of choice. 次の XML に貼り付けます。Paste in the following XML:

<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">

  <PropertyGroup>
    <OutputType>WinExe</OutputType>
    <TargetFramework>netcoreapp3.0</TargetFramework>
    <UseWPF>true</UseWPF>
  </PropertyGroup>

</Project>

プロジェクト ファイルを手動で作成しない場合は、Visual Studio または .NET Core SDK を使用して生成できます。If you don't want to create the project file manually, you can use Visual Studio or the .NET Core SDK to generate the project. ただし、プロジェクト ファイル以外のプロジェクト テンプレートによって生成されるすべてのファイルを削除する必要があります。However, you must delete all other files generated by the project template except for the project file. SDK を使用するには、次のコマンドを SolutionFolder ディレクトリから実行します。To use the SDK, run the following command from the SolutionFolder directory:

dotnet new wpf -o MyWPFAppCore -n MyWPFCore

MyWPFCore.csproj を作成した後、ディレクトリ構造は次のようになります。After you create the MyWPFCore.csproj, your directory structure should look like the following:

SolutionFolder
├───MyApps.sln
├───MyWPFApp
│   └───MyWPF.csproj
└───MyWPFAppCore
    └───MyWPFCore.csproj

SolutionFolder ディレクトリから Visual Studio または .NET Core CLI を使用して、MyWPFCore.csproj プロジェクトを MyApps.sln に追加できます。You'll want to add the MyWPFCore.csproj project to MyApps.sln with either Visual Studio or the .NET Core CLI from the SolutionFolder directory:

dotnet sln add .\MyWPFAppCore\MyWPFCore.csproj

アセンブリ情報の生成を修正するFix assembly info generation

.NET Framework で作成された Windows Presentation Foundation プロジェクトには、生成されるアセンブリのバージョンなどのアセンブリの属性を格納する AssemblyInfo.cs ファイルが含まれています。Windows Presentation Foundation projects that were created with .NET Framework include an AssemblyInfo.cs file, which contains assembly attributes such as the version of the assembly to be generated. SDK スタイルのプロジェクトでは、SDK プロジェクト ファイルに基づいて、この情報が自動的に生成されます。SDK-style projects automatically generate this information for you based on the SDK project file. 両方の種類の "アセンブリ情報" があると、競合が発生します。Having both types of "assembly info" creates a conflict. この問題は、自動生成を無効にして、既存の AssemblyInfo.cs ファイルをプロジェクトに強制的に使用させることで解決します。Resolve this problem by disabling automatic generation, which forces the project to use your existing AssemblyInfo.cs file.

メインの <PropertyGroup> ノードに追加する 3 つの設定があります。There are three settings to add to the main <PropertyGroup> node.

  • GenerateAssemblyInfoGenerateAssemblyInfo
    このプロパティを false に設定すると、アセンブリ属性が生成されなくなります。When you set this property to false, it won't generate the assembly attributes. これにより、.NET Framework プロジェクトからの既存の AssemblyInfo.cs ファイルとの競合を回避できます。This avoids the conflict with the existing AssemblyInfo.cs file from the .NET Framework project.

  • AssemblyNameAssemblyName
    このプロパティの値は、コンパイル時に作成される出力バイナリです。The value of this property is the output binary created when you compile. 名前には、拡張子を追加する必要はありません。The name doesn't need an extension added to it. たとえば、MyCoreApp を使用すると、MyCoreApp.exe が作成されます。For example, using MyCoreApp produces MyCoreApp.exe.

  • RootNamespaceRootNamespace
    プロジェクトで使用される既定の名前空間。The default namespace used by your project. これは、.NET Framework プロジェクトの既定の名前空間と一致させる必要があります。This should match the default namespace of the .NET Framework project.

これら 3 つの要素を、MyWPFCore.csproj ファイルの <PropertyGroup> ノードに追加します。Add these three elements to the <PropertyGroup> node in the MyWPFCore.csproj file:

<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">

  <PropertyGroup>
    <OutputType>WinExe</OutputType>
    <TargetFramework>netcoreapp3.0</TargetFramework>
    <UseWPF>true</UseWPF>

    <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
    <AssemblyName>MyCoreApp</AssemblyName>
    <RootNamespace>MyWPF</RootNamespace>
  </PropertyGroup>

</Project>

ソース コードを追加するAdd source code

現時点では、MyWPFCore.csproj プロジェクトには、コンパイルされるコードはありません。Right now, the MyWPFCore.csproj project doesn't compile any code. 既定では、.NET Core プロジェクトには、現在のディレクトリとすべての子ディレクトリ内のすべてのソース コードが自動的に含まれます。By default, .NET Core projects automatically include all source code in the current directory and any child directories. 相対パスを使用して、.NET Framework プロジェクトのコードが含まれるようにプロジェクトを構成する必要があります。You must configure the project to include code from the .NET Framework project using a relative path. .NET Framework プロジェクトで、ウィンドウとコントロールのアイコンとリソース用の .resx ファイルが使用されている場合は、それらも含める必要があります。If your .NET Framework project used .resx files for icons and resources for your windows and controls, you'll need to include those too.

プロジェクトに追加する必要がある最初の <ItemGroup> ノードには、アプリで使用されるスタートアップ構成とリソースを表す App.xaml ファイルがあります。The first <ItemGroup> node you need to add to your project includes the App.xaml file that represents the startup config and resources your app uses. App.xaml ファイルには App.xaml.cs ファイルも付随しますが、それは別の <ItemGroup> に自動的に入ります。The App.xaml file also has an accompanying App.xaml.cs file, but it will be automatically included in a different <ItemGroup>.

  <ItemGroup>
    <ApplicationDefinition Include="..\MyWPFApp\App.xaml">
      <Generator>MSBuild:Compile</Generator>
    </ApplicationDefinition>
  </ItemGroup>

次に、次の <ItemGroup> コードをプロジェクトに追加します。Next, add the following <ItemGroup> node to your project. 各ステートメントには、子ディレクトリを含むファイルの glob パターンが含まれています。Each statement includes a file glob pattern that includes child directories. これには、プロジェクトのソース コード、設定ファイル、リソースが含まれます。It includes the source code for your project, any settings files, and any resources. obj ディレクトリは明示的に除外されます。The obj directory is explicitly excluded.

  <ItemGroup>
    <Compile Include="..\MyWPFApp\**\*.cs" Exclude="..\MyWPFApp\obj\**" />
    <None Include="..\MyWPFApp\**\*.settings" />
    <EmbeddedResource Include="..\MyWPFApp\**\*.resx" />
  </ItemGroup>

次に、App.xaml ファイルを除くすべての xaml ファイルの <Page> エントリが含まれる別の <ItemGroup> ノードをプロジェクトに含めます。Next, include another <ItemGroup> node that contains a <Page> entry for every xaml file in your project except the App.xaml file. これには、xaml 形式のすべてのウィンドウ、ページ、リソースが含まれます。These contain all of the windows, pages, and resources that are in xaml format. ここでは glob パターンを使用できません。ファイルごとにエントリを追加し、使用されている <Generator> を示す必要があります。You cannot use a glob pattern here and must add an entry for every file and indicate the <Generator> used.

  <ItemGroup>
    <Page Include="..\MyWPFApp\MainWindow.xaml">
      <Generator>MSBuild:Compile</Generator>
    </Page>
  </ItemGroup>

NuGet パッケージを追加するAdd NuGet packages

.NET Framework プロジェクトによって参照される各 NuGet パッケージを.NET Core プロジェクトに追加します。Add each NuGet package referenced by the .NET Framework project to the .NET Core project.

ほとんどの場合、.NET Framework WPF アプリには、packages.config プロジェクトによって参照されるすべての NuGet パッケージの一覧を含むファイルがあります。Most likely your .NET Framework WPF app has a packages.config file that contains a list of all of the NuGet packages that are referenced by your project. この一覧を調べて、.NET Core プロジェクトに追加する NuGet パッケージを決定できます。You can look at this list to determine which NuGet packages to add to the .NET Core project. たとえば、.NET Framework プロジェクトで MahApps.Metro NuGet パッケージが参照される場合、Visual Studio でそれをプロジェクトに追加します。For example, if the .NET Framework project references the MahApps.Metro NuGet package, add it to the project with Visual Studio. SolutionFolder ディレクトリから .NET Core CLI を使用してパッケージ参照を追加することもできます。You can also add the package reference with the .NET Core CLI from the SolutionFolder directory:

dotnet add .\MyWPFAppCore\MyWPFCore.csproj package MahApps.Metro -v 2.0.0-alpha0262

上のコマンドによって、次の NuGet 参照が MyWPFCore.csproj プロジェクトに追加されます。The previous command would add the following NuGet reference to the MyWPFCore.csproj project:

  <ItemGroup>
    <PackageReference Include="MahApps.Metro" Version="2.0.0-alpha0262" />
  </ItemGroup>

コンパイルの問題Problems compiling

プロジェクトのコンパイルで問題が発生した場合は、.NET Framework では使用できるが .NET Core では使用できない Windows 専用 API が使用されている可能性があります。If you have problems compiling your projects, you may be using some Windows-only APIs that are available in .NET Framework but not available in .NET Core. Windows 互換機能パック NuGet パッケージのプロジェクトへの追加を試すことができます。You can try adding the Windows Compatibility Pack NuGet package to your project. このパッケージは Windows でのみ実行され、約 20,000 の Windows API を .NET Core と .NET Standard プロジェクトに追加します。This package only runs on Windows and adds about 20,000 Windows APIs to .NET Core and .NET Standard projects.

dotnet add .\MyWPFAppCore\MyWPFCore.csproj package Microsoft.Windows.Compatibility

前のコマンドにより、以下が MyWPFCore.csproj プロジェクトに追加されます。The previous command adds the following to the MyWPFCore.csproj project:

  <ItemGroup>
    <PackageReference Include="Microsoft.Windows.Compatibility" Version="2.0.1" />
  </ItemGroup>

WPF デザイナーWPF Designer

この記事で説明したように、Visual Studio 2019 では、.NET Framework プロジェクトでのみ WPF デザイナーがサポートされます。As detailed in this article, Visual Studio 2019 only supports the WPF Designer in .NET Framework projects. サイドバイサイドの .NET Core プロジェクトを作成することで、.NET Framework プロジェクトを使用してフォームをデザインしながら、.NET Core でプロジェクトをテストできます。By creating a side-by-side .NET Core project, you can test your project with .NET Core while you use the .NET Framework project to design forms. ソリューション ファイルには、.NET Framework と .NET Core の両方のプロジェクトが含まれます。Your solution file includes both the .NET Framework and .NET Core projects. .NET Framework プロジェクトにフォームとコントロールを追加してデザインし、.NET Core プロジェクトに追加されたファイルの glob パターンに基づいて、新しいファイルまたは変更されたファイルが、.NET Core プロジェクトに自動的に追加されます。Add and design your forms and controls in the .NET Framework project, and based on the file glob patterns we added to the .NET Core projects, any new or changed files will automatically be included in the .NET Core projects.

Visual Studio 2019 で WPF デザイナーがサポートされるようになったら、.NET Core プロジェクト ファイルの内容を .NET Framework プロジェクト ファイルにコピーして貼り付けることができます。Once Visual Studio 2019 supports the WPF Designer, you can copy/paste the content of your .NET Core project file into the .NET Framework project file. その後、<Source><EmbeddedResource> 項目を使用して追加されたファイルの glob パターンを削除します。Then delete the file glob patterns added with the <Source> and <EmbeddedResource> items. アプリで使用されるすべてのプロジェクト参照のパスを修正します。Fix the paths to any project reference used by your app. これにより、.NET Framework プロジェクトが .NET Core プロジェクトに効率的にアップグレードされます。This effectively upgrades the .NET Framework project to a .NET Core project.

次の手順Next steps