C# 获取启用DeterministicSourcePath的源文件位置

C# 获取启用DeterministicSourcePath的源文件位置,c#,.net,msbuild,deterministic,C#,.net,Msbuild,Deterministic,问题: 有没有一种方法可以在不使用CallerFilePath属性的情况下获取调用者或当前帧源代码位置 背景: 我已定义此帮助器: public class PathHelper { public static string GetThisFilePath([CallerFilePath] string path = null) { return path; } } 可按如下方式调用,以获取用于构建二进制文件的源代码的位置: var currentSou

问题: 有没有一种方法可以在不使用
CallerFilePath
属性的情况下获取调用者或当前帧源代码位置

背景:

我已定义此帮助器:

public class PathHelper
{
    public static string GetThisFilePath([CallerFilePath] string path = null)
    {
        return path;
    }
}
可按如下方式调用,以获取用于构建二进制文件的源代码的位置:

var currentSourceFilePath = PathHelper.GetThisFilePath();
除非我已经打开(通常通过ContinuousIntegrationBuild-msbuild属性),否则这工作正常。在这种情况下,返回的路径将被修剪为如下内容:

/_/MyRelativeSourcePath
因此,决定论路径似乎被注入到支持
CallerFilePath
的编译器功能中,从而产生这种行为


我需要源代码位置,以便能够单元测试特定于产品的功能(这与检查构建过程有关),同时我仍然希望支持完全确定在CI机器上构建。

您可以尝试以下操作。请注意

  • 这只是一个想法,具体的实现取决于您的环境

  • 如果您仅使用“默认生成输出路径”,则这将起作用

  • 我没有测试它

      public static string GetThisFilePath([CallerFilePath] string path = null)
      {
          const string determenisticRoot = "/_/";
    
          if(!path.StartsWith(determenisticRoot))
          {
              return path;
          }
    
          // callerBinPath would be something like $(SolutionRoot)/.../MyProject.Tests/bin/Debug/net5.0
          var callerBinPath = Path.GetDirectoryName(Assembly.GetCallingAssembly().Location);
    
          // Traverse to $(TestProjectRoot) - testProjectRoot would be something like $(SolutionRoot)/.../MyProject.Tests
          var testProjectRoot = Path.Combine(callerExecutablePath, "../../..");
    
          // Combine projectRoot root with relative path from [CallerFilePath]
          return Path.Combine(testProjectRoot, path.Substring(determenisticRoot.Length));
      }
    

谢谢@Vladyslav的建议。不幸的是,它可能会给人一种工作解决方案的印象,同时又相当脆弱。现在,我在所有测试代码上禁用了确定性源路径,这为我的场景提供了解决方案。如果这是一个生产代码,人们可能应该重新调整/重新设计,以便在运行时不需要构建时代码路径。