2012-11-03 2 views
0

이것은 나에게 버그처럼 보입니다. 그러나 어쩌면 사람들이 나를 도와 줄 수 있습니다.이것은 Microsoft.CSharp.CSharpCodeProvider의 파일 경로 해결 버그입니까?

이것은 버그입니까? 다음과 같이

주석으로 테스트 케이스는 다음과 같습니다 윈도우에서

using System; 
using System.CodeDom.Compiler; 
using System.Diagnostics; 
using System.IO; 
using Microsoft.CSharp; 

namespace CompilerBugTestCase 
{ 
    internal static class Program 
    { 
     private const string DirectoryName = "TestSourceCode"; 
     private const string DirectoryNameTrailingSlash = DirectoryName + "/"; // This is intentionally defined with the wrong kind of slash 
     private const string FileName = "Test.cs"; 
     private const string FilePath = DirectoryNameTrailingSlash + FileName; // By composition, this includes the wrong kind of slash 

     private static void Main() 
     { 
      ShowItDoesWorkA(); 
      Console.WriteLine("ShowItDoesWorkA executed."); 

      ShowItDoesWorkB(); 
      Console.WriteLine("ShowItDoesWorkB executed."); 

      ShowItDoesNotWork(); 
      Console.WriteLine("ShowItDoesNotWork executed."); 

      ShowItDoesNotWorkSimple(); 
      Console.WriteLine("ShowItDoesWorkSimple executed."); 

      Console.WriteLine("Press [ ENTER ] to exit"); 
      Console.ReadLine(); 
     } 

     private static void Setup() 
     { 
      if (!Directory.Exists(DirectoryName)) 
      { 
       Directory.CreateDirectory(DirectoryName); 
      } 

      // Notice that this call has no problems 
      // It uses the wrong slash, too! 
      if (File.Exists(FilePath)) 
      { 
       File.Delete(FilePath); 
      } 

      // We're creating a file with the wrong slash here as well. 
      File.WriteAllText(FilePath, "using System; namespace TestCode { internal static class TestClass { public static void Main() { Console.WriteLine(\"I work!\"); } } }"); 
     } 

     private static void CompileFiles(string[] files) 
     { 
      CSharpCodeProvider compiler = new CSharpCodeProvider(); 
      CompilerParameters parameters = new CompilerParameters() 
      { 
       GenerateExecutable = false, 
       GenerateInMemory = true, 
       IncludeDebugInformation = false, 
       TreatWarningsAsErrors = true 
      }; 

      CompilerResults results = compiler.CompileAssemblyFromFile(parameters, files); 
      if (results.Errors.Count > 0) 
      { 
       // When looking at this exception, note the path it says it cannot find! 
       // You will see it did not translate the path correctly and actually chopped the directory out. 
       // Is that really the intended behavior? 
       Debug.Fail(results.Errors[0].ErrorText); 
      } 
     } 

     private static void ShowItDoesWorkA() 
     { 
      Setup(); 

      string[] files = Directory.GetFiles(DirectoryName); 
      CompileFiles(files); 
     } 

     private static void ShowItDoesWorkB() 
     { 
      Setup(); 

      DirectoryInfo directory = new DirectoryInfo(DirectoryName); 
      FileInfo[] files = directory.GetFiles(); 

      string[] paths = new string[files.Length]; 
      for (int i = 0; i < paths.Length; i++) 
      { 
       paths[i] = files[i].FullName; 
      } 

      CompileFiles(paths); 
     } 

     private static void ShowItDoesNotWork() 
     { 
      Setup(); 

      // Here we'll use the path with the wrong kind of slash. 
      // It picks up the file just fine. 
      string[] files = Directory.GetFiles(DirectoryNameTrailingSlash); 
      CompileFiles(files); 
     } 

     private static void ShowItDoesNotWorkSimple() 
     { 
      // This is the simplest test case. 
      // We hard code the path with the wrong kind of slash and it still crashes. 

      Setup(); 

      string[] files = new string[1] { FilePath }; 
      CompileFiles(files); 
     } 
    } 
} 

답변

3
private const string DirectoryNameTrailingSlash = DirectoryName + "/"; 

경로 분리 문자가 백 슬래시, "\\"입니다. 또는 더 정확하게 Path.DirectorySeparatorChar입니다. 이제 Windows 자체는 슬래시를 분리 기호로 해석하기 위해 노력합니다. 그러나 다른 코드에서 항상 일치하는 것은 아닙니다. 나는 CodeDOMProvider 클래스의 소스 코드에서 발견 된이 조각처럼 : 슬래시를 사용할 때

internal static bool TryGetProbableCoreAssemblyFilePath(CompilerParameters parameters, out string coreAssemblyFilePath) { 
     string multiTargetingPackRoot = null; 
     char[] pathSeperators = new char[] { Path.DirectorySeparatorChar }; 
     // etc.. 
    } 

코드의이 종류는 오작동. 마지막으로 컴파일 옵션은 슬래시 (/)로 컴파일러에 전달됩니다. /reference처럼.

올바른 방법으로 문제를 해결하려면 Path.Combine()을 사용하십시오.

+0

의도적으로 슬래시를 사용한다는 코드 주석에 언급했습니다. 나는 구체적으로 불일치를 지적했다. 나는 그것을 고치는 방법을 알고있다. "다른 코드와 항상 일치하는 것은 아닙니다."라는 귀하의 확인에 감사드립니다. 나는 또한 나의 질문이 "나는 잘못을 저질러서 [...]"하고있는 것으로 나타났습니다. 그것은 내가 문제가 있음을 나타냅니다. 그것이 수정되었습니다. –

+0

이 기능은 메모리 내 어셈블리에서 어떻게 작동합니까? 비슷한 오류가 나타납니다. http : //stackoverflow.com/questions/28231162/adding-assemblies-to-buildmanager-using-codedom-causing-intermittent-errors –

관련 문제