はじめに
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についての説明サイトは多数あるのでここでは概要の流れのみ記載します。
-
VS Codeのインストールと日本語化
インストール説明サイトの1つを参考に記載しておきます。
https://www.javadrive.jp/vscode/install/index1.html(インストール)
https://www.javadrive.jp/vscode/install/index4.html#section1(日本語化)インストールの途中で「追加タスクの選択」画面になります。本記事では下記のような設定でインストールしたとして説明しています。とりあえず試してみたいだけの人は「サポートされているファイルの種類のエディターとして、Code を登録する」のチェックを外してください。
-
VS Codeの拡張機能のインストール
-
VS Codeのユーザー設定の変更
ソースファイルを保存するときに自動整形するように設定を変更します。
コンパイルと実行
実際にプログラムを書いてHello Worldと表示させてみます。
-
以下のように入力した後「Ctrl+S」で保存。これでソースファイルの作成は完了です。
a.csusing System; namespace ConsoleApp { internal class Program { static void Main(string[] args) { Console.WriteLine("Hello World"); } } }
-
あとはコンパイルするだけですが、毎回コンパイルのためのコマンドを入力するのは大変なので、コンパイルをするためのバッチファイルを作成します。先ほどと同様にファイル「a.bat」を作成し、以下のように入力した後、「Ctrl+S」で保存。
a.batC:\Windows\Microsoft.NET\Framework\v4.0.30319\csc *.cs pause
1行目がcscでコンパイルするためのコマンドです。cscに続けてC#ソースファイルを指定します。 フォルダ内の全csファイルをまとめてコンパイルする場合は*.csと指定します。今回はソースファイルが1つしかないため「a.cs」でも構いません。
2行目は処理の一時停止をするためのコマンドです。バッチファイルは処理が終わると画面を閉じてしまいます。コンパイルエラーなどがあった場合、画面が閉じてしまうと内容が確認できないので、一時停止させます。
サンプルコード
cscはVisual Studioやdotnet newのように雛形を自動で作成してくれるわけではないので、全て自分で記載する必要があります。一般的ではないかもしれませんが用途別のサンプルコードとコンパイルするためのコマンドを記載しておきます。
コンソールアプリケーション
コマンドライン引数を表示するだけのサンプルコードです。
//コンパイル方法
//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()などについてはこちらが参考になると思います。
通常のフォームアプリケーションのサンプルコード
//コンパイル方法
//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
//コンパイル方法
//同じフォルダにアイコンファイル(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
//コンパイル方法
//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
をつけることで非表示で実行させることができます。
//コンパイル方法
//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
のほうが簡単ですが、自分でリソースファイルを指定して設定することもできます。本記事の趣旨とは異なりますのでここでは概要の流れのみ記載します。
-
.rcファイルを作成する*。
app.rc100 ICON "app.ico"
-
MinGW-w64*のインストール先のbinフォルダ内にあるwindres.exe*を使用して.rcファイルから.resファイルを作成する。
コマンドプロンプトREM 同じフォルダにapp.icoを入れておく。 windres -i app.rc -O res -o app.res
-
.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
//コンパイル方法
//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
-
nugetのClosedXMLのページへ行きます。最新のバージョンでは .NET Frameworkには対応していないようなので、バージョン0.95.4 のページへ行きます。
https://www.nuget.org/packages/ClosedXML/0.95.4#dependencies-body-tab
-
依存関係を確認します。cscは.NET Frameworkとの対応で行くと4.5になりますのでそれ以下のバージョンである必要があります。
ここでは.NET Framework 4.0の箇所を確認します。DocumentFormat.OpenXml(v2.7.2以上)とExcelNumberFormat(v1.0.10以上)が必要であることが分かります。
-
DocumentFormat.OpenXml 2.7.2 のページへ
https://www.nuget.org/packages/DocumentFormat.OpenXml/2.7.2#dependencies-body-tab
-
Download packageをクリックしダウンロードします。また、NET Framework 4.5以下(.NET Framework 4.0)で使用する場合は依存関係なしであることを確認します。
-
ExcelNumberFormat 1.1.0 のページへ
https://www.nuget.org/packages/ExcelNumberFormat/1.0.10#dependencies-body-tab
-
同様にDownload packageをクリックしダウンロードし、また.NET Framework 4.5以下(.NET Framework 2.0)で使用する場合は依存関係なしであることを確認します。
-
ダウンロードしたファイルのファイル名の末尾に「.zip」を追加します。「拡張子を変更すると、ファイルが使えなくなる可能性があります。」と表示されたら「はい」を押します。
-
他の2つのファイルについても同様にファイル名の末尾に「.zip」を追加します。これでファイルのダブルクリックにより中身を見られるようになります。
-
以下の3つのファイルを同じフォルダへコピーします。ここでは例として
C:\work
へコピーしたとします。closedxml.0.95.4.nupkg.zip\lib\net40\ClosedXML.dll
をC:\work
へコピー
documentformat.openxml.2.7.2.nupkg.zip\lib\net40\DocumentFormat.OpenXml.dll
をC:\work
へコピー
excelnumberformat.1.0.10.nupkg.zip\lib\net20\ExcelNumberFormat.dll
をC:\work
へコピー
-
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(); } } }
-
/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
nuget
上記の例では、自分で依存関係の確認とダウンロードをしましたが、パッケージ・マネージャであるnugetを利用すると、これらを自動で行うことができます。例として上記と同じことをしてみます。
-
nugetのダウンロードページに行きます。
-
ダウンロードしたnuget.exeを適当な場所に移動します。普段使いする場合はパスを通した場所に移動しますが、ここでは
C:\work
に移動したとします。 -
C:\work
でコマンドプロンプトを立ち上げて以下のコマンドを実行します。コマンドプロンプトC:\work>nuget install ClosedXML -version 0.95.4
-
依存関係にあるパッケージが全てダウンロードされました。上記の例では.NET Framework4.5を対象にしましたがそれ以外の場合に必要になるパッケージもダウンロードされています。
参考リンク
.NET開発の新標準「NuGet」入門(前編)(1/4) - @IT
NuGet CLI を使用して NuGet パッケージを管理する | Microsoft Learn
Roslyn
よく分かっていないためインターネットで調べてみました。間違っているかもしれませんが、
-
C#とVisual Basic.NETのコンパイラ。コード解析もできる。
GitHub - dotnet/roslyn: The Roslyn .NET compiler provides C# and Visual Basic languages with rich code analysis APIs.
Roslyn - Wikipedia
10分間で人に説明できるまで分かるCompiler as a Service“Roslyn” - Build Insider
Visual Studio 2015の新機能“Roslyn”とは - Build Insider -
Visual StudioでサポートされているRoslynパッケージのバージョンについてはこちら。
-
オープンソース(MIT license)
-
C#コンパイラのファイル名は同じくcsc.exe。
-
最新バージョンのC#言語で書かれたコードをコンパイル可能。但し.生成物をNET Framework4.8環境(Windowsに標準でインストール済み。2023年3月時点)で使用する場合はC#7.3まで*なので
-langversion:7.3
オプション*により許容される言語バージョンを指定したほうがいいかもしれません。 -
上述の通り
-deterministic
オプションにより決定論的ビルドが可能。 -
Microsoft.Net.Compilers.Toolset(2023年3月時点ではv4.5.0)の中にあるのでnugetを利用して入手可能。以下のコマンドを実行。完了後
Microsoft.Net.Compilers.Toolset.4.5.0\tasks\net472
内にcsc.exe
があります。コマンドプロンプトC:\work>nuget install Microsoft.Net.Compilers.Toolset -version 4.5.0