.NET プロジェクト SDK

最新の .NET プロジェクトは、ソフトウェア開発キット (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

.NET SDK は、.NET の基本 SDK です。 その他の SDK からは .NET SDK が参照され、その他の SDK に関連付けられているプロジェクトでは、すべての .NET SDK プロパティが使用可能になります。 たとえば、Web SDK は、.NET SDK と Razor SDK の両方に依存しています。

NuGet を使用して配布できる独自の SDK を作成することもできます。

Windows フォームおよび Windows Presentation Foundation (WPF) プロジェクトの場合、.NET SDK (Microsoft.NET.Sdk) を指定し、プロジェクト ファイルでいくつかの追加プロパティを設定します。 詳細については、「.NET デスクトップ SDK を有効にする」を参照してください。

プロジェクト ファイル

.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 を指定するもう 1 つの方法として、トップレベルの 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=net8.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 ビルド エラーが発生する可能性があります。 このエラーを解決する方法については、「NETSDK1022: 重複する項目が含まれていました」を参照してください。

暗黙的な 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 Standard 1.0 から 2.0 をターゲットとする場合、.NET SDK により、特定の "メタパッケージ" への暗黙的な参照が追加されます。 メタパッケージは、他のパッケージの依存関係のみで構成されるフレームワーク ベースのパッケージです。 メタパッケージは、プロジェクト ファイルの TargetFramework または TargetFrameworks (plural) プロパティで指定されたターゲット フレームワークに基づいて暗黙的に参照されます。

<PropertyGroup>
  <TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<PropertyGroup>
  <TargetFrameworks>netstandard2.0;net462</TargetFrameworks>
</PropertyGroup>

必要に応じて、DisableImplicitFrameworkReferences プロパティを使用して暗黙的なパッケージ参照を無効にし、必要なフレームワークまたはパッケージのみに明示的な参照を追加することができます。

レコメンデーション:

  • .NET Framework または .NET Standard 1.0 から 2.0 をターゲットとする場合は、プロジェクト ファイルの <PackageReference> 項目を使用して NETStandard.Library メタパッケージへの明示的な参照を追加しないでください。 .NET Standard 1.0 から 2.0 プロジェクトの場合、これらのメタパッケージは暗黙的に参照されます。 .NET Framework プロジェクトの場合、.NET Standard ベースの NuGet パッケージを使用する場合、何らかのバージョンの NETStandard.Library が必要であれば、NuGet はそのバージョンを自動的にインストールします。
  • .NET Standard 1.0 から 2.0 をターゲットとする場合に、特定バージョンの NETStandard.Library メタパッケージが必要であれば、<NetStandardImplicitPackageVersion> プロパティを使用し、必要なバージョンを設定できます。

ビルド イベント

SDK スタイルのプロジェクトでは、PreBuild または PostBuild という名前の MSBuild ターゲットを使用し、PreBuildBeforeTargets プロパティまたは AfterTargetsPostBuild プロパティを設定します。

<Target Name="PreBuild" BeforeTargets="PreBuildEvent">
    <Exec Command="&quot;$(ProjectDir)PreBuildEvent.bat&quot; &quot;$(ProjectDir)..\&quot; &quot;$(ProjectDir)&quot; &quot;$(TargetDir)&quot;" />
</Target>

<Target Name="PostBuild" AfterTargets="PostBuildEvent">
   <Exec Command="echo Output written to $(TargetDir)" />
</Target>

Note

  • MSBuild ターゲットには任意の名前を使用できます。 ただし、PreBuild および PostBuild ターゲットは Visual Studio IDE によって認識されるため、これらの名前を使用することにより、IDE でコマンドを編集できます。
  • $(ProjectDir) などのマクロが解決されないため、SDK スタイルのプロジェクトでは、プロパティ PreBuildEventPostBuildEvent は推奨されません。 たとえば、次のようなコードはサポートされません。
<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 ハッカソンのサンプル) レポートで参照することができます。

関連項目