2016-06-22 6 views
3

実行時にテキストを動的オブジェクトにコンパイルするときに問題があります。C#アセンブリを動的にロードする

私はテキストをコンパイルしたコードのシンプルな作品を書いた:

public class CompileFactory 
{ 
    public dynamic Compile(String classCode, String mainClass, Object[] requiredAssemblies) 
    { 
     CSharpCodeProvider provider = new CSharpCodeProvider(new Dictionary<string, string> 
      { 
      { "CompilerVersion", "v4.0" } 
      }); 

     CompilerParameters parameters = new CompilerParameters 
     { 
      GenerateExecutable = true,  // Create a dll 
      GenerateInMemory = true,   // Create it in memory 
      WarningLevel = 3,     // Default warning level 
      CompilerOptions = "/optimize", // Optimize code 
      TreatWarningsAsErrors = false  // Better be false to avoid break in warnings 
     }; 

     // Add all extra assemblies required 
     foreach (var extraAsm in requiredAssemblies) 
     { 
      parameters.ReferencedAssemblies.Add(extraAsm as string); 
     } 
     CompilerResults results = provider.CompileAssemblyFromSource(parameters, classCode); 
     if (results.Errors.Count != 0) 
     { 
      return "FAILED"; 
     } 
     return results.CompiledAssembly.CreateInstance(mainClass); ; 
    } 
} 

これは私がCompileメソッドを使用しています方法です。

List<string> assemblies = new List<string>{"System.Net.Mail.dll", "System.Net.dll"}; 
dynamic obj = compile.Compile(fileText, pluginName, assemblies.ToArray()); 

ご覧のとおり、ある時点で追加のアセンブリへの参照を追加しています。何らかの理由でusing System.Net;をテキストファイルに追加すると、参照されずエラーが発生します。私がコンパイルしているテキストは、文字通りテキストとして保存された.csファイルです。私はusing *を抽出して別々に追加することでこの問題を回避することを考えましたが、System.Net.Mail.dllを追加するとメタデータファイルが見つかりませんでした。

似たような経験がありますか?私は本当にファイルにusing *を追加して準備をしています。 入力があれば幸いです。

+0

「コンパイル」の呼び出し方法を表示できますか?あなたが渡した引数を見たいのですが、 –

+0

@PhilippeParé 'dynamic obj = compile.Compile(fileText、pluginName、assemblies.ToArray());'アセンブリーは 'List {" System.Net.Mail.dll " 、 "System.Net.dll"}; ' –

+0

あなたの問題に非常に関連しているので、あなたの投稿にこれを追加する必要があります。私の答えは –

答えて

2

ここでの問題は、System.Net.dllが存在しないことです。 .Netタイプが参照されているどこかを右クリックし、 "定義に移動"を選択することによって、どのアセンブリをチェックすることができます。これにより、クラス定義「from metadata」を持つタブが表示されます。このファイルの先頭には、このタイプがどこから来るのかを示す#regionがあります。

#region Assembly System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 
// C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.2\System.dll 
#endregion 
「System.dllの」の代わりに「System.Net.dll」と Compileにお電話を変更し

し、それがうまく

編集]を動作するはずです:TcpClientのケースでは、我々はこれを見ることができます/説明:usingステートメントからアセンブリ名を取得することはできません。

+0

以下で確認してください。私はアセンブリへの参照の任意のタイプが解決される解決策が欲しいです。 'System.dll'を参照に追加するだけでは、' System.XML.dll'は追加されません。私はどこに行くのですか?コンパイル中に追加のアセンブリを追加する必要がある 'using *'呼び出しに基づいて決定します。 –

+0

この 'System.Net.dll'の次はうまくロードされますが、' System.Net.Mail.dll'は実行されません。 –

+1

'using'ステートメントだけに基づいて必要なアセンブリが見つかりません。私はあなたが参照に必要なすべてのアセンブリを置くことをお勧めします –

関連する問題