私は、C#コードの行を受け入れ、それを周囲のコードでラップし、アセンブリにコンパイルするこのコンソールタイプのものを持っています。次に、そのアセンブリからメソッドを呼び出し、結果を出力します。これで完了です。
問題は、アセンブリに名前を付ける必要があるため、非公開クラスにアクセスできるように、アセンブリをフレンドアセンブリとして設定できることです。私はそれを「コンソール」と名付けました。
すべてが期待どおりに機能しましたが、問題は、「console」という名前のファイルがディレクトリにすでに存在し、上書きできないため、スクリプトの終了後に2番目のスクリプトを実行できないことです。
Disposeメソッドを持つすべてのものをDisposeしてみました。File.Deleteを使用してファイルを手動で削除しようとしました。何も役に立たなかった。
これが私が使用しているコードです。誰かが私を助けてくれることを願っています。
CSharpCodeProvider provider = new CSharpCodeProvider();
var param = new CompilerParameters();
param.GenerateInMemory = false;
param.GenerateExecutable = false;
param.OutputAssembly = "console";
param.ReferencedAssemblies.Add("System.dll");
param.ReferencedAssemblies.Add("System.Core.dll");
param.ReferencedAssemblies.Add(Assembly.GetExecutingAssembly().Location);
var results = provider.CompileAssemblyFromSource(param,
@"
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace FireflyGL
{
class DebugConsole
{
static void Run(StringWriter writer)
{
var stdOut = Console.Out;
Console.SetOut(writer);
" + input.Text + @"
Console.SetOut(stdOut);
}
}
}");
if (results.Errors.HasErrors)
{
for (int i = 0; i < results.Errors.Count; ++i)
{
PushText(results.Errors[i].ErrorText);
}
}
else
{
try
{
var writter = new StringWriter();
results.CompiledAssembly.GetType("FireflyGL.DebugConsole").GetMethod("Run", BindingFlags.Static | BindingFlags.NonPublic).Invoke(null, new object[] { writter });
PushText(writter.ToString());
history.Add(input.Text);
currentHistory = history.Count;
input.Text = "";
writter.Dispose();
}
catch (Exception)
{
}
}
provider.Dispose();
File.Delete(results.CompiledAssembly.Location);