【问题标题】:Is this a file path resolution bug in Microsoft.CSharp.CSharpCodeProvider?这是 Microsoft.CSharp.CSharpCodeProvider 中的文件路径解析错误吗?
【发布时间】:2012-11-03 08:16:56
【问题描述】:

这对我来说似乎是一个错误。但是,也许你们可以帮我做决定。

这是一个错误吗?

注释的测试用例如下:

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);
        }
    }
}

【问题讨论】:

    标签: c# .net-4.5


    【解决方案1】:
     private const string DirectoryNameTrailingSlash = DirectoryName + "/";
    

    Windows 中的路径分隔符是反斜杠"\\"。或者更准确地说,是Path.DirectorySeparatorChar。现在 Windows 本身也努力尝试将正斜杠解释为分隔符。然而,其他代码并不总是广泛匹配。就像我在CodeDOMProvider 类的源代码中找到的这个sn-p:

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

    当您使用正斜杠时,这种代码会出现故障。最后但同样重要的是,编译选项通过正斜杠传递给编译器。喜欢/reference

    用正确的方法解决你的问题:使用Path.Combine()

    【讨论】:

    • 我在代码中的 cmets 中提到我故意使用正斜杠。我特别指出了不一致之处。我知道如何解决它。感谢您确认它“并不总是与其他代码广泛匹配”。我还注意到我的问题以“我做错了什么[...]”开头,这表明我遇到了麻烦。已修复。
    • 这对内存中的程序集有何作用?我收到类似的错误:stackoverflow.com/questions/28231162/…
    猜你喜欢
    • 1970-01-01
    • 2016-05-26
    • 2013-06-05
    • 2013-06-04
    • 1970-01-01
    • 2018-09-11
    • 1970-01-01
    • 1970-01-01
    • 2022-07-22
    相关资源
    最近更新 更多