LoginSignup
6
7

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

Last updated at Posted at 2023-03-12

はじめに

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

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

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

cscについて

C#コンパイラ。Windowsに標準で付属しているものからVisual Studio(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には両方ともあり、どちらを使ってもよいみたいです。

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

    コマンドプロンプトからcscをたたくと以下のように表示されます。C#5までで使用できる機能についてはC# の歴史を参照。

    コマンドプロンプト
    >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*

    4.x系の最後の.NET Frameworkである.NET Framework 4.8については2023年3月現在ではWindows10/11に既定でインストールされており、削除される予定はありません。そのため当分の間はcscでの開発したものは利用できると考えても問題ないと思います。
    ライフサイクルについて .NET Framework , Windows 10 , Windows 11

  • 決定論的ビルドができない。*

    決定論的ビルドができると「同一の入力」に対して「同一の出力」を生成できます。これができないと同じソースコードをコンパイルしても毎回異なるバイナリになります。例えばコンパイルをして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/index4.html#section1(日本語化)

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

    vscode008.png

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

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

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

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

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

    5. インストールをクリック。「インストールしています」と表示されるのでインストールが終わるまで待ちます。インストールが終わると「アンインストール」の表示になります。これで完了です。日本語化のときと違って再起動は不要です。拡張機能が不要になった場合はこの「アンインストール」を押してアンインストールします。
      vscode010.png

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

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

    1. 左下の歯車アイコンをクリックし[設定]を選択します。
      vscode100.png

    2. 検索バーに「format save」と入力したときに出てくる、[Editor:Format On Save]にチェックを入れた後、設定画面を閉じます。
      vscode110.png

コンパイルと実行

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

  1. 適当なフォルダ(ここではC:\work)を新規作成し、右クリックして「Code で開く」を選択します。
    comp010.png

  2. 「このフォルダー内のファイルの作成者を信頼しますか?」と表示されるので「はい、作成者を信頼します」をクリックします。
    comp020.png

  3. ソースファイルを作成します。ファイルの新規作成アイコンをクリックし、「a.cs」と入力してEnterを押します。
    comp030.png

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

    comp040.png

    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

    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

  7. コンパイルされ、下記の画面が出るので適当なキーを押して画面を終了させます。
    comp070.png

  8. エクスプローラのアドレスバーに「cmd」と入力し、Enterを押します。
    comp080.png

  9. コマンドプロンプトが立ち上がるので「a.exe」と入力しEnterを押します。
    comp090.png

  10. 「Hello World」と表示されます。
    comp100.png

サンプルコード

cscはVisual Studiodotnet newのように雛形を自動で作成してくれるわけではないので、全て自分で記載する必要があります。一般的ではないかもしれませんが用途別のサンプルコードとコンパイルするためのコマンドを記載しておきます。

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

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

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についてはこちらが参考になると思います。C言語のWinMainに該当すると理解すればいいようです。
  • Application.EnableVisualStyles()などについてはこちらが参考になると思います。

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

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

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#...)
システムトレイ(タスクトレイ)にアイコンを表示するには?[2.0、C#、VB] - @IT
NotifyIcon コンストラクター (System.Windows.Forms) | Microsoft Learn

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をつけることで非表示で実行させることができます。

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との併用は不可*

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

  1. .rcファイルを作成する*

    app.rc
    100 ICON "app.ico"
    
  2. MinGW-w64*のインストール先のbinフォルダ内にあるwindres.exe*を使用して.rcファイルから.resファイルを作成する。

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

    コマンドプロンプト
    csc /t:winexe /win32res:app.res WindowsFormsApp.cs
    

/optimize[+|-]
最適化を実施します。

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

roslyn/Deterministic Inputs.md at main · dotnet/roslyn · GitHub

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

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

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

参考リンク
.NET TIPS VB.NET固有の関数をC#で使用するには? - @IT
C#からVBのMy機能を利用するには?[2.0のみ、VS 2005のみ、C#] - @IT
Mouse クラス (Microsoft.VisualBasic.Devices) | Microsoft Learn

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
NuGet project.json ファイルと UWP プロジェクト | Microsoft Learn

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

    https://www.nuget.org/packages/ClosedXML/0.95.4#dependencies-body-tab

  2. Download packageをクリックしファイルをダウンロードします。
    excel010.png

  3. 依存関係を確認します。cscは.NET Frameworkとの対応で行くと4.5になりますのでそれ以下のバージョンである必要があります。
    ここでは.NET Framework 4.0の箇所を確認します。DocumentFormat.OpenXml(v2.7.2以上)とExcelNumberFormat(v1.0.10以上)が必要であることが分かります。
    excel020.png

  4. DocumentFormat.OpenXml 2.7.2 のページへ

    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

  6. ExcelNumberFormat 1.1.0 のページへ

    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

  9. 他の2つのファイルについても同様にファイル名の末尾に「.zip」を追加します。これでファイルのダブルクリックにより中身を見られるようになります。
    excel050.png

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

    closedxml.0.95.4.nupkg.zip\lib\net40\ClosedXML.dllC:\workへコピー
    excel060.png

    documentformat.openxml.2.7.2.nupkg.zip\lib\net40\DocumentFormat.OpenXml.dllC:\workへコピー
    excel062.png

    excelnumberformat.1.0.10.nupkg.zip\lib\net20\ExcelNumberFormat.dllC:\workへコピー
    excel064.png

  11. C:\workフォルダの中に以下の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オプションにより参照するファイルを追加してコンパイルします。

    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

  14. 開くとA1セルの背景色が赤、値が10になっています。
    excel080.png

nuget

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

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

    https://www.nuget.org/downloads

  2. 最新のファイル(nuget.exe)をダウンロードします。画面は2023年3月時点のものです。
    nuget010.png

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

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

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

    nuget020.png

参考リンク
.NET開発の新標準「NuGet」入門(前編)(1/4) - @IT
NuGet CLI を使用して NuGet パッケージを管理する | Microsoft Learn

Roslyn

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

6
7
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
7