Windows フォーム デスクトップ アプリを .NET Core に移植する方法How to port a Windows Forms desktop app to .NET Core

この記事では、Windows フォームベースのデスクトップ アプリを、.NET Framework から .NET Core 3.0 以降に移植する方法について説明します。This article describes how to port your Windows Forms-based desktop app from .NET Framework to .NET Core 3.0 or later. .NET Core 3.0 SDK には、Windows Forms アプリケーションのサポートが含まれています。The .NET Core 3.0 SDK includes support for Windows Forms applications. Windows Forms は、まだ Windows 専用のフレームワークであるため、Windows 上でのみ実行されます。Windows Forms 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.
MyForms.csprojMyForms.csproj 移植する .NET Framework Windows Forms プロジェクトの名前。The name of the .NET Framework Windows Forms project to port.
MyFormsCore.csprojMyFormsCore.csproj 作成する新しい .NET Core プロジェクトの名前。The name of the new .NET Core project you create.
MyAppCore.exeMyAppCore.exe .NET Core Windows Forms アプリの実行可能ファイル。The .NET Core Windows Forms app executable.

必須コンポーネント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 Core クロスプラットフォームの開発.NET Core cross-platform development
  • 問題なくビルドされて実行されているソリューション内の作業用 Windows Forms プロジェクト。A working Windows Forms project in a solution that builds and runs without issue.

  • C# でコードを書いたプロジェクト。A project coded in C#.

  • .NET Core 3.0 以降.NET Core 3.0 or later.

注意

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 3.0 Windows Forms プロジェクト用のビジュアル デザイナーはまだサポートされていません。Visual Studio 2019 supports .NET Core 3.0 projects but doesn't yet support the visual designer for .NET Core 3.0 Windows Forms projects. ビジュアル デザイナーを使用するには、.NET Core プロジェクトとフォーム ファイルを共有するソリューション内に .NET Windows フォーム プロジェクトを配置する必要です。To use the visual designer, you must have a .NET Windows Forms project in a solution that shares the forms files with the .NET Core project.

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

.NET Framework Windows Forms アプリケーションを移植するときは、いくつかの点を考慮する必要があります。When porting a .NET Framework Windows Forms 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. Windows Forms の別のバージョンを使用している。You're using a different version of Windows Forms.

    .NET Core 3.0 Preview 1 がリリースされたときに、Windows フォームは GitHub でオープン ソースになりました。When .NET Core 3.0 Preview 1 was released, Windows Forms went open source on GitHub. .NET Core Windows フォームのコードは、.NET Framework Windows フォーム コード ベースからの 1 つの分岐です。The code for .NET Core Windows Forms is a fork of the .NET Framework Windows Forms codebase. 違いの存在によって、アプリが移植されない可能性があります。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 が追加され、Windows Forms アプリの .NET Core との互換性が促進される可能性があります。The Windows Compatibility Pack adds many of these APIs and may help your Windows Forms 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 のフォーム デザイナーはまだサポートされていないVisual Studio 2019 doesn't yet support the Forms Designer for .NET Core 3.0

    現時点では、Visual Studio のフォーム デザイナーを使用する場合は、既存の .NET Framework Windows Forms プロジェクト ファイルを保持する必要があります。Currently, you need to keep your existing .NET Framework Windows Forms project file if you want to use the Forms 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 ディレクトリに MyFormsAppCore という名前のディレクトリを作成します。In this example, we'll create a directory named MyFormsAppCore in the SolutionFolder directory:

SolutionFolder
├───MyApps.sln
├───MyFormsApp
│   └───MyForms.csproj
└───MyFormsAppCore      <--- New folder for core project

次に、MyFormsAppCore ディレクトリに MyFormsCore.csproj プロジェクトを作成する必要があります。Next, you need to create the MyFormsCore.csproj project in the MyFormsAppCore 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>
    <UseWindowsForms>true</UseWindowsForms>
  </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 winforms -o MyFormsAppCore -n MyFormsCore

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

SolutionFolder
├───MyApps.sln
├───MyFormsApp
│   └───MyForms.csproj
└───MyFormsAppCore
    └───MyFormsCore.csproj

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

dotnet sln add .\MyFormsAppCore\MyFormsCore.csproj

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

.NET Framework で作成された Windows Forms プロジェクトには、生成されるアセンブリのバージョンなどのアセンブリの属性を格納する AssemblyInfo.cs ファイルが含まれています。Windows Forms 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 つの要素を、MyFormsCore.csproj ファイルの <PropertyGroup> ノードに追加します。Add these three elements to the <PropertyGroup> node in the MyFormsCore.csproj file:

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

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

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

</Project>

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

現時点では、MyFormsCore.csproj プロジェクトには、コンパイルされるコードはありません。Right now, the MyFormsCore.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 forms, you'll need to include those too.

次の <ItemGroup> コードを、プロジェクトに追加します。Add the following <ItemGroup> node to your project. 各ステートメントには、子ディレクトリを含むファイルの glob パターンが含まれています。Each statement includes a file glob pattern that includes child directories.

  <ItemGroup>
    <Compile Include="..\MyFormsApp\**\*.cs" />
    <EmbeddedResource Include="..\MyFormsApp\**\*.resx" />
  </ItemGroup>

または、.NET Framework プロジェクトの各ファイルに対する <Compile> または <EmbeddedResource> エントリを作成できます。Alternatively, you can create a <Compile> or <EmbeddedResource> entry for each file in your .NET Framework project.

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 Windows Forms アプリには、packages.config プロジェクトによって参照されるすべての NuGet パッケージの一覧を含むファイルがあります。Most likely your .NET Framework Windows Forms 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 プロジェクトで MetroFrameworkMetroFramework.Design、および MetroFramework.Fonts NuGet パッケージが参照されている場合は、SolutionFolder ディレクトリから Visual Studio または .NET Core CLI のいずれかを使用して、それぞれをプロジェクトに追加します。For example, if the .NET Framework project referenced the MetroFramework, MetroFramework.Design, and MetroFramework.Fonts NuGet packages, add each to the project with either Visual Studio or the .NET Core CLI from the SolutionFolder directory:

dotnet add .\MyFormsAppCore\MyFormsCore.csproj package MetroFramework
dotnet add .\MyFormsAppCore\MyFormsCore.csproj package MetroFramework.Design
dotnet add .\MyFormsAppCore\MyFormsCore.csproj package MetroFramework.Fonts

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

  <ItemGroup>
    <PackageReference Include="MetroFramework" Version="1.2.0.3" />
    <PackageReference Include="MetroFramework.Design" Version="1.2.0.3" />
    <PackageReference Include="MetroFramework.Fonts" Version="1.2.0.3" />
  </ItemGroup>

移植制御ライブラリPort control libraries

Windows Forms 制御ライブラリ プロジェクトを移植する場合の指示は、.NET Framework Windows Forms アプリ プロジェクトの移植と同じですが、いくつかの設定が異なります。If you have a Windows Forms Controls library project to port, the directions are the same as porting a .NET Framework Windows Forms app project, except for a few settings. また、実行可能ファイルにコンパイルするのではなく、ライブラリにコンパイルします。And instead of compiling to an executable, you compile to a library. 実行可能プロジェクトとライブラリ プロジェクト間の違いは、ソース コードを含むファイルの glob パス以外はごくわずかです。The difference between the executable project and the library project, besides paths for the file globs that include your source code, is minimal.

前の手順の例を使用して、作業するプロジェクトとファイルを展開しましょう。Using the previous step's example, lets expand what projects and files we're working with.

ファイルFile 説明Description
MyApps.slnMyApps.sln ソリューション ファイルの名前。The name of the solution file.
MyControls.csprojMyControls.csproj 移植する .NET Framework Windows Forms 制御プロジェクトの名前。The name of the .NET Framework Windows Forms Controls project to port.
MyControlsCore.csprojMyControlsCore.csproj 作成する新しい .NET Core ライブラリ プロジェクトの名前。The name of the new .NET Core library project you create.
MyCoreControls.dllMyCoreControls.dll .NET Core Windows Forms 制御ライブラリ。The .NET Core Windows Forms Controls library.
SolutionFolder
├───MyApps.sln
├───MyFormsApp
│   └───MyForms.csproj
├───MyFormsAppCore
│   └───MyFormsCore.csproj
│
├───MyFormsControls
│   └───MyControls.csproj
└───MyFormsControlsCore
    └───MyControlsCore.csproj   <--- New project for core controls

MyControlsCore.csproj プロジェクトと前に作成した MyFormsCore.csproj プロジェクト間の違いを考えてみてください。Consider the differences between the MyControlsCore.csproj project and the previously created MyFormsCore.csproj project.

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

   <PropertyGroup>
-    <OutputType>WinExe</OutputType>
     <TargetFramework>netcoreapp3.0</TargetFramework>
     <UseWindowsForms>true</UseWindowsForms>

     <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
-    <AssemblyName>MyCoreApp</AssemblyName>
-    <RootNamespace>WindowsFormsApp1</RootNamespace>
+    <AssemblyName>MyControlsCore</AssemblyName>
+    <RootNamespace>WindowsFormsControlLibrary1</RootNamespace>
   </PropertyGroup>

   <ItemGroup>
-    <Compile Include="..\MyFormsApp\**\*.cs" />
-    <EmbeddedResource Include="..\MyFormsApp\**\*.resx" />
+    <Compile Include="..\MyFormsControls\**\*.cs" />
+    <EmbeddedResource Include="..\MyFormsControls\**\*.resx" />
   </ItemGroup>

 </Project>

.NET Core Windows Forms 制御ライブラリ プロジェクト ファイルの例を次に示します。Here is an example of what the .NET Core Windows Forms Controls library project file would look like:

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

  <PropertyGroup>

    <TargetFramework>netcoreapp3.0</TargetFramework>
    <UseWindowsForms>true</UseWindowsForms>

    <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
    <AssemblyName>MyCoreControls</AssemblyName>
    <RootNamespace>WindowsFormsControlLibrary1</RootNamespace>
  </PropertyGroup>

  <ItemGroup>
    <Compile Include="..\MyFormsControls\**\*.cs" />
    <EmbeddedResource Include="..\MyFormsControls\**\*.resx" />
  </ItemGroup>

</Project>

ご覧のとおり、<OutputType> ノードが削除され、コンパイラでは、実行可能ファイルではなくライブラリが既定で生成されます。As you can see, the <OutputType> node was removed, which defaults the compiler to produce a library instead of an executable. <AssemblyName><RootNamespace> が変更されました。The <AssemblyName> and <RootNamespace> were changed. 具体的には、<RootNamespace> が、移植する Windows Forms 制御ライブラリの名前空間と一致するようになりました。Specifically the <RootNamespace> should match the namespace of the Windows Forms Controls library you are porting. 最後に、<Compile><EmbeddedResource> ノードが、移植する Windows Forms 制御ライブラリのフォルダーを指すように調整されました。And finally, the <Compile> and <EmbeddedResource> nodes were adjusted to point to the folder of the Windows Forms Controls library you are porting.

次に、メインの .NET Core MyFormsCore.csproj プロジェクトに、新しい .NET Core Windows Forms 制御ライブラリへの参照を追加します。Next, in the main .NET Core MyFormsCore.csproj project add reference to the new .NET Core Windows Forms Control library. SolutionFolder ディレクトリから、Visual Studio または .NET Core CLI のいずれかを使用して、参照を追加します。Add a reference with either Visual Studio or the .NET Core CLI from the SolutionFolder directory:

dotnet add .\MyFormsAppCore\MyFormsCore.csproj reference .\MyFormsControlsCore\MyControlsCore.csproj

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

  <ItemGroup>
    <ProjectReference Include="..\MyFormsControlsCore\MyControlsCore.csproj" />
  </ItemGroup>

コンパイルの問題Compilation problems

プロジェクトのコンパイルで問題が発生した場合は、.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 .\MyFormsAppCore\MyFormsCore.csproj package Microsoft.Windows.Compatibility

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

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

Windows フォーム デザイナーWindows Forms Designer

この記事で説明したように、Visual Studio 2019 では、.NET Framework プロジェクトでのみフォーム デザイナーがサポートされます。As detailed in this article, Visual Studio 2019 only supports the Forms 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 で Windows Forms デザイナーがサポートされるようになったら、.NET Core プロジェクト ファイルの内容を .NET Framework プロジェクト ファイルにコピーして貼り付けることができます。Once Visual Studio 2019 supports the Windows Forms 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