.NET プロジェクト SDK
.NET Core および .NET 5 以降のプロジェクトは、ソフトウェア開発キット (SDK) に関連付けられています。 各 "プロジェクト SDK" は、MSBuild ターゲットと、コードのコンパイル、パッキング、発行を行う関連するタスクのセットです。 プロジェクト SDK を参照するプロジェクトは、"SDK スタイルのプロジェクト" と呼ばれることもあります。
使用可能な SDK
次の SDK を利用できます。
ID | 説明 | リポジトリ |
---|---|---|
Microsoft.NET.Sdk |
.NET SDK | https://github.com/dotnet/sdk |
Microsoft.NET.Sdk.Web |
.NET Web SDK | https://github.com/dotnet/sdk |
Microsoft.NET.Sdk.BlazorWebAssembly |
.NET Blazor WebAssembly SDK | https://github.com/dotnet/aspnetcore |
Microsoft.NET.Sdk.Razor |
.NET Razor SDK | https://github.com/dotnet/aspnetcore |
Microsoft.NET.Sdk.Worker |
.NET Worker Service SDK | |
Microsoft.NET.Sdk.WindowsDesktop |
.NET デスクトップ SDK。これには Windows フォーム (WinForms) と Windows Presentation Foundation (WPF) が含まれています。* | https://github.com/dotnet/winforms および https://github.com/dotnet/wpf |
.NET SDK は、.NET の基本 SDK です。 その他の SDK からは .NET SDK が参照され、その他の SDK に関連付けられているプロジェクトでは、すべての .NET SDK プロパティが使用可能になります。 たとえば、Web SDK は、.NET SDK と Razor SDK の両方に依存しています。
NuGet を使用して配布できる独自の SDK を作成することもできます。
* .NET 5 以降、Windows フォームおよび Windows Presentation Foundation (WPF) プロジェクトでは、Microsoft.NET.Sdk.WindowsDesktop
ではなく .NET SDK (Microsoft.NET.Sdk
) を指定する必要があります。 これらのプロジェクトでは、TargetFramework
を net5.0-windows
に、UseWPF
または UseWindowsForms
を true
に設定することで、Windows デスクトップ SDK が自動的にインポートされます。 プロジェクトで .NET 5 以降をターゲットとし、Microsoft.NET.Sdk.WindowsDesktop
SDK を指定すると、ビルド警告 NETSDK1137 が表示されます。
プロジェクト ファイル
.NET プロジェクトは、MSBuild 形式に基づいています。 プロジェクト ファイルは、C# プロジェクトでは .csproj、F# プロジェクトでは .fsproj のような拡張子が付いていて、XML 形式です。 MSBuild プロジェクト ファイルのルート要素は、Project 要素です。 Project
要素には、使用する SDK (およびバージョン) を指定する省略可能な Sdk
属性があります。 .NET ツールを使用してコードをビルドするには、Sdk
属性を、「使用可能な SDK」の表にあるいずれかの ID に設定します。
<Project Sdk="Microsoft.NET.Sdk">
...
</Project>
NuGet から取得した SDK を指定するには、名前の末尾にバージョンを含めるか、global.json ファイルに名前とバージョンを指定します。
<Project Sdk="MSBuild.Sdk.Extras/2.0.54">
...
</Project>
SDK を指定する別の方法として、トップレベルの SDK 要素を使用する方法があります。
<Project>
<Sdk Name="Microsoft.NET.Sdk" />
...
</Project>
これらの方法のいずれかで SDK を参照すると、.NET のプロジェクト ファイルが大幅に簡素化されます。 プロジェクトの評価中に、MSBuild によってプロジェクト ファイルの先頭に Sdk.props
の暗黙的なインポートと、末尾に Sdk.targets
の暗黙的なインポートが追加されます。
<Project>
<!-- Implicit top import -->
<Import Project="Sdk.props" Sdk="Microsoft.NET.Sdk" />
...
<!-- Implicit bottom import -->
<Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk" />
</Project>
ヒント
Windows コンピューターでは、Sdk.props ファイルと Sdk.targets ファイルは %ProgramFiles%\dotnet\sdk\[バージョン]\Sdks\Microsoft.NET.Sdk\Sdk フォルダーにあります。
プロジェクト ファイルの前処理
MSBuild では、dotnet msbuild -preprocess
コマンドを使用して、SDK とそのターゲットが取り込まれた後の完全に展開されたプロジェクトがどのようになるかを確認できます。 dotnet msbuild
コマンドの preprocess スイッチによって、インポートされるファイル、そのソース、ビルドに対するそのコントリビューションが、実際にプロジェクトをビルドすることなく、表示されます。
プロジェクトにターゲット フレームワークが複数存在する場合は、1 つのフレームワークだけにコマンドの結果を集中させてください。そのためには、そのフレームワークを MSBuild プロパティとして指定します。 次に例を示します。
dotnet msbuild -property:TargetFramework=netcoreapp2.0 -preprocess:output.xml
既定で含まれるものと除外されるもの
Compile
項目、埋め込みリソース、None
項目に既定で含まれるものと除外されるものが SDK で定義されています。 SDK 以外の .NET Framework プロジェクトとは異なり、既定値がほとんどの一般的なユース ケースに対応しているため、これらの項目をプロジェクト ファイルで指定する必要はありません。 この動作により、プロジェクト ファイルのサイズがより小さく、より簡単に理解できるようになり、必要に応じて手作業で編集できます。
次の表は、.NET SDK に組み込まれる、および除外される要素と glob の一覧を示します。
要素 | 含まれる glob | 除外される glob | glob の削除 |
---|---|---|---|
Compile | **/*.cs (または他の言語拡張機能) | **/*.user; **/*.*proj; **/*.sln; **/*.vssscc | 該当なし |
EmbeddedResource | **/*.resx | **/*.user; **/*.*proj; **/*.sln; **/*.vssscc | 該当なし |
None | **/* | **/*.user; **/*.*proj; **/*.sln; **/*.vssscc | **/*.cs; **/*.resx |
Note
./bin
フォルダーと ./obj
フォルダーは、$(BaseOutputPath)
と $(BaseIntermediateOutputPath)
の MSBuild プロパティによって表され、既定で glob から除外されます。 除外されるものは、DefaultItemExcludes プロパティによって表されます。
.NET デスクトップ SDK には、さらに多くの WPF に含まれるものと除外されるものが含まれています。 詳細については、「WPF に含まれるものと除外されるもの」を参照してください。
ビルド エラー
これらの項目をプロジェクト ファイルに明示的に定義すると、次のような "NETSDK1022" ビルド エラーが発生する可能性があります。
重複する 'Compile' 項目が含まれていました。 .NET SDK には、既定でプロジェクト ディレクトリの 'Compile' 項目が含まれています。 これらの項目をプロジェクト ファイルから削除するか、プロジェクト ファイルに明示的に含める場合は 'EnableDefaultCompileItems' プロパティを 'false' に設定することができます。
重複する 'EmbeddedResource' 項目が含まれていました。 .NET SDK には、既定でプロジェクト ディレクトリの 'EmbeddedResource' 項目が含まれています。 これらの項目をプロジェクト ファイルから削除するか、プロジェクト ファイルに明示的に含める場合は 'EnableDefaultEmbeddedResourceItems' プロパティを 'false' に設定することができます。
このエラーを解決するには、次のいずれかの操作を行います。
前の表に列挙されている暗黙的な項目と一致する明示的な
Compile
、EmbeddedResource
、またはNone
の項目を削除します。暗黙的なファイルの組み込みをすべて無効にするには、EnableDefaultItems プロパティを
false
に設定します。<PropertyGroup> <EnableDefaultItems>false</EnableDefaultItems> </PropertyGroup>
アプリで発行する一部のファイルを指定する必要がある場合は、そのために既知の MSBuild のしくみ (たとえば
Content
要素) を引き続き使用できます。Compile
、EmbeddedResource
、またはNone
glob のみを選択的に無効にするには、EnableDefaultCompileItems、EnableDefaultEmbeddedResourceItems、または EnableDefaultNoneItems のプロパティをfalse
に設定します。<PropertyGroup> <EnableDefaultCompileItems>false</EnableDefaultCompileItems> <EnableDefaultEmbeddedResourceItems>false</EnableDefaultEmbeddedResourceItems> <EnableDefaultNoneItems>false</EnableDefaultNoneItems> </PropertyGroup>
Compile
glob のみを無効にすると、Visual Studio のソリューション エクスプローラーに *.cs 項目がプロジェクトの一部として (None
項目として組み込まれて) 引き続き表示されます。 暗黙的なNone
glob を無効にするには、EnableDefaultNoneItems
もfalse
に設定します。
暗黙的な using ディレクティブ
.NET 6 以降、暗黙的な global using
ディレクティブが新しい C# プロジェクトに追加されます。 これは、完全修飾名を指定したり、using
ディレクティブを手動で追加したりしなくても、これらの名前空間で定義された型を使用できることを意味します。 暗黙的な 側面とは、プロジェクトの obj ディレクトリに生成されるファイルに global using
ディレクティブが追加されるという事実を指します。
次のいずれかの SDK を使用するプロジェクトには、暗黙的な global using
ディレクティブが追加されます。
Microsoft.NET.Sdk
Microsoft.NET.Sdk.Web
Microsoft.NET.Sdk.Worker
Microsoft.NET.Sdk.WindowsDesktop
global using
ディレクティブは、プロジェクトの SDK に基づく一連の既定の名前空間の名前空間ごとに追加されます。 これらの既定の名前空間を次の表に示します。
SDK | 既定の名前空間 |
---|---|
Microsoft.NET.Sdk | System System.Collections.Generic System.IO System.Linq System.Net.Http System.Threading System.Threading.Tasks |
Microsoft.NET.Sdk.Web | Microsoft.NET.Sdk 名前空間 System.Net.Http.Json Microsoft.AspNetCore.Builder Microsoft.AspNetCore.Hosting Microsoft.AspNetCore.Http Microsoft.AspNetCore.Routing Microsoft.Extensions.Configuration Microsoft.Extensions.DependencyInjection Microsoft.Extensions.Hosting Microsoft.Extensions.Logging |
Microsoft.NET.Sdk.Worker | Microsoft.NET.Sdk 名前空間 Microsoft.Extensions.Configuration Microsoft.Extensions.DependencyInjection Microsoft.Extensions.Hosting Microsoft.Extensions.Logging |
Microsoft.NET.Sdk.WindowsDesktop (Windows Forms) | Microsoft.NET.Sdk 名前空間 System.Drawing System.Windows.Forms |
Microsoft.NET.Sdk.WindowsDesktop (WPF) | Microsoft.NET.Sdk 名前空間 System.IO 削除済み System.Net.Http 削除済み |
この機能を無効にする場合、または既存の C# プロジェクトで暗黙的な global using
ディレクティブを有効にする場合は、ImplicitUsings
MSBuild プロパティを使用して実行できます。
必要に応じて、プロジェクト ファイルに Using
項目 (Visual Basic プロジェクトの場合は Import
項目) を追加することによって暗黙的な global using
ディレクティブを指定できます。次に例を示します。
<ItemGroup>
<Using Include="System.IO.Pipes" />
</ItemGroup>
暗黙的なパッケージ参照
.NET Core 1.0 から 2.2 または .NET Standard 1.0 から 2.0 をターゲットとする場合、.NET SDK により、特定のメタパッケージへの暗黙的な参照が追加されます。 メタパッケージは、他のパッケージの依存関係のみで構成されるフレームワーク ベースのパッケージです。 メタパッケージは、プロジェクト ファイルの TargetFramework または TargetFrameworks プロパティで指定されたターゲット フレームワークに基づいて暗黙的に参照されます。
<PropertyGroup>
<TargetFramework>netcoreapp2.1</TargetFramework>
</PropertyGroup>
<PropertyGroup>
<TargetFrameworks>netcoreapp2.1;net462</TargetFrameworks>
</PropertyGroup>
必要に応じて、DisableImplicitFrameworkReferences プロパティを使用して暗黙的なパッケージ参照を無効にし、必要なフレームワークまたはパッケージのみに明示的な参照を追加することができます。
レコメンデーション:
- .NET Framework、.NET Core 1.0 から 2.2、または .NET Standard 1.0 から 2.0 をターゲットとする場合は、プロジェクト ファイルの
<PackageReference>
アイテム経由でMicrosoft.NETCore.App
またはNETStandard.Library
メタパッケージを明示的に参照しないようにします。 .NET Core 1.0 から 2.2 および .NET Standard 1.0 から 2.0 のプロジェクトの場合、このようなメタパッケージは暗黙的に参照されます。 .NET Framework プロジェクトの場合、.NET Standard ベースの NuGet パッケージを使用する場合、何らかのバージョンのNETStandard.Library
が必要であれば、NuGet はそのバージョンを自動的にインストールします。 - .NET Core 1.0 から 2.2 をターゲットとする場合、特定バージョンのランタイムが必要であれば、メタパッケージを参照するのではなく、プロジェクト内で
<RuntimeFrameworkVersion>
プロパティを使用します (1.0.4
など)。 たとえば、自己完結の配置を使用している場合は、1.0.0 LTS ランタイムの特定のパッチ バージョンが必要になることがあります。 - .NET Standard 1.0 から 2.0 をターゲットとする場合、特定バージョンの
NETStandard.Library
メタパッケージが必要であれば、<NetStandardImplicitPackageVersion>
プロパティを使用し、必要なバージョンを設定できます。
ビルド イベント
SDK スタイルのプロジェクトでは、PreBuild
または PostBuild
という名前の MSBuild ターゲットを使用し、PreBuild
の BeforeTargets
プロパティまたは AfterTargets
の PostBuild
プロパティを設定します。
<Target Name="PreBuild" BeforeTargets="PreBuildEvent">
<Exec Command=""$(ProjectDir)PreBuildEvent.bat" "$(ProjectDir)..\" "$(ProjectDir)" "$(TargetDir)"" />
</Target>
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
<Exec Command="echo Output written to $(TargetDir)" />
</Target>
Note
- MSBuild ターゲットには任意の名前を使用できます。 ただし、
PreBuild
およびPostBuild
ターゲットは Visual Studio IDE によって認識されるため、これらの名前を使用することにより、IDE でコマンドを編集できます。 $(ProjectDir)
などのマクロが解決されないため、SDK スタイルのプロジェクトでは、プロパティPreBuildEvent
とPostBuildEvent
は推奨されません。 たとえば、次のようなコードはサポートされません。
<PropertyGroup>
<PreBuildEvent>"$(ProjectDir)PreBuildEvent.bat" "$(ProjectDir)..\" "$(ProjectDir)" "$(TargetDir)"</PreBuildEvent>
</PropertyGroup>
ビルドのカスタマイズ
ビルドをカスタマイズするには、さまざまな方法があります。 プロパティを引数として msbuild または dotnet コマンドに渡すことによって、プロパティをオーバーライドすることができます。 また、プロパティをプロジェクト ファイルに追加することや、Directory.Build.props ファイルに追加することができます。 .NET プロジェクトの便利なプロパティの一覧については、「.NET SDK プロジェクトの MSBuild リファレンス」をご覧ください。
ヒント
コマンド ラインから新しい Directory.Build.props ファイルを簡単に作成するには、リポジトリのルートにある コマンド dotnet new buildprops
を使用します。
カスタム ターゲット
.NET プロジェクトでは、プロジェクトで使用するカスタムの MSBuild ターゲットとプロパティをパッケージ化し、そのパッケージをプロジェクトで使用することができます。 この種の拡張機能を使用するのは、次の場合です。
- ビルド処理を拡張する。
- ビルド プロセスの成果物 (生成されたファイルなど) にアクセスする。
- どのような構成でビルドが呼び出されるかを検査する。
カスタムのビルド ターゲットまたはプロパティを追加するには、プロジェクトの build フォルダーに <package_id>.targets
または <package_id>.props
の形式のファイル (たとえば Contoso.Utility.UsefulStuff.targets
) を配置します。
次の XML は .csproj ファイルからのスニペットです。パッケージ化する対象を dotnet pack
コマンドに指示しています。 <ItemGroup Label="dotnet pack instructions">
要素で、パッケージ内の build フォルダーにターゲット ファイルを配置します。 <Target Name="CollectRuntimeOutputs" BeforeTargets="_GetPackageFiles">
要素で、アセンブリと .json ファイルを build フォルダーに配置します。
<Project Sdk="Microsoft.NET.Sdk">
...
<ItemGroup Label="dotnet pack instructions">
<Content Include="build\*.targets">
<Pack>true</Pack>
<PackagePath>build\</PackagePath>
</Content>
</ItemGroup>
<Target Name="CollectRuntimeOutputs" BeforeTargets="_GetPackageFiles">
<!-- Collect these items inside a target that runs after build but before packaging. -->
<ItemGroup>
<Content Include="$(OutputPath)\*.dll;$(OutputPath)\*.json">
<Pack>true</Pack>
<PackagePath>build\</PackagePath>
</Content>
</ItemGroup>
</Target>
...
</Project>
プロジェクトでカスタム ターゲットを使用するには、パッケージとそのバージョンを指す PackageReference
要素を追加します。 ツールとは異なり、カスタム ターゲットのパッケージは、それを使用するプロジェクトの依存関係クロージャに含まれます。
カスタム ターゲットの使用方法を構成できます。 それは MSBuild ターゲットであるため、指定されたターゲットに依存することや、別のターゲットの後に実行したり、dotnet msbuild -t:<target-name>
コマンドを使用して手動で呼び出したりすることができます。 ただし、優れたユーザー エクスペリエンスを提供するために、プロジェクトごとのツールとカスタム ターゲットを組み合わせることができます。 このシナリオでは、必要なすべてのパラメーターをプロジェクトごとのツールで受け取り、受け取ったパラメーターを、ターゲットを実行する必要な dotnet msbuild
の呼び出しに変換します。 このような相乗効果のサンプルは、dotnet-packer
プロジェクトの「MVP Summit 2016 Hackathon samples」 (MVP Summit 2016 ハッカソンのサンプル) レポートで参照することができます。
関連項目
.NET
フィードバック
https://aka.ms/ContentUserFeedback」を参照してください。
以下は間もなく提供いたします。2024 年を通じて、コンテンツのフィードバック メカニズムとして GitHub の issue を段階的に廃止し、新しいフィードバック システムに置き換えます。 詳細については、「フィードバックの送信と表示