而不是运行其路径硬编码的外部程序,我想获得当前的项目目录。我正在使用自定义任务中的进程调用外部程序。

我该怎么做呢?AppDomain.CurrentDomain.BaseDirectory只是给了我VS 2008的位置。


当前回答

using System;
using System.IO;

// Get the current directory and make it a DirectoryInfo object.
// Do not use Environment.CurrentDirectory, vistual studio 
// and visual studio code will return different result:
// Visual studio will return @"projectDir\bin\Release\netcoreapp2.0\", yet 
// vs code will return @"projectDir\"
var currentDirectory = new DirectoryInfo(AppDomain.CurrentDomain.BaseDirectory);

// On windows, the current directory is the compiled binary sits,
// so string like @"bin\Release\netcoreapp2.0\" will follow the project directory. 
// Hense, the project directory is the great grand-father of the current directory.
string projectDirectory = currentDirectory.Parent.Parent.Parent.FullName;

其他回答

using System;
using System.IO;

// This will get the current WORKING directory (i.e. \bin\Debug)
string workingDirectory = Environment.CurrentDirectory;
// or: Directory.GetCurrentDirectory() gives the same result

// This will get the current PROJECT bin directory (ie ../bin/)
string projectDirectory = Directory.GetParent(workingDirectory).Parent.FullName;

// This will get the current PROJECT directory
string projectDirectory = Directory.GetParent(workingDirectory).Parent.Parent.FullName;

这个解决方案很适合我,在开发和测试和PROD服务器上使用ASP。NET MVC5通过c#:

var projectDir = Path.GetDirectoryName(AppDomain.CurrentDomain.BaseDirectory);

如果你需要项目目录中的项目配置文件使用:

$(ProjectDir)

获取c#项目根文件夹的正确方法是利用[CallerFilePath]属性获取源文件的完整路径名,然后减去文件名加扩展名,留下项目的路径。

下面是如何做到这一点:

在项目的根文件夹中,添加包含以下内容的ProjectSourcePath.cs文件:

internal static class ProjectSourcePath
{
    private const  string  myRelativePath = nameof(ProjectSourcePath) + ".cs";
    private static string? lazyValue;
    public  static string  Value => lazyValue ??= calculatePath();

    private static string calculatePath()
    {
        string pathName = GetSourceFilePathName();
        Assert( pathName.EndsWith( myRelativePath, StringComparison.Ordinal ) );
        return pathName.Substring( 0, pathName.Length - myRelativePath.Length );
    }
}

字符串?需要一个非常晚的c#版本#nullable enable;如果你没有,那就去掉?。

Assert()函数是我自己的;如果你喜欢过危险的生活,你可以用你自己的代替它,或者省略它。

函数GetSourceFilePathName()的定义如下:

using System.Runtime.CompilerServices

    public static string GetSourceFilePathName( [CallerFilePath] string? callerFilePath = null ) //
        => callerFilePath ?? "";

一旦你有了以上这些,你可以这样使用它:

string projectSourcePath = ProjectSourcePath.Value;

1 'proper'在:万无一失的;可靠;没有假设;不牢靠的:不牢靠的;不一定在某些项目上成功,但在另一些项目上失败;当你改变不相关的东西时,不太可能毫无征兆地坏掉;等。

这还将通过从当前执行目录向上导航两级来为您提供项目目录(这不会为每次构建返回项目目录,但这是最常见的)。

System.IO.Path.GetFullPath(@"..\..\")

当然,您希望将其包含在某种验证/错误处理逻辑中。

这适用于VS2017 w/ SDK核心MSBuild配置。

您需要在EnvDTE / EnvDTE80包中NuGet。

不要使用COM或互操作。任何东西……垃圾! !

 internal class Program {
    private static readonly DTE2 _dte2;

    // Static Constructor
    static Program() {
      _dte2 = (DTE2)Marshal.GetActiveObject("VisualStudio.DTE.15.0");
    }


    private static void FindProjectsIn(ProjectItem item, List<Project> results) {
      if (item.Object is Project) {
        var proj = (Project) item.Object;
        if (new Guid(proj.Kind) != new Guid(Constants.vsProjectItemKindPhysicalFolder))
          results.Add((Project) item.Object);
        else
          foreach (ProjectItem innerItem in proj.ProjectItems)
            FindProjectsIn(innerItem, results);
      }

      if (item.ProjectItems != null)
        foreach (ProjectItem innerItem in item.ProjectItems)
          FindProjectsIn(innerItem, results);
    }


    private static void FindProjectsIn(UIHierarchyItem item, List<Project> results) {
      if (item.Object is Project) {
        var proj = (Project) item.Object;
        if (new Guid(proj.Kind) != new Guid(Constants.vsProjectItemKindPhysicalFolder))
          results.Add((Project) item.Object);
        else
          foreach (ProjectItem innerItem in proj.ProjectItems)
            FindProjectsIn(innerItem, results);
      }

      foreach (UIHierarchyItem innerItem in item.UIHierarchyItems)
        FindProjectsIn(innerItem, results);
    }


    private static IEnumerable<Project> GetEnvDTEProjectsInSolution() {
      var ret = new List<Project>();
      var hierarchy = _dte2.ToolWindows.SolutionExplorer;
      foreach (UIHierarchyItem innerItem in hierarchy.UIHierarchyItems)
        FindProjectsIn(innerItem, ret);
      return ret;
    }


    private static void Main() {
      var projects = GetEnvDTEProjectsInSolution();
      var solutiondir = Path.GetDirectoryName(_dte2.Solution.FullName);

      // TODO
      ...

      var project = projects.FirstOrDefault(p => p.Name == <current project>);
      Console.WriteLine(project.FullName);
    }
  }