对我来说这看起来像个错误。但是,也许你们大家可以帮我决定。
这是一个错误吗?
评论的测试用例如下:
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);
}
}
}
答案 0 :(得分:4)
private const string DirectoryNameTrailingSlash = DirectoryName + "/";
Windows中的路径分隔字符是反斜杠"\\"
。或者更准确地说,它是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()
。