開発環境を使わずにC#をスクリプトのように利用する


サマリー

Windows上でちょっとした処理をさせたい場合、バッチファイルやPowerShellを利用するのが一般的かと思いますが、バッチファイルにはそこまで精通していなく、かつ柔軟度は必ずしも高くないですし、PowerShellは(Linuxコマンドと等価なものもあるので多少触れますが)まだ覚えていません。

C#はたまに書いているのでC#で書きたくなるのですが、わざわざ開発環境でビルドするまではしたくなく、自分の端末・環境でロジックは書いて準備し、本番環境のセットアップに持ち込み、そこで、ちょっと修正もできるようにしたいなぁと思って、こんなものを考えてみました。(本番環境にVisualStudioをインストールなどはしない、というのも考慮しています)

C#のコード自体を試したいなら

.NET Fiddleとか、別の記事に書いてあります【初心者向け】Online完結!Web開発環境クッキングレシピ[ver 2019.11]-その1の Gitpod、その他同等のものを利用したほうがよいです。

ツールについて

こちらに置いてあります。
CSBuildRun

Windowsと.NET Runtime標準搭載

もうすぐお別れのWindows7、そこから現役のWindows10まで、.NET Runtimeは標準搭載です。自分のWindows端末であれば、
C:\Windows\Microsoft.NET\Framework64\v4.0.30319
ここに C#のコンパイラ(csc.exe)が普通に含まれています。csc.exe XXX.csとすることで、C#コードをコンパイルすることができます。

構成について

C#ファイルとバッチファイル、configファイルで構成されています。

  • Bootstrap.bat : Bootstrap.csをコンパイルし、BuildAndRun.exeを生成します
  • Bootstrap.cs : C#コード(Main.cs)を実行時に読み込み、コンパイルしてMain.csの中のMainClassに定義される、startup()を呼び出す実装にしてあります
  • BuildAndRun.exe.config : BuildAndRun.exeの設定ファイルひな形です
  • Main.cs : スクリプト的に扱う、カスタマイズして利用する、動的にコンパイルされる対象のファイルです。

使い方

Bootstrap.batを実行します。初めにどの.Netを利用するか尋ねられます。番号を選択します

Please select target dot net version.
0-".Net4.0" (C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\)
1-".Net4.0(x64)" (C:\WINDOWS\Microsoft.NET\Framework64\v4.0.30319\)

次にビルドするタイプ(コマンドライン、GUI、管理者権限昇格の有無)を問われるので、番号を選択します。

Please select build type (0:command line 1:command line(admin) 2:window 3:window(admin).

これでBuildAndRun.exeが生成されます。
Bootstrap.batにPlease select build typeを0と答えていれば、実行すると

start sample
finish sample

と表示されていると思います。

実際にはなにかスクリプト的に処理を実施させたいので、Main.csの下記部分を変更してみます。

Main.cs
  //--------------------------------------------------
  /// <summary>
  /// Entry point of CUI code
  /// </summary>
  /// <remarks>
  /// Entry point of CUI code
  /// </remarks>
  //--------------------------------------------------      
  public override void startCUI()
  {
    System.Console.WriteLine("start sample");

    /* sample code, but can't run with .net 2.0 , so commented out
    Func<string, bool> handleFiles = (string path) => {
      Console.WriteLine(path);
      return true;
    };

    IEnumerable<string> results = 
      BuildAndRunUtil.ProcessRecurcively("c:\\", "*.txt", handleFiles);
    */

    System.Console.WriteLine("finish sample");
  }
Main.cs
  public override void startCUI()
  {
    System.Console.WriteLine(DateTime.Now.ToString());
  }

再度BuildAndRun.exeを実行すれば、日付出力に変わったはずです。

試しに、System.Console.WriteLine(DateTime.Now.ToString());の最後のセミコロンを削除してBuildAndRun.exeを実行すると

Line number 85, Error Number: CS1002, '; が必要です。;

と怒られるはずです。
コードをカスタマイズして、依存するアセンブリがある場合、BuildAndRun.exe.configのAssemblyRefsを任意に編集してください。

BuildAndRun.exe.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <appSettings>
        <!--
        <add key="InputSourceCode" value="Main.cs"/>
        <add key="InputStartupClass" value="MainClass"/>
        -->
        <add key="InputSourceCode" value="Main.cs"/>
        <add key="InputStartupClass" value="MainClass"/>
        <add key="InputStartupMethod" value="startup"/>
        <add key="AssemblyRefs" value="mscorlib.dll,System.dll,System.Core.dll,System.Drawing.dll,System.Windows.Forms.dll,System.Data.dll,System.Xml.dll,Microsoft.CSharp.dll"/>
        <add key="AssemblyRefs20" value="mscorlib.dll,System.dll,System.Drawing.dll,System.Windows.Forms.dll,System.Data.dll,System.Xml.dll"/>
    </appSettings>
</configuration>

その他

ただ、.NET 2.0しか入っていないシステムではこれは使えないので、今回記事の方式だと対応できる (バイナリは一切持ち込まない、ともいえる)

  • .NET CoreならインストールせずともXCOPYベースで利用できる

XCOPYで動くならばインストールではないので、良いかもしれないです。

  • .NET Frameworkの最新RuntimeがインストールされていてもC:\WINDOWS\Microsoft.NET\Framework64\v4.0.30319\のcsc.exeは C#Version5くらいまでしか対応していない