0

私は、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);
4

1 に答える 1

1

すべての参照を削除するには、アセンブリをアンロードする必要があります。残念ながら、それはできません。ただし、をアンロードすることはできますが、その中AppDomainでアセンブリを参照しているAppDomain場合は、それもアンロードされます。

メモリリークの作成を気にしない場合は、アセンブリに一意の名前を作成することもできます(console1などconsole2)...

于 2012-06-05T13:21:21.987 に答える