C# Scripting入門:Roslynで.csxを実行する方法から活用例・注意点まで徹底解説
はじめに
C# Scriptingは、C#コードをスクリプトのように手軽に実行できる仕組みです。Roslynを使えば、.csxファイルの実行や、アプリケーション内での動的なC#コード実行を実現できます。
本記事では、C# Scriptingの基本、.csxの実行方法、Roslyn APIの使い方、活用例、注意点、セキュリティ設計までを解説します。
1. C# Scriptingとは何か
1-1. C# Scriptingの概要と通常のC#プログラムとの違い
C# Scriptingは、C#の文法を使ってコードを逐次実行できる仕組みです。通常のC#プログラムはプロジェクトを作成し、ビルドして実行します。一方、C# Scriptingでは短いコードをそのまま評価したり、.csxファイルとして実行したりできます。
1-2. .csxファイルとは何か
.csxはC# Scriptファイルの拡張子です。通常の.csファイルとは異なり、トップレベルに文を書けます。
C#Console.WriteLine("Hello, C# Scripting!");
このように、クラスやMainメソッドを書かずに実行できます。
1-3. RoslynとC# Scriptingの関係
Roslynは、Microsoftが提供するC#およびVB.NETのコンパイラプラットフォームです。C# ScriptingはRoslynの機能を利用して、C#コードの解析、コンパイル、実行を行います。
1-4. C# Scriptingが注目される理由
C# Scriptingは、検証コード、自動化、動的なルール実行、プロトタイピングに向いています。C#や.NETの資産をそのまま使えるため、.NET開発者にとって導入しやすい点が魅力です。
2. C# Scriptingでできること・主な活用シーン
2-1. 小さな処理や検証コードをすばやく実行する
APIの動作確認、文字列処理、計算ロジックの検証などを、プロジェクト作成なしで試せます。
2-2. 業務ツールや自動化スクリプトに活用する
ファイル整理、ログ集計、CSV変換、定型処理の自動化などに利用できます。
2-3. アプリケーションに動的な処理を組み込む
ユーザーが定義した式やルールを、アプリケーション側で実行する用途に使えます。
2-4. 設定・ルール・計算式を外部スクリプト化する
割引計算、判定条件、帳票出力ルールなどを外部ファイル化すれば、アプリ本体を変更せずにロジックを差し替えられます。
2-5. 学習・プロトタイピング用途で使う
C#の文法確認やLINQの試行、ライブラリの動作確認にも便利です。
3. C# Scriptingを始めるための準備
3-1. 必要な開発環境
C# Scriptingを使うには、.NET SDK、Visual Studio、VS Codeなどの環境を用意します。アプリに組み込む場合は、NuGetパッケージを追加します。
3-2. Roslyn関連パッケージの導入
Roslyn APIでスクリプトを実行するには、次のパッケージを導入します。
Bashdotnet add package Microsoft.CodeAnalysis.CSharp.Scripting
3-3. Microsoft.CodeAnalysis.CSharp.Scriptingの役割
このパッケージは、C#コードを文字列として評価したり、スクリプトとして継続実行したりするためのAPIを提供します。
3-4. csi・dotnet-script・Roslyn APIの違い
csiはC# Interactive用の実行環境です。dotnet-scriptは.csx実行に便利なCLIツールです。Roslyn APIは、自作アプリケーションにスクリプト実行機能を組み込むために使います。
3-5. どの実行方法を選ぶべきか
手軽に試すならcsi、.csxファイルを実用的に管理するならdotnet-script、アプリ内で動的処理を実行するならRoslyn APIが適しています。
4. .csxファイルを実行する基本手順
4-1. .csxファイルの基本構文
.csxでは、トップレベルに処理を書けます。
C#var name = "Roslyn";
Console.WriteLine($"Hello, {name}");
4-2. csiで.csxを実行する方法
script.csxを作成し、次のように実行します。
Bashcsi script.csx
4-3. dotnet-scriptで.csxを実行する方法
dotnet-scriptを使う場合は、次のように実行します。
Bashdotnet script script.csx
4-4. NuGetパッケージを.csx内で読み込む方法
.csxでは、環境によって次のようにNuGetパッケージを参照できます。
C##r "nuget: Newtonsoft.Json"
using Newtonsoft.Json;
4-5. using・参照・外部ファイルの扱い方
名前空間は通常のC#と同じくusingで指定します。外部DLLを使う場合は#r、別スクリプトを読み込む場合は#loadを使います。
C##load "common.csx"
#r "MyLibrary.dll"
4-6. 実行時によくあるエラーと対処法
よくあるエラーは、参照不足、名前空間不足、パッケージのバージョン不一致です。using、#r、NuGet参照、実行環境の.NETバージョンを確認しましょう。
5. Roslyn APIでC#スクリプトを実行する方法
5-1. CSharpScript.EvaluateAsyncの基本
EvaluateAsyncは、コードを評価して結果を取得するAPIです。
C#using Microsoft.CodeAnalysis.CSharp.Scripting;
var result = await CSharpScript.EvaluateAsync<int>("1 + 2");
Console.WriteLine(result);
5-2. CSharpScript.RunAsyncの基本
RunAsyncは、スクリプトの実行状態を取得したい場合に使います。
C#var state = await CSharpScript.RunAsync("var x = 10;");
5-3. ScriptOptionsで参照や名前空間を設定する
外部アセンブリや名前空間を指定するにはScriptOptionsを使います。
C#var options = ScriptOptions.Default
.AddImports("System", "System.Linq")
.AddReferences(typeof(object).Assembly);
5-4. Globalsを使って外部データを渡す
アプリ側のデータをスクリプトに渡すにはGlobalsを使います。
C#public class Globals
{
public int Price { get; set; }
}
var globals = new Globals { Price = 1000 };
var result = await CSharpScript.EvaluateAsync<int>(
"Price * 2",
globals: globals
);
5-5. 戻り値・例外・実行結果を取得する
戻り値はEvaluateAsyncで取得できます。例外は通常のtry-catchで処理します。
C#try
{
var result = await CSharpScript.EvaluateAsync<int>("10 / 0");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
5-6. スクリプトを継続実行する方法
RunAsyncで取得した状態に対してContinueWithAsyncを使うと、変数を引き継いで実行できます。
C#var state = await CSharpScript.RunAsync("var x = 10;");
state = await state.ContinueWithAsync("x += 5;");
6. C# Scriptingの実践サンプル
6-1. 文字列や数値を処理する簡単なスクリプト
C#var text = "csharp scripting";
Console.WriteLine(text.ToUpper());
6-2. ファイル操作を行うスクリプト
C#using System.IO;
var lines = File.ReadAllLines("input.txt");
File.WriteAllLines("output.txt", lines.Select(x => x.ToUpper()));
6-3. JSONやCSVを処理するスクリプト
C##r "nuget: Newtonsoft.Json"
using Newtonsoft.Json;
var json = "{\"name\":\"Taro\"}";
dynamic obj = JsonConvert.DeserializeObject(json);
Console.WriteLine(obj.name);
6-4. 外部ライブラリを使ったスクリプト
NuGetパッケージを使えば、通常のC#開発と同じように外部ライブラリを利用できます。
6-5. アプリケーション内でユーザー定義ロジックを実行する例
C#var formula = "Price >= 1000";
var result = await CSharpScript.EvaluateAsync<bool>(
formula,
globals: new Globals { Price = 1200 }
);
このように、業務ルールを外部化できます。
7. C# Scriptingを使うメリット
7-1. コンパイルなしで素早く実行できる
短い処理をすぐに試せるため、検証や運用作業が効率化します。
7-2. C#の知識をそのまま活かせる
既存のC#開発者であれば、新しい言語を覚えずに使えます。
7-3. 既存の.NET資産を利用しやすい
.NETライブラリ、NuGetパッケージ、自社ライブラリを活用できます。
7-4. 動的な拡張機能を実装しやすい
アプリ本体を再ビルドせずに、処理内容を変更できます。
7-5. 開発・検証・運用を効率化できる
一時的な検証、データ変換、運用スクリプトに向いています。
8. C# Scriptingの注意点とデメリット
8-1. セキュリティリスクに注意する
C# Scriptingは強力ですが、ファイル操作、ネットワーク通信、プロセス実行なども可能です。
8-2. 信頼できないスクリプトを実行してはいけない理由
悪意あるスクリプトを実行すると、情報漏えい、ファイル削除、不正アクセスにつながる可能性があります。
8-3. パフォーマンス面の注意点
初回実行時にはコンパイルコストが発生します。頻繁に実行する場合はキャッシュや事前検証を検討しましょう。
8-4. デバッグや保守が難しくなるケース
スクリプトが増えすぎると、通常のC#コードより管理しにくくなる場合があります。
8-5. バージョン差異や依存関係の管理に注意する
.NETバージョン、NuGetパッケージ、実行環境の差異によって動作が変わることがあります。
8-6. 本番環境で使う際の判断基準
本番環境では、実行権限、ログ、監査、障害対応、保守性を十分に検討する必要があります。
9. セキュアにC# Scriptingを使うための設計ポイント
9-1. 実行できる処理を制限する
必要なAPIだけを公開し、自由に任意コードを実行できる設計は避けます。
9-2. 入力値を検証する
ユーザー入力をそのままスクリプトに渡すのは危険です。型、範囲、文字列長を検証しましょう。
9-3. ファイル・ネットワーク・プロセス操作を制御する
ファイル削除、外部通信、プロセス起動などは特に注意が必要です。
9-4. 実行ログと監査ログを残す
誰が、いつ、どのスクリプトを実行したかを記録します。
9-5. タイムアウトやリソース制限を設ける
無限ループや高負荷処理を防ぐため、実行時間やメモリ使用量の制限を検討します。
9-6. サンドボックス化を検討する
完全な安全性をRoslyn APIだけで保証するのは困難です。必要に応じて別プロセス、コンテナ、権限制限を組み合わせます。
10. C# Scriptingでよくある疑問
10-1. C# Scriptingは今でも使えるのか
はい、RoslynのAPIや.csx実行環境を使えば現在でも利用できます。
10-2. .csxと通常の.csファイルの違いは何か
.csxはスクリプト向けで、トップレベルに処理を書けます。.csは通常のC#ソースファイルです。
10-3. Visual StudioやVS Codeで編集できるのか
編集できます。C#拡張機能を入れると、補完や構文ハイライトを利用しやすくなります。
10-4. NuGetパッケージは使えるのか
実行環境によっては、.csx内でNuGetパッケージを参照できます。
10-5. ASP.NET Coreアプリに組み込めるのか
組み込めます。ただし、セキュリティと運用設計を慎重に行う必要があります。
10-6. PowerShellやPythonの代わりになるのか
用途によります。.NET資産を活かしたい場合はC# Scriptingが有利です。一方、OS操作や汎用スクリプトではPowerShellやPythonが適する場合もあります。
11. C# Scriptingと他の選択肢の比較
11-1. C# ScriptingとPowerShellの違い
PowerShellは管理作業やWindows操作に強く、C# ScriptingはC#コードや.NET資産の活用に強みがあります。
11-2. C# ScriptingとPythonスクリプトの違い
Pythonはデータ分析や自動化で広く使われます。C# Scriptingは.NETアプリとの統合に向いています。
11-3. C# ScriptingとSource Generatorの違い
Source Generatorはコンパイル時にコードを生成する仕組みです。C# Scriptingは実行時にコードを評価します。
11-4. C# Scriptingとプラグイン方式の違い
プラグイン方式は明確なインターフェースで拡張します。C# Scriptingはより柔軟ですが、制御が難しくなる場合があります。
11-5. 用途別の選び方
簡単な運用処理ならPowerShell、データ処理ならPython、.NETアプリ内の動的ロジックならC# Scripting、堅牢な拡張ならプラグイン方式が適しています。
12. C# Scripting導入前のチェックリスト
12-1. 実行目的が明確か
なぜC# Scriptingを使うのかを明確にしましょう。
12-2. セキュリティ要件を満たせるか
任意コード実行のリスクを許容できるか確認します。
12-3. 保守担当者が理解できるか
スクリプトを誰が管理し、レビューするのかを決めておきます。
12-4. エラー時の運用ルールがあるか
失敗時の通知、ロールバック、再実行手順を用意します。
12-5. 通常のC#実装で十分ではないか
動的実行が不要なら、通常のC#実装の方が安全で保守しやすい場合があります。
まとめ
C# Scriptingは、C#コードを手軽に実行できる便利な仕組みです。.csxファイルを使えば短い処理を素早く実行でき、Roslyn APIを使えばアプリケーション内に動的な処理を組み込めます。
一方で、C# Scriptingは任意コード実行に近い性質を持つため、セキュリティ、依存関係、パフォーマンス、保守性には注意が必要です。
小規模な検証や自動化には非常に便利ですが、本番環境で使う場合は、実行制限、ログ、タイムアウト、サンドボックス化を含めた設計が欠かせません。C#と.NETの資産を活かしながら柔軟な仕組みを作りたい場合、C# Scriptingは有力な選択肢になります。

