2016-06-22 3 views
3

런타임에 텍스트를 동적 개체로 컴파일 할 때 문제가 있습니다. 나는 Compile 방법을 사용하고 어떻게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); ; 
    } 
} 

이것은 :

나는 텍스트를 컴파일하는 코드의 간단한 조각을 썼다.

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é'동적 obj = compile.Compile (파일 텍스트, pluginName, assemblies.ToArray()); '어셈블리는 단지 목록입니다. { "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.Net.dll"의 "System.dll을"로 Compile에 전화를 변경

그것은 잘

편집 작업을해야하십시오 TcpClient의 경우, 우리는이를 볼 수 있습니다/설명 : using 문에서 어셈블리 이름을 가져올 수 없습니다.

+0

입니다. 어셈블리에 대한 모든 유형의 참조가 해결되는 솔루션을 원합니다. 참조에'System.dll' 만 추가하면'System.XML.dll'이 추가되지 않습니다. 내가 어디로 갈거야? 컴파일하는 동안 추가 어셈블리가 추가되어야하는'using *'호출을 기반으로 결정하십시오. –

+0

이'System.Net.dll' 옆에있는'System.Net.Mail.dll'은 아무렇지도 않습니다. –

+1

은'using' 문에만 기반한 어셈블리를 찾을 수 없습니다. 참조에 필요한 모든 어셈블리를 넣는 것이 좋습니다 –

관련 문제