C# 入門講座
Visual Studio 2005 Visual Studio 2008 Visual Studio 2010 Visual Studio 2012 Visual Studio 2013 Visual Studio 2015 Visual Studio 2017 Visual Studio 2019 Visual Studio 2022

第7回 ビルド

2022/1/16

この記事が対象とする製品・バージョン。環境が2017以前の場合はこの記事の過去の版も参考にしてください。

Visual Studio 2022 Visual Studio 2022 対象です。
VS2019 Visual Studio 2019 対象です。
VS2017 Visual Studio 2017 対象ですが少し説明と違う場合があります。
VS2015 Visual Studio 2015 対象ですが少し説明と違う場合があります。
VS2013 Visual Studio 2013 対象ですが少し説明と違う場合があります。
VS2012 Visual Studio 2012 対象ですがそこそこ説明が違う場合があります。
VS2010 Visual Studio 2010 対象ですがそこそこ説明が違う場合があります。
VS2008 Visual Studio 2008 対象ですがそこそこ説明が違う場合があります。
VS2005 Visual Studio 2005 対象ですがそこそこ説明が違う場合があります。
VS.NET 2003 Visual Studio 2003 対象外ですがほとんどの操作は同じなので参考になります。
VS.NET 2002 Visual Studio (2002) 対象外ですがほとんどの操作は同じなので参考になります。

 

目次

 

1.プロジェクトを構成するファイル

1-1.プロジェクトを構成するファイル

C#のプロジェクトはかなりシンプルなものでも複数のファイルから成り立っています。

下の画像は初期状態のWindowsフォームアプリのソリューションエクスプローラーです。

初期状態のプロジェクトはVisual Studioのバージョンや環境・設定によっても異なりますが、おおむね同じです。ここではVisual Studio 2022 + .NET 6 を例に説明します。

ソリューションエクスプローラーには下記の5個の項目が表示されています。

これらはファイルに似た単位ですが、ファイル自体を表しているわけではありません。

「ソリューション 'WinFormsApp1' (1/1 プロジェクト)」などを右クリックして、「エクスプローラーでフォルダーを開く」を選択すると、フォルダーが開いて実際のファイルを確認することができます。

 

ソリューションやプロジェクトを構成するファイル/フォルダーの中には隠しファイル/隠しフォルダーになっているものもあり、エクスプローラーの設定によってはそれらは表示されません。

 

デフォルトの設定の場合の主だったファイルとフォルダーについて簡単に説明しておきます。

まず、ソリューションを作成した時点で、ソリューションを同じ名前のフォルダーが1つ作成され、すべてのファイルはその中に作成されます。上の画像ではトップレベルにあるフォルダー「WinFormsApp1」がそれです。

このフォルダーの中には、ソリューション情報を管理するWinFormsApp1.slnというファイルが作成されます。このファイルの名前もソリューションの名前も同じになります。このファイルにはたいした情報はありません。プログラムで重要なのはソリューションではなくプロジェクトです。

ソリューションのフォルダーの中にはもう1つプロジェクト名と同じ名前のフォルダーがあります。上の画像では WinFormsApp1です。デフォルトではソリューションの名前とプロジェクトの名前が同じなので同じ名前のフォルダーになります。

プロジェクトのフォルダーの中にはプロジェクトの情報を持っているWinFormsApp1.csprojファイルがあります。このことは入門講座第1回でも説明しています。.slnファイルか.csprojファイルのどちらかをダブルクリックするとVisual Studioが開いてWindowsFormsApp1プロジェクトが編集可能な状態になります。

Form1.csはみなさんがプログラムしているフォームのプログラムです。このファイルをメモ帳で開いてプログラムの内容を確認することもできます。

Form1.Designer.cs (読み方:フォームイチ ドット デザイナー ドット シーエス)はVisual Studioが自動生成しているプログラムで、ここには興味深い内容が記述されています。少し詳しく見てみましょう。

 

1-2.Form1.Designer.cs

フォームにボタンやテキストボックスをぺたぺた貼り付けていろいろとプロパティを変更すると、このForm1.Designer.csにその操作の結果がプログラムとして記録されます。

ですので、プロパティを使ったプログラム方法がわからない場合、実際にプロパティウィンドウで対象のプロパティを変更してみてから、Form1.Designer.csの中を確認するとどのようなプログラムでそれが実現できるのか確認することができます。

少し試してみましょう。

フォームにボタンを1つ貼り付けてから、プロパティウィンドウを使ってFontプロパティを何か変更してみてください。たとえば、フォントを「メイリオ」にして、大きさを18ポイントにしてみます。

プロパティウィンドウでFontプロパティを変更したところ

次にソリューションエクスプローラーでForm1.Designer.csをダブルクリックしてソースコードを確認してみてください。

既定のソリューションエクスプローラーでは Form1.cs の左にある矢印を展開するとForm1.Designer.csが表示されます。

このあたりの操作はバージョンによって少し違うかもしれません。この後の説明も細かい差異があるかもしれませんがこの仕組み自体ははじめのC#からずっと変わっていないのでここで説明する内容は当てはまるはずです。

Form1.Designer.csを表示する

■この画像はVisual Studio 2019のものです

Form1.Designer.csの中にははじめから何十行かプログラムがあります。「その中に Windows フォーム デザイナーで生成されたコード」(Windows Form Designer generated code)と書いてある部分があるので、その左の + をクリックして展開してみてください。

Windows フォーム デザイナーで生成されたコード

■この画像はVisual Studio 2019のものです。(2022年1月時点ではVisual Studio 2022では英語表記になっていました。)

展開して出現したプログラムの中をbutton1とFontを手がかりにざっと見てみると、すぐにFontを設定している箇所が見つかると思います。


this.button1.Font = new System.Drawing.Font("メイリオ", 18F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);

生成されるプログラムはバージョンによって少し違うようです。この例はVisual Studio 2022が生成したものです。

プログラムの意味は良くわからないかもしれませんが、これをコピーしてあなたのプログラムに貼り付ければプログラムの中でフォントを変更することができます。

なお、このForm1.Designer.csは中を見るのはかまいませんが変更は絶対にしないでください。ここを変更するとVisual Studioはフォームをうまく認識できなくなって、デザイナーが機能しなくなる場合があります。

 

1-3.objフォルダーとbinフォルダー

objフォルダーとbinフォルダーには、プログラムを開始するときに、自動的にファイルが生成されます。この2つのフォルダーは削除してもプログラムを開始すると再度自動生成されます。

プログラムを開始する流れは重要なので章を改めて説明します。

 

2.ビルド

C#でプログラムしたプログラムはほとんどの場合、実行するときに拡張子が .dll のファイルになります。(拡張子が .cs のファイルが直接実行されることは一切ありません。が、表示上その方がわかりやすいので、Visual Studioで操作しているときはVisual Studioはそのように見せかけます。)

名前は既定ではプロジェクトと同じ名前になるのでたとえば、WinFormsApp1.dll というファイルになります。

Windows上でプログラムを実行するには拡張子が .exe のファイルもあった方が良いので、Windowsフォームアプリの場合、Visual Studioは拡張子 .exe のファイルも作り出します。.exeのファイルはOS(Windows/Mac/Linux)の差異を吸収するための技術的な仕掛けの一部であり、このファイルにみなさんのプログラムが格納されているわけではありません。みなさんのプログラムが格納されているのは拡張子 .dll ファイルの方です。

 

 

C#などのプログラムからコンピューターで実行可能なファイルなど(この場合はdllファイルとexeファイルなど)を作成することをビルドと呼びます。

普段、Visual Studioでプログラムを実行をすると、自動的にビルドが行われています。[ビルド]メニューの[ソリューションのビルド]か[WinFormsApp1のビルド](WinFormsApp1の部分はプロジェクト名によって変わります)をクリックすると、プログラムを開始しないでビルドだけ行うこともできます。

ビルドは複雑な処理なので、いきなり実行可能な形式のファイル(dllやexeファイルなど)を作成することはできず、中間段階でいくつかのファイルを作成します。中間段階のファイルは最終的には不要なのでビルド完了後には削除してもかまいません。objフォルダーはこのような中間段階でできるものが格納されます。

ビルドのやり方にはいろいろあり、オプションや設定で細かく制御できます。

既定では、ビルドのやり方が2つ用意されており、ほとんどの場合、この既定のビルドの設定のどちらかを使います。このビルドの設定のことを「ビルドの構成」や「プロジェクトの構成」と呼びます。

既定で用意されているビルド構成の1つは開発用のビルド構成で、Debug(デバッグ)と呼びます。Debugがデフォルトのビルド構成なので、特に意識していない場合Debugでビルドされています。もう1つは完成版用の構成でRelease(リリース)と呼びます。Debugでビルドしたほうが開発者用の便利機能がいろいろと使用できますので普段はDebugでビルドするようにしてください。Releaseでビルドすると開発者用の便利機能の多くが使えなくなる代わりに実行に不要な開発向けの情報が削除され、速度の向上やファイルサイズの削減が期待できます。Releaseでビルドしてしまうとこの入門講座や初級講座で解説しているいろいろな機能が使えない場合がありますので、人に渡したり世の中に配ったりするのでなければDebugビルドを使用してください。

DebugとReleaseはここで切り替えます。

DebugビルドとReleaseビルドの切り替え

Visual Studioのバージョンによって少し位置や表示が違うかもしれませんが大体同じです。

それでは、何かプログラムを実行してみてください。今はビルドが目的なので実行を開始したらすぐに終了させてください。実行するだけでビルドも行われます。

 

ビルドで生成された結果を確認してみましょう。

結果は binフォルダーの中に作成されます。binフォルダーの下にはビルド構成のフォルダーがあります。先ほど説明したように既定では2つのデバッグ構成がありますからDebugフォルダーとReleaseフォルダーがあるはずです。(一度もビルドしていない構成のフォルダーは存在しない場合もあるかもしれません。)

今回はDebugビルドで実行したので、Debugフォルダーの中を除いてみましょう。

Debugフォルダーの中には対象の環境の名前のフォルダーが作成されています。たとえば、フレームワークが .NET 6 で Windows を対象にしている場合、net6.0-windows というフォルダーが作成されています。このフォルダーの中を見ると、ビルドの結果作成されたファイルが確認できます。

たとえば、次のようになっています。

ファイル名はデフォルトではプロジェクト名になるので、プロジェクト名を変更している場合はこれとは異なるファイルになります。ここではプロジェクト名がWinFormsApp1という前提で説明します。また以前使われていた.NET Frameworkの場合はもう少しファイル数が少ないです。

WinFormsApp1.dllはあなたが作成したプログラムそのものです。もし、技術力があればこのファイルから、元のプログラムがどのようなものだったかかなりの精度で復元することもできます。(ILSpyというアプリを使うと簡単にできます。)

WinFormsApp1.exeはWindows上でWinFormsApp1.dllを実行するための仕掛けでです。このexeファイルをダブルクリックすることで Visual Studioがなくてもアプリを実行することができます。

WinFormsApp1.pdbは開発者用の情報が入ったファイルです。普通は直接使用することはないので無視してください。このファイルに格納されている情報にはプログラムで使用しているファイルのパスも埋め込まれています。そのため基になったプログラム(.csファイルなど)を保存しているフォルダー名にあなたの名前や学校名を含んでいる場合などはこのpdbファイルの中にあなたの名前や学校名が埋め込まれます。こういうことなのでpdbファイルは信用できる人や開発チーム以外の他の人には渡さないように気をつけてください。できあがったプログラムを友達に渡す方法は第10回で説明しています。

まだ単純なプログラムしか作っていないのでビルドも単純ですが、複雑なアプリケーションを作成するとビルド時に行われる処理や、binフォルダー内に生成されるファイルは変わります。

 

3.コンパイル

3-1.ソースコードとコンパイル

ビルドについてもう少し詳しく見てみます。

MessageBox.Show("Hello") や button1.Text = "aaa" などの文字で書かれたC#のプログラムを ソースコード と呼びます。

フォームにボタンやテキストボックスをぺたぺた貼り付ける操作も、その操作に応じて裏ではForm1.Designer.csにソースコードが自動生成されており、人間が自分で書いたか、コンピューターが自動生成したかの違いはありますが、ソースコードとしては同じ立場です。

ソースコードはそのままでは実行できません。コンピューターでメインの処理を実行しているCPUがC#を理解できないからです。CPUが理解できるのはマシン語(機械語)と呼ばれる形式です。一応「語」とは付いていますが、もはや人間が直接読み書きするような言葉ではありません。C#は2段階の翻訳を経てマシン語に変換され実行されます。

このようにソースコードをコンピューターで実行可能な言語に翻訳する処理を コンパイル と呼びます。

 

3-2.IL

コンパイルの一段階目でソースコードから、アセンブリと呼ばれる種類のファイルに変換されます。

先ほどの例では WinFormsApp1.dll がアセンブリです。

アセンブリの中にはいろいろな情報が含まれています。その中で実行する処理についてはIL(アイエル)と呼ばれる言語で記述されています。C#のソースコードがILに変換されてアセンブリに格納されているというわけです。

ILはかつては MSIL (エムスアイエル) とも呼ばれていました。2段階目のコンパイルをする前の中間の位置づけなので、中間言語とも呼びます。ILの段階ですでにマシン語に近い言語になっており人間による解読は困難です。熟練した人間は直接ILを読み書きできるかもしれません。

この一段階目のコンパイルはVisual Studioでビルドを実行したときに行われます。

 

IL逆アセンブラーというツールでアセンブリを開くと、その中に含まれているアセンブリを確認することができます。

IL逆アセンブラーのファイル名はildasm.exeで、フレームワークののバージョンなどによって分かれているため同じパソコンの中に複数のildasm.exeが存在している場合があります。

これがどこにインストールされているかはっきりした情報はわからないのですが、最近(2022年1月現在)では下記のようなパスに存在します。

C:\Program Files (x86)\Microsoft SDKs\Windows\vXX.XA\bin\NETFX X.X.XTools\ildasm.exe

Xの部分にはバージョンを表す数字が入ります。桁数はバージョンによって異なる場合があります。

たとえば次のパスです。

C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8 Tools\ildasm.exe

 

ildasm.exeを起動すると次のようなウィンドウが開きます。

ildasm.exe

この中に、dllファイルをドラッグ&ドロップしてみてください。

私はC#では下記の通りプログラムして、実行してできた dllファイルを idsasmにドロップしてみました。

private void button1_Click(object sender, EventArgs e)
{
   MessageBox.Show("Hello");
}

 

このように表示されます。

なにやら見慣れない情報が表示されます。このほとんどはILの目次のような情報です。

この中にbutton1_Clickがあります。これをダブルクリックすると中のILが見えます。ILがC#とは全然違う言語であることがわかると思います。

ここで注目して欲しいことは2点あります。

1つは「Hello」という文字列が見えていることです。このようにプログラム内に記述した文字列は簡単に見ることができるので、パスワードのような重要な情報をプログラム内に埋め込んで配布すると中身のパスワードも簡単に見られてしまいます。

2つ目はこのスクリーンショットでは見えていませんが、もう少し右にスクロールすると MessageBox::Show という記述が見えることです。つまり、C#とは全然違うとはいえMSILの知識があれば、このプログラムがどういう処理を行っているかも見ることができます。

見終わったら忘れずにildasm.exeを閉じてください。ildasm.exeでdllなどのファイルを開いている間はVisual Studioでは実行できなくなってしまいます。

 

なお、アセンブリをメモ帳で開いた場合は、ILを確認することはできず次のような表示になります。基本的にはどんな処理をやっているのか読めませんが、一部文字列で埋め込まれる情報もあるので、メモ帳で開くだけでもプログラムの情報の一部を判別できる場合があります。

メモ帳でWindowsFormsApp1.exeを開いたところ

 

 

3-3.JIT

2段階目のコンパイルでILからマシン語(機械語)に翻訳されます。

2段階目のコンパイルはプログラムを実行している最中に行われます。exeの場合は、exeを実行しているときに同時にこの2段階目のコンパイルもしているということです。この仕組みのおかげで、実行する環境に合わせたコンパイルが可能になります。このように実行するタイミングでコンパイルを行う仕組みを JIT ・ JITコンパイル と呼びます。

 

C#ではいろいろな環境向けにいろいろな方法で作ったアプリケーションを実行できるので、場合によってはここで紹介したものとは異なる道筋でプログラムがコンパイルされ実行されることもあります。ここで紹介した流れが代表的なものなので、まずはこの流れを押さえておきましょう。

 

4.エラー

4-1.エラーの種類

今度はビルドの観点でエラーを眺めてみます。

エラーとは、プログラムが意図したとおりに動かない現象で、実にさまざまな種類・状況があります。

ビルドの観点でエラーを3つに分けてみましょう。

 

4-2.ビルドエラー

ビルドエラーはソースコードをILに変換できないというエラーです。

ILを生成できないのでdllファイルも生成されず、プログラムの実行はまったくできません。

ビルドエラーの表示

「最後に成功したビルドを実行しますか?」と聞かれているのは、もし、以前に作成したdllファイルがあるのならば、とりあえずそれを実行しますか? という意味です。

ほとんどの場合、以前に作成したdllファイルを実行する意味はないので「いいえ」が正解です。私はこのダイアログで「はい」が実際に役に立ったことは一度もありません。

 

ビルドエラー

ビルドエラーの場合の多くは、原因と思われる箇所に 赤い波線 が表示され、エラー一覧にエラーの内容が表示されます。

エラー一覧が表示されていない場合は、表示メニューのエラー一覧で表示されます。

これらを手がかりにプログラムを修正していくことになります。

赤い波線はエラーになっている場所であることに間違いないのですが、必ずしも修正すべき場所を表していないことに注意してください。赤い波線とエラー一覧をヒントに修正すべき場所を探すのはプログラマの仕事です。初級講座では修正すべき場所を探すための便利な機能やツールも紹介しますが、まずはC#の知識をつけていくのが良いです。

 

4-3.実行時エラー

実行時エラーはビルドはIL化してアセンブリ(dll)の生成までは成功したけど、それを実行するとエラーが発生するというものです。

次のようにエラーの内容を指摘するダイアログが表示されます。これを例外処理アシスタント ダイアログと呼びます。

実行時エラー

せっかくいろいろな情報が表示されても初心者には厳しいです!と思われるかもしれませんが、一応表示されている内容には目を通す癖をつけましょう。そうしないといつまで経っても慣れないです。

たとえば、この画像だとよくはわからなくてもプログラム内の jp-JP の部分がおかしいらしいという見当はつけられますね。

この例ではここを ja-JP にするとエラーが発生しなくなります。

 

4-4.論理エラー

論理エラーとは、実行した結果が想定と違うことを指します。Visual Studioは別にエラーとは言わないし実行もできるのだけれど、結果がおかしいという場合です。

たとえば、日付の書式設定で日と月を逆にしてしまうとおかしな表示になります。27月6日・・・。おかしいです。

前回の講座の内容を読んでいる人はこのエラーを治す方法は理解していると思います。

月がおかしい

この論理エラーという種類のエラーは、プログラムの実行はできているので他のエラーよりはまだましなように思えるかもしれませんが、Visual Studioが何も言ってくれないので気が付かない場合があり、結構やっかいです。

企業で使っている業務システムで問題になる「バグ」の多くはこの論理エラーです。大人数で何か月もかけてシステムをプログラムして、「できましたー。使ってください!」と言って、使ってみたらエラーにもならずちゃんと動くから、1年くらい使ってて、ある日システムに表示されるなにかの金額の合計を見たら実際にありえない金額が表示されいた…というようなケースですね。はじめからエラーで動かないなら使わないだけなんですが、1年後に金額が違うことが分かったとなるとたいへん困ってしまいます。

ビルドエラーや実行時エラーはVisual Studioが「エラーがある。原因はこれじゃないか」と親切に教えてくれるのですが、論理エラーはエラーがあるのかないのかも自分で確認する必要がありますし、エラーがある場合の原因の推測や修復方法も自分で考えなければなりません。

 

 

次の回では、情報の探し方を見方を説明します。

C#入門講座 第8回 ヘルプの使い方