Visual Studioでファイルの「ビルドアクション」って何なの？

#はじめに
追記：[こちら](http://www.kanazawa-net.ne.jp/~pmansato/wpf/wpf_resource.htm)がとても詳しいことがわかりました。

僕が書いた記事はもしかしたら役に立つかもしれません( ;∀;)



Visual Studioでアプリケーションを作成するときに、アプリケーションにテキストファイルや画像ファイルなどいろいろなファイルを追加することがあります。
この時、それらのファイルのプロパティから`ビルドアクション`というものを指定することができます。

![clipboard_20181012193953.png](https://qiita-image-store.s3.amazonaws.com/0/245438/16651eed-4f57-fd1b-7668-5d3546eea9dc.png)

[こちら](https://qiita.com/shuhey/items/646f285d3a2d9705c98e)で書いたように、追加したファイルにアクセスしたい場合にこの`ビルドアクション`を`コンテンツ`にしたり`埋め込みリソース`にしたりします。

しかし、このビルドアクションの選択肢はこれだけではなく、以下のとおり沢山あります。

* なし
* コンパイル
* コンテンツ
* 埋め込みリソース
* AdditionalFiles
* CodeAnalysisDictionary
* ApplicationDefinition
* Page
* Resource
* SplashScreen
* DesignData
* DesignDataWithDesignTimeCreatableTypes
* EntityDeploy
* XamlAppDef

特に`埋め込みリソース`と`Resource`の違いがわかりません。

#ググってみました
すると[こちら](https://stackoverflow.com/questions/145752/what-are-the-various-build-action-settings-in-visual-studio-project-properties)に同じ疑問を抱く方がいまして、その疑問に対して回答している方がいました。

それによると。

* **なし**：このファイルはプロジェクトのアウトプットグループに含まれず、また、ビルドプロセスにおいてコンパイルもされません。ReadMeファイルのようなテキストファイルがそれにあたります。
* **コンパイル**：このファイルはビルドによる出力に含まれます。この設定はコードファイルに使われます。
* **埋め込みリソース**：ファイルをアセンブリ・マニフェスト・リソースの中に埋め込みます。
* **Resource**：WPFのみ。`AppName.g.resources`という名前の共有アセンブリ・マニフェスト・リソース内に埋め込まれる。
* **Page**：WPFのみ。`xaml`ファイルを`baml`にコンパイルするために使われる。`baml`とは`Resource`と同じ方法で埋め込まれる（例：`AppName.g.resources`）。
* **ApplicationDefinition**：WPFのみ。あなたのアプリケーションを定義する`XAML/class`ファイルを表します。`x:Class="Namespace.ClassName"`でコードビハインドを特定し、`StartupUri=”Window1.xaml”`でエントリポイントとなるFormやPageを設定します。
* **SplashScreen**：WPFのみ。`SplashScreen`と指定された画像は、WPFアプリケーションがロードされるときに自動的に表示され、（ロードが終わると）消えます。
* **DesignData**：Visual Studio上でユーザーコントロールがサンプルデータとともにプレビューできるようにXAMLビューモデルをコンパイルします。（モックの型を使用）
* **DesignDataWithDesignTimeCreatableTypes**：Visual Studio上でユーザーコントロールがサンプルデータとともにプレビューできるようにXAMLをコンパイルします。（実際の型を使用）https://blogs.msdn.microsoft.com/mcsuksoldev/2010/08/27/designdata-mvvm-support-in-blend-vs2010-and-wpfsilverlight/
* **EntityDeploy**：エンティティ・フレームワーク。エンティティ・フレームワークのアーティファクトをデプロイするために使用される。https://msdn.microsoft.com/en-us/library/microsoft.data.entity.build.tasks.entitydeploy.aspx?f=255&MSPPError=-2147217396
* **CodeAnalysisDictionary**：カスタム・ワード・ディクショナリを含むXMLファイル。https://blogs.msdn.microsoft.com/codeanalysis/2007/08/20/new-for-visual-studio-2008-custom-dictionaries/

はい、だんだん翻訳が怪しくなっていきました。
率直に申し上げて、`DesignData`から下がさっぱりわかりませんでした。


#でも、わかったこともあります
一番わかりやすいのは`SplashScreen`ですね。
このビルドアクションを選択した画像ファイルは、アプリケーションの起動時にスプラッシュスクリーンとして表示されます。

`コンパイル`がついているファイルは文字通りコンパイルされます。
`.cs`がついたクラスファイルがそれにあたります。
例えば`MainWindow.xaml.cs`のプロパティをみてみると、`ビルドアクション`が`コンパイル`になっていることがわかります。
![clipboard_20181013210348.png](https://qiita-image-store.s3.amazonaws.com/0/245438/f18e69a7-ebcd-5435-53b9-9f4194382cde.png)
そして、コンパイルされたくないもの、する必要がなくなったものは`なし`を選択するということですね。

`埋め込みリソース`を指定すると、そのファイルがリソースとしてアセンブリに埋め込まれ、実行時にアクセスすることができます。おそらくですが、exeやdllの中にバイナリとして埋め込まれるので、ファイルとしてユーザーの目に触れることはないでしょう。

`Resource`は例えばテキストファイルを追加したとき、そのビルドアクションがデフォルトでResourceになっています。説明によればAppName.g.resourcesファイルの中に埋め込まれるとのことですが、このファイルがどこにあるかというと、以下のフォルダの中にあります。

```
ソリューションフォルダ\ソリューション名\obj\debug\ソリューション名.g.resources
```
このファイルはバイナリファイルなので、Resourceと設定されたファイルがバイナリデータとしてここに埋め込まれているということかなと。
となれば実行時に埋め込まれたファイルにアクセスする方法もきっとあるはずです。

`Page`となっているのはMainWindow.xamlなどのXAMLファイルですね。


さて、リンク先には`コンテンツ`に触れられていなかったので、僕なりの理解を書きますと、`コンテンツ`に設定されたファイルは`埋め込みリソース`や`Resource`と違って、アセンブリに含まれません。じゃあどうなるかというと、インストール時にファイルがインストール先のフォルダに配置されます。
ですので、インストール先のフォルダからそのファイルまでのパスをたどれば、通常のファイルアクセスのやり方で読み書きができます。


#おわりに
今までビルドアクションがなんだかわからないまま何となくアプリを作ってきましたが、こうして自分なりに調べてみると、自分にとって必要な項目がわかってきて、もやもやが解消されました。

Visual Studioで開発を行っている場合、ほとんどの場合、Visual Studioがデフォルトで設定してくれるビルドアクションで問題ないと思います。

ファイルを追加した場合のみ、それをバイナリとしてアセンブリに含めるか（埋め込みリソース、Resource）、インストール先のフォルダにそのまま配置するか（コンテンツ）で設定を適宜変更する機会があるかと思います。
この3つのビルドアクションはそれぞれファイルへのアクセスの仕方が異なるのでそれについては、順次投稿していきます。


#追記
ビルドアクションを`Resource`にしたときのファイルへのアクセス方法について書きました。[こちら](https://qiita.com/shuhey/items/94d252f802df49b0c37e)。