6
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

C#Advent Calendar 2024

Day 18

.NETのテンプレートを比較してみる

Last updated at Posted at 2024-12-17

この記事はC# Advent Calendar 2024(シリーズ2)の18日目の記事です。

別のアドベントカレンダーでこちらの記事を書いていたら、もう少し深追いしてみたい項目が出てきたのでC#アドベントカレンダーにエントリーしてもう一記事書くことにしました。

本記事の目的

前述の記事にて、「コンソールアプリケーション」のテンプレートで作成したプロジェクトではSystem.Windows.Formsが参照されておらず使用できないことを書きました。何が違うのか調べてみると、以下のような違いがあります。(この画像は前述の記事にも載せているものです)
image.png
この違いはどこから生まれてくるのか確認してみたいと思います。

比較してみる

作成後無編集の状態で「Windowsフォームアプリケーション」と「コンソールアプリケーション」を比較してみました。
Visual Studio 2022の以下のテンプレートを選択して作成したものです。
image.png
比較しやすいようにソリューション名・プロジェクト名を同じにしておいてWinMergeで比較してみました。
image.png
それぞれの違いを見ていきましょう。

.sln

image.png
これは固有のIDのようなものが違うだけで、本質的な違いはないですね。

Program.cs

image.png
これは違って当然ですね。
テンプレートには初期状態では以下のコードが書かれます。

  • Windowsフォームアプリケーション
    →初期フォームを表示するためのコード
  • コンソールアプリケーション
    →サンプルコードとしてHello World

C#では9.0よりトップレベルステートメントが書けるようになりましたが、テンプレートではコンソールアプリのみとなっているようです。

.csproj

image.png
予想通りですが、違いはここになります。以下のような違いがありました。

Windowsフォーム コンソール
OutputType WinExe Exe
TargetFramework net8.0-windows net8.0
UseWindowsForms true 記載なし

今回の検証目的であるSystem.Windows.Formsはどうやって参照されているのかにはUseWindowsFormsが関係ありそうに見えますが、他の項目もWindowsのプログラムを作ることに関係ある値に見えるのでこちらも一体で関係あるようにも見えます。

確認してみる

コンソールアプリのcsprojを編集して、それぞれの項目の意味を確認してみます。
まずは他の項目はそのままに、ダイレクトに関係しそうな項目名に見えるUseWindowsFormsだけを追加してみました。

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

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net8.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
    <UseWindowsForms>true</UseWindowsForms> <!-- 追加 -->
  </PropertyGroup>

</Project>

この状態だとコンパイルエラーになりました。エラー内容は以下です。

Windows フォームまたは WPF を使用しているとき、またはそのようなプロジェクトまたはパッケージを参照しているときには、ターゲット プラットフォームを Windows に設定する必要があります (通常は TargetFramework プロパティに '-windows' を含めることによる)。

エラー内容に記載のとおりTargetFrameworkをnet8.0-windowsに変更してみます。

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

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net8.0-windows</TargetFramework> <!-- 変更 -->
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
    <UseWindowsForms>true</UseWindowsForms> <!-- 追加 -->
  </PropertyGroup>

</Project>

コンパイルが通りました。また、検証目的であったSystem.Windows.Formsの参照も追加されていました。
image.png
この状態で実行するとコンソールが表示されます。WinFormsアプリではコンソールは表示されませんから、やはりまだ違う状態であることがわかります。
image.png
では最後に、OutputTypeをWinExeに変更してみます。これで、結局Widowsフォームアプリケーションのテンプレートから作成したのと同じ状態になりました。

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

  <PropertyGroup>
    <OutputType>WinExe</OutputType> <!-- 変更 -->
    <TargetFramework>net8.0-windows</TargetFramework> <!-- 変更 -->
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
    <UseWindowsForms>true</UseWindowsForms> <!-- 追加 -->
  </PropertyGroup>

</Project>

この状態で実行するとコンソールが表示されなくなりました。
当たり前と言えば当たり前ですがcsprojの相違点三点全てがそろわないとWinFormsアプリにならないということがわかりました。

公式ドキュメントより

ここまで実際にcsprojを編集して確認しましたが、Microsfotの公式ドキュメントを調べてみます。

TargetFramework

プラットフォーム固有のライブラリの場合、プラットフォーム固有のフレーバーをターゲットにする必要があります。 たとえば、WinForms プロジェクトと WPF プロジェクトは net9.0-windows をターゲットにする必要があります。

OutputType

OutputType は、Windows Presentation Foundation (WPF) アプリと Windows フォーム アプリでは、自動的に WinExe に設定されます。 OutputType が WinExe に設定されている場合、アプリの実行時にコンソール ウィンドウは開きません。

UseWindowsForms

WinForms をインポートして使用する場合は、UseWindowsForms を true に設定する。

ということで、キーワードがわかってから調べてみるとちゃんとドキュメントに記載されていることがわかりました。

6
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?