Quantcast
Channel: C#タグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 8899

C#で作ったプログラムから、C#のソースコードをコンパイルして実行する

$
0
0

C#で作ったexe上で、C#のソースコードをコンパイル・実行できる。ライブラリ不要!
※何でもできるので、わりと危険。

きーわーど: 動的コンパイル, スクリプト, プラグイン, メタプログラミング

画面キャプチャ

image.png

■今回作ったソフトの仕様概要
テキストボックスのコードの、最初のpublic classの、Stringを引数にとるRunメソッドを実行するようにした。

■動作#1
ボタンを押すと、Hello, World!!!とコンソールに出力される。
Runメソッドの引数に"World!!!"を渡している。)

■動作#2
コンパイルエラー情報も出せるようにしている。
4行目の末尾の)を意図的に消して、public void Run(string sとしてボタンを押すと、

Line:4
Column:29
ErrorNumber:CS1026
ErrorText:) が必要です。

とコンソールに出力される。

ソースコード

usingMicrosoft.CSharp;// C# プラグインの処理に必要usingSystem;usingSystem.CodeDom.Compiler;// C# プラグインの処理に必要usingSystem.IO;usingSystem.Linq;usingSystem.Reflection;usingSystem.Drawing;usingSystem.Windows.Forms;classPluginTest:Form{Buttonbtn;TextBoxtxt;PluginTest(){btn=newButton();btn.Size=newSize(200,30);btn.Text="Compile and Go.";btn.Click+=(s,e)=>{CompileAndGo();};Controls.Add(btn);txt=newTextBox();txt.Multiline=true;txt.ScrollBars=ScrollBars.Both;txt.Top=40;txt.Text=String.Join("\r\n",newstring[]{"using System;","public class TestClass","{","    public void Run(string s)","    {","        Console.Write(\"Hello, \");","        Console.WriteLine(s);","    }","}",""});Controls.Add(txt);Load+=(s,e)=>{MyResize();};Resize+=(s,e)=>{MyResize();};ResizeEnd+=(s,e)=>{MyResize();};}voidMyResize(){inth=ClientSize.Height-txt.Top;if(h<20){h=20;}txt.Size=newSize(ClientSize.Width,h);}voidCompileAndGo(){stringsourceCode=txt.Text;RunCSharp(sourceCode);}staticvoidRunCSharp(stringsourceCode){// C# のコードをアセンブリに変換Assemblyassembly=CompileCSharpCode(sourceCode);if(assembly!=null){// アセンブリに変換されたプラグインを実行RunAssembly(assembly);}}publicstaticAssemblyCompileCSharpCode(stringcsharpSourceCode){using(varcscp=newCSharpCodeProvider()){varparam=newCompilerParameters{GenerateInMemory=true};try{CompilerResultsresult=cscp.CompileAssemblyFromSource(param,csharpSourceCode);if(result.Errors.Count>0){foreach(CompilerErrorcompErrinresult.Errors){//Console.WriteLine("FileName:{0}", compErr.FileName);Console.WriteLine("Line:{0}",compErr.Line);Console.WriteLine("Column:{0}",compErr.Column);Console.WriteLine("ErrorNumber:{0}",compErr.ErrorNumber);Console.WriteLine("ErrorText:{0}",compErr.ErrorText);}returnnull;}returnresult.CompiledAssembly;}catch(Exceptione){Console.WriteLine(e);returnnull;}}}staticvoidRunAssembly(AssemblypluginAssembly){// アセンブリを読み込み、その中から public な最初のクラスを取り出すvarpluginType=pluginAssembly.GetExportedTypes().FirstOrDefault(type=>type.IsClass);if(pluginType!=null){dynamicmyInstance=Activator.CreateInstance(pluginType);Typetype=myInstance.GetType();MethodInfomi=type.GetMethod("Run",newType[]{typeof(String)});if(mi==null){// Stringクラスを引数とするRunメソッドがあるかをチェックMessageBox.Show("Cannot find Run(String) method.");}else{myInstance.Run("World!!!");}}}[STAThread]staticvoidMain(string[]args){Application.Run(newPluginTest());}}

参考サイト


Viewing all articles
Browse latest Browse all 8899

Trending Articles