株式会社シベスピ 従業員ブログ

シベスピの社員ブログ。技術・想い・経験沢山書いていきます!

【C#】Visual StudioなしでC#のコンパイル【小ネタ】

御託

こんにちはIskです。
最近ブログの出番が回ってこないのでネタが溜まってしまいました。基本的に気分が乗らないと書けないのですが、今日はいい感じなのでここらで一気に書き出してみたいと思います。(2/10時点)
とのことだったのですが翌日2/11に昔ハマってたものに再ハマりしてしまい結局2/10に書いたこれ一本しか書き上がってませんでした。(ネタはあるのよ…)

さて今回はWindowsフォームアプリケーション入門とは別に、C#に関する小ネタを書いていこうかなと思います。
基本的にC#でコードを書く時はVisualStudioを使用するのが一般的ですが、セキュリティの都合やネットワークの関係でVisual Studioをダウンロードできない・インストールできない場合や、Visual Studioが入っていない端末で一時的に作業しなければいけないなどVisual Studioを使用できない事が多々あると思います。(Isk調べ 調査対象:Isk)

そんな時ふとC#のプログラムが書きたくなったらどうしましょう。コンパイルできません。困りました。禁断症状で夜しか眠ることが出来ません。

でも大丈夫!C#はそんな迷える子羊のために素晴らしいものを用意してくれています。

コンパイル方法

・使うもの
C:\Windows\Microsoft.NET\Framework\(バージョン)\csc.exe
Windowsに標準でインストール済みです
※(バージョン)は各端末によって異なる場合があります

・使い方
コマンドプロンプト
「C:\Windows\Microsoft.NET\Framework\(バージョン)\csc.exe C:\main.cs」

御託2

なんということでしょう。Visual Studioが使用できない環境でもC#で書いたソースファイルをexeにすることが出来ました。これには迷える子羊たちも大喜びで庭を駆けずり回っています。かがくの ちからって すげー!

でもでもちょっと待って。これFile.ReadAllTextとか使えなくない?意味なくない?ちゃうちゃうちゃうんちゃう?

コンパイルに便利なバッチ

コンソールアプリケーション用バッチファイル

@echo off
rem ソースファイルと同じディレクトリにこのバッチファイルを配置してください。
rem バッチファイルを実行すると同じディレクトリにあるソースファイルがコンパイルされます。
rem バージョン部分は各環境に置き換えて下さい。
cd /d C:\Windows\Microsoft.NET\Framework\v4.0.30319

set srcPath=%~dp0*.cs
set exePath=%~dp0%~n0.exe

set dllPaths=system.dll,system.drawing.dll,system.windows.forms.dll,system.io.dll,System.Reflection.dll

csc.exe /optimize+ /out:%exePath% %srcPath% /r:%dllPaths%

echo %ERRORLEVEL%

if %ERRORLEVEL% == 0 (
  goto SUCCESS
) 

pause

:SUCCESS

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

using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using System.IO;
using System.Text;
using System.Reflection;
using System.Diagnostics;

namespace Isk
{
    public class Class1 
    {
        static void Main()
        {
        	Console.WriteLine("ハロワ");
        }
    }
}

Windowsフォームアプリケーション用バッチファイル

@echo off
rem ソースファイルと同じディレクトリにこのバッチファイルを配置してください。
rem バッチファイルを実行すると同じディレクトリにあるソースファイルがコンパイルされます。
rem バージョン部分は各環境に置き換えて下さい。
cd /d C:\Windows\Microsoft.NET\Framework\v4.0.30319

set srcPath=%~dp0*.cs
set exePath=%~dp0%~n0.exe

set dllPaths=system.dll,system.drawing.dll,system.windows.forms.dll,system.io.dll,System.Reflection.dll

csc.exe /t:winexe /optimize+ /out:%exePath% %srcPath% /r:%dllPaths%

echo %ERRORLEVEL%

if %ERRORLEVEL% == 0 (
  goto SUCCESS
)

pause

:SUCCESS

Windowsフォームアプリケーション用サンプルソース

Form1.cs

using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using System.IO;
using System.Text;
using System.Reflection;
using System.Linq;
using System.Collections;
using System.Collections.Generic;

namespace Isk
{
    public partial class Form1
    {
        public Form1()
        {
            ComponentInitialize();
        }
        
        private void button_Click(object sender, EventArgs e)
        {
        	textbox.Text = "はろわ";
        }
    }
}


Form1.Designer.cs

using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using System.IO;
using System.Text;
using System.Reflection;

namespace Isk
{
    public partial class Form1 : Form
    {
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.Run(new Form1());
        }
        
        private TextBox textbox;
        private Button button;
        
        private void ComponentInitialize()
        {
            textbox = new TextBox(){
                Location = new Point(5, 5),
                Size = new Size(this.ClientSize.Width - 5 - 5, 40),
                Anchor = (AnchorStyles.Top | AnchorStyles.Right | AnchorStyles.Left),
                Font = new Font("MS ゴシック", 9),
            };
            
            button = new Button(){
                Location = new Point(5, textbox.Location.Y + textbox.Size.Height + 5),
                Font = new Font("MS ゴシック", 9),
                Text = "ぼったーん",
            };
            
            button.Click += button_Click;
            
            this.Controls.Add(textbox);
            this.Controls.Add(button);
        }
    }
}

解説

Windowsには標準で.NET Frameworkがインストールされています。.NET Frameworkにはご覧のようにC#コンパイラが同梱されており、それを使用することでC#コンパイルを行っています。基本的なコンパイルだけなら「コンパイル方法」で説明したような一文で十分ですが、.NET Frameworkのクラスライブラリを使用したい場合、「コンパイルに便利なバッチ」の様にソース中で使用するdllをコンパイラオプションで指定する必要があります。
以前どこかのページで見た上記と同じ様なバッチファイルでは、コンパイル対象のソースの先頭のusingからdll名を推測して自動で取得してくるような処理がありましたが、そもそもIDEが無い環境で現在指定してあるdllのクラス以外を使用する様なコードを書くことはまず無いと思うので、特に実装するつもりはありません。
またexeだけでなくdllも作成できるのでやろうと思えばガッツリ開発も出来ると思いますが、同じくIDEが無いのでそこまでガッツリやる必要もあまりないでしょう。

コンパイラオプションに関する詳しい解説は下記のURLから参照して下さい。
C# コンパイラ オプション - https://docs.microsoft.com/ja-jp/dotnet/csharp/language-reference/compiler-options/

終わりに

非開発環境で急にプログラムを実行しなければならなくなった時、Windowsバッチやシェルなどの選択肢がありますが、それよりも普段書いて慣れ親しんでいる便利で高速で生産性の高いC#で書ければ非常に効率良く作業が行えます。是非活用してみて下さい。