csc.exeとVisual Studio Codeで始めるWindowsC#プログラミング

# はじめに
Windowsに標準で付属しているC#コンパイラのcsc.exe（以下csc）と[Visual Studio Code][vsc]（以下VS Code）を利用してC#プログラミングを始めるためのまとめです。C#によるプログラミングの仕方についての説明ではなく、cscを利用するにあたっての説明がメインとなります。

[vsc]: https://code.visualstudio.com/
[vs]: https://visualstudio.microsoft.com/
[nf]:https://ja.wikipedia.org/wiki/.NET_Framework

* Windows環境をあまり変えずに気軽にプログラミングをしたい。
* たまにちょっとコードを書いてさっと利用したい。

※サポート中のWindows10（2023年3月時点）を前提として記載しています。

# cscについて

C#コンパイラ。Windowsに標準で付属しているものから[Visual Studio][vs]（VS Codeのことではありません）をインストールしたときにあわせてインストールされるものまで色々ありますが、以下はWindowsに標準で付属しているcscについての説明です。

* cscのある場所

  34bit版 `C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe`  
  64bit版 `C:\Windows\Microsoft.NET\Framework64\v4.0.30319\csc.exe`  
  ※64bit版のWindowsには両方ともあり、[どちらを使ってもよい](https://atmarkit.itmedia.co.jp/ait/articles/1504/15/news019.html)みたいです。  

* C#5までしか対応していない。

   コマンドプロンプトからcscをたたくと以下のように表示されます。C#5までで使用できる機能については[C# の歴史](https://learn.microsoft.com/ja-jp/dotnet/csharp/whats-new/csharp-version-history)を参照。


   ```:コマンドプロンプト
   >C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc
   Microsoft (R) Visual C# Compiler version 4.8.4084.0
   for C# 5
   Copyright (C) Microsoft Corporation. All rights reserved.

   This compiler is provided as part of the Microsoft (R) .NET Framework, but only supports language versions up to C# 5, which is no longer the latest version. For compilers that support newer versions of the C# programming language, see http://go.microsoft.com/fwlink/?LinkID=533240
   ```

* .NET Frameworkとの対応だと4.5[*](https://ufcpp.net/study/csharp/ap_ver5.html)

  4.x系の最後の[.NET Framework][nf]である.NET Framework 4.8については2023年3月現在では[Windows10/11に既定でインストール](https://learn.microsoft.com/ja-jp/dotnet/framework/migration-guide/versions-and-dependencies)されており、削除される予定はありません。そのため当分の間はcscでの開発したものは利用できると考えても問題ないと思います。
  ライフサイクルについて [.NET Framework](https://learn.microsoft.com/ja-jp/lifecycle/faq/dotnet-framework) , [Windows 10](https://learn.microsoft.com/ja-jp/lifecycle/products/windows-10-home-and-pro) , [Windows 11](https://learn.microsoft.com/ja-jp/lifecycle/products/windows-11-home-and-pro)

* 決定論的ビルドができない。[*](https://ufcpp.net/blog/2019/5/deterministicbuilds/)

   決定論的ビルドができると「同一の入力」に対して「同一の出力」を生成できます。これができないと同じソースコードをコンパイルしても毎回異なるバイナリになります。例えばコンパイルをしてexeファイルを作成した場合、コンパイルのたびに違うものができます。
実際にfcで比較すると同一でないことが確認できます。

   ```:コマンドプロンプト
   >fc C:\work\app1.exe C:\work\app2.exe
   ファイル C:\WORK\app1.exe と C:\WORK\APP2.EXE を比較しています
   00000088: D8 DE
   00000468: 18 7A
   00000469: 5A 8D
   0000046A: BE 24
   (以下略)
   ```
  同じバイナリであれば以下のようになります。

   ```:コマンドプロンプト
   >fc C:\work\app1.exe C:\work\app2.exe
   ファイル C:\WORK\app1.exe と C:\WORK\APP2.EXE を比較しています
   FC: 相違点は検出されませんでした
   ```

# 環境構築

コンパイラは付属しているため、メモ帳があればすぐにでも開発できますが、コード補完や自動整形などができるVS Codeを使うほうがコーディングがやりやすいと思います。VS Codeについての説明サイトは多数あるのでここでは概要の流れのみ記載します。

1. VS Codeのインストールと日本語化

   インストール説明サイトの1つを参考に記載しておきます。  
   [https://www.javadrive.jp/vscode/install/index1.html](https://www.javadrive.jp/vscode/install/index1.html)（インストール）  
   [https://www.javadrive.jp/vscode/install/index4.html#section1](https://www.javadrive.jp/vscode/install/index4.html#section1)（日本語化）  

   インストールの途中で「追加タスクの選択」画面になります。本記事では下記のような設定でインストールしたとして説明しています。とりあえず試してみたいだけの人は「サポートされているファイルの種類のエディターとして、Code を登録する」のチェックを外してください。  

   ![vscode008.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3193449/39a7ecb1-67eb-ae46-ef9b-04ad379fde76.png)

2. VS Codeの拡張機能のインストール

   1. 拡張機能アイコンをクリック

   2. 検索ワードを入力（この場合はC#）

   3. 目当ての拡張機能をクリック（この場合はMicrosoftのC#）。右側に拡張機能の説明画面が表示されます。

   4. ライセンスを確認。問題ないなければ手順5.へ

   5. インストールをクリック。「インストールしています」と表示されるのでインストールが終わるまで待ちます。インストールが終わると「アンインストール」の表示になります。これで完了です。日本語化のときと違って再起動は不要です。拡張機能が不要になった場合はこの「アンインストール」を押してアンインストールします。  
      ![vscode010.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3193449/ed55ce29-b9b5-224d-90cf-c5415b7e1d16.png)

3. VS Codeのユーザー設定の変更

   ソースファイルを保存するときに自動整形するように設定を変更します。  

   1. 左下の歯車アイコンをクリックし[設定]を選択します。  
      ![vscode100.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3193449/2805be54-852a-6e63-cf81-4c101a298a81.png)

   2. 検索バーに「format save」と入力したときに出てくる、[Editor:Format On Save]にチェックを入れた後、設定画面を閉じます。  
      ![vscode110.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3193449/7e89299d-1fdb-a6ef-b09b-c37ae27ec42b.png)

# コンパイルと実行

実際にプログラムを書いてHello Worldと表示させてみます。

1. 適当なフォルダ（ここでは`C:\work`）を新規作成し、右クリックして「Code で開く」を選択します。  
  ![comp010.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3193449/b72c0936-3f2a-c71d-2af7-fceda3092901.png)
2. 「このフォルダー内のファイルの作成者を信頼しますか？」と表示されるので「はい、作成者を信頼します」をクリックします。  
  ![comp020.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3193449/23868b5d-99d6-0c9a-5ee8-6d10e0d24c5d.png)
3. ソースファイルを作成します。ファイルの新規作成アイコンをクリックし、「a.cs」と入力してEnterを押します。  
  ![comp030.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3193449/972f77a5-e441-f2a4-ad2e-5ab2c2c50f5d.png)

4. 以下のように入力した後「Ctrl+S」で保存。これでソースファイルの作成は完了です。

   ![comp040.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3193449/f0d676ba-e819-b7ec-1eef-b4997944e25c.png)

    ```cs:a.cs
    using System;

    namespace ConsoleApp
    {
        internal class Program
        {
            static void Main(string[] args)
            {
                Console.WriteLine("Hello World");
            }
        }
    }
    ```
5. あとはコンパイルするだけですが、毎回コンパイルのためのコマンドを入力するのは大変なので、コンパイルをするためのバッチファイルを作成します。先ほどと同様にファイル「a.bat」を作成し、以下のように入力した後、「Ctrl+S」で保存。  

   ![comp050.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3193449/a1a7181b-227a-0ad6-5b5a-fc6897decf00.png)

    ```bat:a.bat
    C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc *.cs
    pause
    ```
    1行目がcscでコンパイルするためのコマンドです。cscに続けてC#ソースファイルを指定します。 フォルダ内の全csファイルをまとめてコンパイルする場合は*.csと指定します。今回はソースファイルが1つしかないため「a.cs」でも構いません。  

    2行目は処理の一時停止をするためのコマンドです。バッチファイルは処理が終わると画面を閉じてしまいます。コンパイルエラーなどがあった場合、画面が閉じてしまうと内容が確認できないので、一時停止させます。  

6. エクスプローラに戻って「a.bat」を実行します。  
   ![comp060.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3193449/8fa285bb-1d97-85fc-ac5d-a6af20d225bf.png)

7. コンパイルされ、下記の画面が出るので適当なキーを押して画面を終了させます。  
   ![comp070.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3193449/f3079fc2-0bd9-2f41-739a-4dcabe6837de.png)

8. エクスプローラのアドレスバーに「cmd」と入力し、Enterを押します。  
   ![comp080.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3193449/ca1e02d4-3f33-415a-850a-8f1047bba30f.png)

9. コマンドプロンプトが立ち上がるので「a.exe」と入力しEnterを押します。  
   ![comp090.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3193449/78a7c891-c6fe-8172-2e29-758533eb7450.png)

10. 「Hello World」と表示されます。  
   ![comp100.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3193449/6eeacbd8-577b-5fb7-30f9-45f1980410e0.png)


# サンプルコード

cscは[Visual Studio][vs]や[dotnet new](https://learn.microsoft.com/ja-jp/dotnet/core/tools/dotnet-new-sdk-templates)のように雛形を自動で作成してくれるわけではないので、全て自分で記載する必要があります。一般的ではないかもしれませんが用途別のサンプルコードとコンパイルするためのコマンドを記載しておきます。  


## コンソールアプリケーション

コマンドライン引数を表示するだけのサンプルコードです。

```cs:ConsoleApp.cs
//コンパイル方法
//C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc ConsoleApp.cs
using System;

namespace ConsoleApp
{
    internal class Program
    {
        static void Main(string[] args)
        {
            foreach (var s in args)
            {
                Console.WriteLine(s);
            }
        }
    }
}
```

## Windowsフォームアプリケーション

コンパイラオプションとして `/target:winexe`をつけることでWindowsアプリケーションとしてコンパイルします。

* STAThreadについては[こちら](https://dobon.net/vb/dotnet/form/stathread.html)が参考になると思います。C言語の[WinMain](https://www.keicode.com/winprimer/wp06.php)に該当すると理解すればいいようです。  
* Application.EnableVisualStyles()などについては[こちら](https://atmarkit.itmedia.co.jp/fdotnet/easyvs2nd/easyvs2nd04/easyvs2nd04_01.html)が参考になると思います。


**通常のフォームアプリケーションのサンプルコード**


```cs:WindowsFormsApp.cs
//コンパイル方法
//C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc /target:winexe WindowsFormsApp.cs
using System;
using System.Windows.Forms;

namespace WindowsFormsApp
{
    internal static class Program
    {
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
    }

    public partial class Form1 : Form
    {
        public Form1()
        {

        }
    }
}
```

**アイコンを指定したいときのサンプルコード**

コンパイラオプションの`/win32icon`によりアイコンを指定することができます。これだけではアプリケーションファイルのアイコン（エクスプローラ上で表示されるアイコン）しか変更できませんが、サンプルコードではExtractAssociatedIconメソッドを使用することでフォームのアイコンにも同じアイコンを設定しています。  

参考リンク  
[Icon.ExtractAssociatedIcon(String) メソッド (System.Drawing) | Microsoft Learn](https://learn.microsoft.com/ja-jp/dotnet/api/system.drawing.icon.extractassociatedicon?view=netframework-4.8)  

```cs:WindowsFormsApp.cs
//コンパイル方法
//同じフォルダにアイコンファイル(app.ico)を入れる。
//C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc /target:winexe /win32icon:app.ico WindowsFormsApp.cs
using System;
using System.Windows.Forms;

namespace WindowsFormsApp
{
    internal static class Program
    {
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
    }

    public partial class Form1 : Form
    {
        public Form1()
        {
            try
            {
                //自分自身のパス
                string apppath = System.Reflection.Assembly.GetExecutingAssembly().Location;

                //自分自身のアイコンを取得する
                System.Drawing.Icon myIcon = System.Drawing.Icon.ExtractAssociatedIcon(apppath);

                //Formのアイコンとして設定する
                this.Icon = myIcon;
            }
            catch (System.Exception)
            {
                ;
            }
        }
    }
}
```

**タスクトレイ常駐アプリとする場合のサンプルコード**

フォームを表示させずにタスクトレイにのみアイコンを表示させるようにしています。またタスクトレイアイコンの右クリックからアプリケーションを終了できるようにしています。  

参考リンク  
[フォームを表示させずにトレイアイコンを表示する - .NET Tips (VB.NET,C#...)](https://dobon.net/vb/dotnet/form/hideformwithtrayicon.html)  
[システムトレイ（タスクトレイ）にアイコンを表示するには？［2.0、C#、VB］ - ＠IT](https://atmarkit.itmedia.co.jp/fdotnet/dotnettips/739notifyicon2/notifyicon2.html)  
[NotifyIcon コンストラクター (System.Windows.Forms) | Microsoft Learn](https://learn.microsoft.com/ja-jp/dotnet/api/system.windows.forms.notifyicon.-ctor)  

```cs:WindowsFormsApp.cs
//コンパイル方法
//C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc /target:winexe WindowsFormsApp.cs
using System;
using System.Windows.Forms;

namespace WindowsFormsApp
{
    internal static class Program
    {
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Form1 f = new Form1();
            Application.Run();
        }
    }
    public class Form1 : Form
    {
        private System.ComponentModel.IContainer components;
        private NotifyIcon notifyIcon1;

        public Form1()
        {
            this.components = new System.ComponentModel.Container();

            //終了メニュー
            ToolStripMenuItem ExitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
            ExitToolStripMenuItem.Text = "終了";
            ExitToolStripMenuItem.Click += new System.EventHandler(this.ExitToolStripMenuItem_Click);

            //コンテキストメニュー
            ContextMenuStrip contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip();
            contextMenuStrip1.Items.Add(ExitToolStripMenuItem);

            //トレイアイコン
            this.notifyIcon1 = new System.Windows.Forms.NotifyIcon(this.components);
            this.notifyIcon1.ContextMenuStrip = contextMenuStrip1;
            this.notifyIcon1.Icon = this.Icon;
            this.notifyIcon1.Visible = true;
        }

        private void ExitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.notifyIcon1.Visible = false;
            Application.Exit();
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }
    }
}
```

**処理だけして終了させる場合のサンプルコード**

Windowsアプリケーションとしてコンパイルすることで実行時にコンソール画面を出しません。処理だけをして終了させたいときは、`/target:winexe`をつけることで非表示で実行させることができます。  


```cs:WindowsFormsApp.cs
//コンパイル方法
//C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc /target:winexe WindowsFormsApp.cs
using System;

namespace WindowsFormsApp
{
    internal static class Program
    {
        [STAThread]
        static void Main()
        {
            //ここにコードを記載
        }
    }
}
```
# コンパイラオプション

ここでは一部の代表的なコンパイラオプションについて説明します。  
コンパイラオプションについては `csc /help` or `csc -help` or `csc /?` で確認できます。  

**/target:winexe または /t:winexe**  
Windowsアプリケーションをビルドします（上述の通り）。  

**/target:library または  /t:library**  
ライブラリをビルドします。  

**/win32icon:アイコンファイル**  
アイコンを指定します（上述の通り）。/win32resとの併用は不可[*](https://atmarkit.itmedia.co.jp/ait/articles/0512/09/news137.html)。  

**/win32res:resファイル**  
リソースファイルを指定します。リソースがアイコンだけであれば`/win32icon`のほうが簡単ですが、自分でリソースファイルを指定して設定することもできます。本記事の趣旨とは異なりますのでここでは概要の流れのみ記載します。  

1. .rcファイルを作成する[*](https://www.keicode.com/winprimer/wp13.php)。  

   ```cpp:app.rc
   100 ICON "app.ico"
   ```
2. MinGW-w64[*](https://www.javadrive.jp/cstart/install/index6.html)のインストール先のbinフォルダ内にあるwindres.exe[*](https://web.mit.edu/rhel-doc/3/rhel-binutils-en-3/windres.html)を使用して.rcファイルから.resファイルを作成する。  

   ```bat:コマンドプロンプト
   REM 同じフォルダにapp.icoを入れておく。
   windres -i app.rc -O res -o app.res
   ```
3. .resファイルを指定してコンパイルをする。  

   ```bat:コマンドプロンプト
   csc /t:winexe /win32res:app.res WindowsFormsApp.cs
   ```
**/optimize[+|-]**  
最適化を実施します。  

**/deterministic (参考)**  
決定論的ビルドをします。「同一の入力」に対して「同一の出力」を生成します。  
Windowsに標準で付属しているcscにはないオプションですが、決定論的ビルドができることは重要ですので参考として記載します。後述の[Roslyn](#roslyn)の場合、初期の頃のバージョンを除けばこのオプションを使用できます。「同一の入力」については以下が参考になると思います。  

[roslyn/Deterministic Inputs.md at main · dotnet/roslyn · GitHub](https://github.com/dotnet/roslyn/blob/main/docs/compilers/Deterministic%20Inputs.md)

**/nologo**  
コンパイル時の著作権メッセージを表示しません。  

**/r:ファイル**  
指定したアセンブリファイルを参照します。指定しなくても[デフォルトで多くのアセンブリが参照設定されている](https://atmarkit.itmedia.co.jp/fdotnet/dotnettips/179cscrsp/cscrsp.html)ため、ちょっとコードを書く分には特に意識する必要はありません。デフォルトで参照されているもの以外を参照したい場合、例えばMicrosoft.VisualBasic.dllを参照することでデフォルトのままでは使用できない機能を利用できますが、そのようなことをしたい場合は`/r:Microsoft.VisualBasic.dll`というように指定します。  

以下は`Microsoft.VisualBasic.dll`の参照により左右のマウスボタンの機能が入れ替わっているかを確認するサンプルコードです。  

参考リンク  
[.NET TIPS VB.NET固有の関数をC#で使用するには？ - ＠IT](https://atmarkit.itmedia.co.jp/fdotnet/dotnettips/254vbfunc/vbfunc.html)  
[C#からVBのMy機能を利用するには？［2.0のみ、VS 2005のみ、C#］ - ＠IT](https://atmarkit.itmedia.co.jp/fdotnet/dotnettips/413myincs/myincs.html)  
[Mouse クラス (Microsoft.VisualBasic.Devices) | Microsoft Learn](https://learn.microsoft.com/ja-jp/dotnet/api/microsoft.visualbasic.devices.mouse?view=netframework-4.8)  


```cs:WindowsFormsApp.cs
//コンパイル方法
//C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc /target:winexe /r:Microsoft.VisualBasic.dll WindowsFormsApp.cs
using System;
using System.Windows.Forms;
using Microsoft.VisualBasic;

namespace WindowsFormsApp
{
    internal static class Program
    {
        [STAThread]
        static void Main()
        {
            Microsoft.VisualBasic.Devices.Computer myComputer = new Microsoft.VisualBasic.Devices.Computer();

            if (myComputer.Mouse.ButtonsSwapped)
            {
                MessageBox.Show("左右のマウスボタンの機能が入れ替わっています");
            }
            else
            {
                MessageBox.Show("左右のマウスボタンの機能が入れ替わっていません");
            }
        }
    }
}
```
# 番外編

環境をあまり変更せずに、ちょっとコードを書いてさっと利用したい、という本記事の趣旨とは異なる内容になります。但し関連する内容のため番外編として記載します。


## 標準環境にあるファイル以外を参照する

参照するファイルは、元から存在するファイルだけでなく、インターネットなどで入手したものも指定できます。例えば以下の例では、ClosedXML等を参照することで、セルA1の値と書式が変更されたExcelファイルを作成しています。

参考リンク  
[ExcelなしでExcelファイルを操作するには？（ClosedXML編）［.NET 4.0、C#／VB］：.NET TIPS - ＠IT](https://atmarkit.itmedia.co.jp/ait/articles/1810/24/news016.html)  
[NuGet project.json ファイルと UWP プロジェクト | Microsoft Learn](https://learn.microsoft.com/ja-jp/nuget/archive/project-json-and-uwp)

1. nugetのClosedXMLのページへ行きます。最新のバージョンでは .NET Frameworkには対応していないようなので、バージョン0.95.4 のページへ行きます。  

    [https://www.nuget.org/packages/ClosedXML/0.95.4#dependencies-body-tab](https://www.nuget.org/packages/ClosedXML/0.95.4#dependencies-body-tab)

2. Download packageをクリックしファイルをダウンロードします。  
    ![excel010.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3193449/b37dfb28-63c2-f79f-391d-4f13a0a43ec4.png)

3. 依存関係を確認します。cscは.NET Frameworkとの対応で行くと4.5になりますのでそれ以下のバージョンである必要があります。  
ここでは.NET Framework 4.0の箇所を確認します。DocumentFormat.OpenXml(v2.7.2以上)とExcelNumberFormat(v1.0.10以上)が必要であることが分かります。  
    ![excel020.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3193449/624abb05-fcc3-4ea4-b01d-cc9513abb42a.png)  

4. DocumentFormat.OpenXml 2.7.2  のページへ  

    [https://www.nuget.org/packages/DocumentFormat.OpenXml/2.7.2#dependencies-body-tab](https://www.nuget.org/packages/DocumentFormat.OpenXml/2.7.2#dependencies-body-tab)

5. Download packageをクリックしダウンロードします。また、NET Framework 4.5以下(.NET Framework 4.0)で使用する場合は依存関係なしであることを確認します。  
    ![excel030.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3193449/9fef229c-6232-0085-900c-9dd206490fb9.png)

6. ExcelNumberFormat 1.1.0 のページへ  

   [https://www.nuget.org/packages/ExcelNumberFormat/1.0.10#dependencies-body-tab](https://www.nuget.org/packages/ExcelNumberFormat/1.0.10#dependencies-body-tab)

7. 同様にDownload packageをクリックしダウンロードし、また.NET Framework 4.5以下(.NET Framework 2.0)で使用する場合は依存関係なしであることを確認します。  

8. ダウンロードしたファイルのファイル名の末尾に「.zip」を追加します。「拡張子を変更すると、ファイルが使えなくなる可能性があります。」と表示されたら「はい」を押します。  
    ![excel040.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3193449/9a6645f5-4cf8-bb2c-0275-1577582ea588.png)

9. 他の2つのファイルについても同様にファイル名の末尾に「.zip」を追加します。これでファイルのダブルクリックにより中身を見られるようになります。  
    ![excel050.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3193449/3518271d-ddc0-24ea-7b5b-31e3ed119ab7.png)


10. 以下の3つのファイルを同じフォルダへコピーします。ここでは例として`C:\work`へコピーしたとします。  

    `closedxml.0.95.4.nupkg.zip\lib\net40\ClosedXML.dll`を`C:\work`へコピー  
    ![excel060.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3193449/9df2dbf7-ac34-62a4-c0a6-1cd6370be47c.png)

    `documentformat.openxml.2.7.2.nupkg.zip\lib\net40\DocumentFormat.OpenXml.dll`を`C:\work`へコピー  
    ![excel062.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3193449/84246812-5edc-5556-677f-e7292b9105c5.png)

    `excelnumberformat.1.0.10.nupkg.zip\lib\net20\ExcelNumberFormat.dll`を`C:\work`へコピー  
    ![excel064.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3193449/c82dd7b5-75d4-3a36-89fc-28f71083b328.png)

11. `C:\work`フォルダの中に以下のcsファイルを作成します。  

    ```cs:CreateBook.cs
    //ClosedXMLを使用してExcelブックを操作する。
    using System;
    using System.Windows.Forms;

    namespace WindowsFormsApp
    {
        internal static class Program
        {
            [STAThread]
            static void Main()
            {
                //ブックの新規作成
                ClosedXML.Excel.XLWorkbook book = new ClosedXML.Excel.XLWorkbook();

                //シート追加
                ClosedXML.Excel.IXLWorksheet worksheet = book.Worksheets.Add("sheet1");

                //セルに値を入れる
                worksheet.Cell("A1").Value = 10;

                //セルの書式変更
                worksheet.Cell("A1").Style.Fill.BackgroundColor = ClosedXML.Excel.XLColor.Red;

                //保存
                book.SaveAs(@"C:\work\book1.xlsx");

                //破棄
                book.Dispose();
            }
        }
    }
    ```
12. `/r`オプションにより参照するファイルを追加してコンパイルします。  

    ```bat
    REM コンパイル方法
    C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc /target:winexe /r:ClosedXML.dll   /r:DocumentFormat.OpenXml.dll /r:ExcelNumberFormat.dll CreateBook.cs
    ```

13. 作成された`CreateBook.exe`を実行すると`book1.xlsx`が作成されます。  
    ![excel070.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3193449/6be93008-0748-b346-989a-38cfefda7719.png)

14. 開くとA1セルの背景色が赤、値が10になっています。  
    ![excel080.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3193449/857c2f62-c3d4-99c0-b5ea-2e265685cce5.png)

## nuget

上記の例では、自分で依存関係の確認とダウンロードをしましたが、パッケージ・マネージャであるnugetを利用すると、これらを自動で行うことができます。例として上記と同じことをしてみます。  

1. nugetのダウンロードページに行きます。  

   [https://www.nuget.org/downloads](https://www.nuget.org/downloads)

2. 最新のファイル（nuget.exe）をダウンロードします。画面は2023年3月時点のものです。  
    ![nuget010.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3193449/102c8c58-b89f-8388-a7dc-89ce65b96cd9.png)

3. ダウンロードしたnuget.exeを適当な場所に移動します。普段使いする場合はパスを通した場所に移動しますが、ここでは`C:\work`に移動したとします。  

4. `C:\work`でコマンドプロンプトを立ち上げて以下のコマンドを実行します。  

   ```dos:コマンドプロンプト
   C:\work>nuget install ClosedXML -version 0.95.4
   ```
5. 依存関係にあるパッケージが全てダウンロードされました。上記の例では.NET Framework4.5を対象にしましたがそれ以外の場合に必要になるパッケージもダウンロードされています。  

    ![nuget020.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3193449/f0dd840c-a54d-009c-3186-81a43351d0c7.png)


参考リンク  
[.NET開発の新標準「NuGet」入門（前編）（1/4） - ＠IT](https://atmarkit.itmedia.co.jp/fdotnet/chushin/nuget_01/nuget_01_01.html)  
[NuGet CLI を使用して NuGet パッケージを管理する | Microsoft Learn](https://learn.microsoft.com/ja-jp/nuget/consume-packages/install-use-packages-nuget-cli)  

## Roslyn

よく分かっていないためインターネットで調べてみました。間違っているかもしれませんが、

* C#とVisual Basic.NETのコンパイラ。コード解析もできる。

   [GitHub - dotnet/roslyn: The Roslyn .NET compiler provides C# and Visual Basic languages with rich code analysis APIs.](https://github.com/dotnet/roslyn)  
   [Roslyn - Wikipedia](https://ja.wikipedia.org/wiki/Roslyn)  
   [10分間で人に説明できるまで分かるCompiler as a Service“Roslyn” - Build Insider](https://www.buildinsider.net/enterprise/sansanreport/0503)  
   [Visual Studio 2015の新機能“Roslyn”とは - Build Insider](https://www.buildinsider.net/enterprise/roslyn/01)

* Visual StudioでサポートされているRoslynパッケージのバージョンについては[こちら](https://learn.microsoft.com/ja-jp/visualstudio/extensibility/roslyn-version-support?view=vs-2022)。

* オープンソース（MIT license）

* C#コンパイラのファイル名は同じくcsc.exe。

* 最新バージョンのC#言語で書かれたコードをコンパイル可能。但し.生成物をNET Framework4.8環境(Windowsに標準でインストール済み。2023年3月時点)で使用する場合はC#7.3まで[*](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)#Versions)なので`-langversion:7.3`オプション[*](https://learn.microsoft.com/ja-jp/dotnet/csharp/language-reference/compiler-options/language)により許容される言語バージョンを指定したほうがいいかもしれません。

* 上述の通り`-deterministic`オプションにより決定論的ビルドが可能。

* [Microsoft.Net.Compilers.Toolset](https://www.nuget.org/packages/Microsoft.Net.Compilers.Toolset)（2023年3月時点ではv4.5.0）の中にあるのでnugetを利用して入手可能。以下のコマンドを実行。完了後`Microsoft.Net.Compilers.Toolset.4.5.0\tasks\net472`内に`csc.exe`があります。

   ```dos:コマンドプロンプト
   C:\work>nuget install Microsoft.Net.Compilers.Toolset -version 4.5.0
   ```