在创建自定义MSBuild任务时,如何从C#代码获取当前项目目录?

时间:2021-12-02 20:00:42

Instead of running an external program with its path hardcoded, I would like to get the current Project Dir. I'm calling an external program using a process in the custom task.

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

How would I do that? AppDomain.CurrentDomain.BaseDirectory just gives me the location of VS 2008.

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

19 个解决方案

#1


You can try one of this two methods.

您可以尝试这两种方法之一。

string startupPath = System.IO.Directory.GetCurrentDirectory();

string startupPath = Environment.CurrentDirectory;

Tell me, which one seems to you better

告诉我,哪一个对你好

#2


I hope this will help:

我希望这个能帮上忙:

Directory.GetParent(Directory.GetCurrentDirectory()).Parent.FullName;

This will get the project directory

这将获得项目目录

#3


This will also give you the project directory by navigating two levels up from the current executing directory (this won't return the project directory for every build, but this is the most common).

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

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

Of course you would want to contain this inside some sort of validation/error handling logic.

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

#4


If you want ot know what is the directory where your solution is located, you need to do this:

如果您不想知道解决方案所在的目录是什么,则需要执行以下操作:

 var parent = Directory.GetParent(Directory.GetCurrentDirectory()).Parent;
            if (parent != null)
            {
                var directoryInfo = parent.Parent;
                string startDirectory = null;
                if (directoryInfo != null)
                {
                    startDirectory = directoryInfo.FullName;
                }
                if (startDirectory != null)
                { /*Do whatever you want "startDirectory" variable*/}
            }

If you let only with GetCurrrentDirectory() method, you get the build folder no matter if you are debugging or releasing. I hope this help! If you forget about validations it would be like this:

如果只使用GetCurrrentDirectory()方法,则无论是在调试还是发布,都会获得构建文件夹。我希望这有帮助!如果您忘记了验证,它将是这样的:

var startDirectory = Directory.GetParent(Directory.GetCurrentDirectory()).Parent.Parent.FullName;

#5


If a project is running on an IIS express, the Environment.CurrentDirectory could point to where IIS Express is located ( the default path would be C:\Program Files (x86)\IIS Express ), not to where your project resides.

如果项目在IIS Express上运行,则Environment.CurrentDirectory可以指向IIS Express所在的位置(默认路径为C:\ Program Files(x86)\ IIS Express),而不是项目所在的位置。


This is probably the most suitable directory path for various kinds of projects.

这可能是各种项目最合适的目录路径。

AppDomain.CurrentDomain.BaseDirectory

This is the MSDN definition.

这是MSDN定义。

Gets the base directory that the assembly resolver uses to probe for assemblies.

获取程序集解析程序用于探测程序集的基目录。

#6


I was looking for this too. I've got a project that runs HWC, and I'd like to keep the web site out of the app tree, but I don't want to keep it in the debug (or release) directory. FWIW, the accepted solution (and this one as well) only identifies the directory the executable is running in.

我也在寻找这个。我有一个运行HWC的项目,我想让网站远离应用程序树,但我不想将它保留在调试(或发布)目录中。 FWIW,已接受的解决方案(以及此解决方案)仅标识可执行文件所在的目录。

To find that directory, I've been using

为了找到该目录,我一直在使用

string startupPath = System.IO.Path.GetFullPath(".\\").

#7


Another way to do this

另一种方法

string startupPath = System.IO.Directory.GetParent(@"./").FullName;

If you want to get path to bin folder

如果要获取bin文件夹的路径

string startupPath = System.IO.Directory.GetParent(@"../").FullName;

Maybe there are better way =)

也许还有更好的方法=)

#8


Yet another imperfect solution (but perhaps a little closer to perfect than some of the others):

另一个不完美的解决方案(但可能比其他一些更接近完美):

    protected static string GetSolutionFSPath() {
        return System.IO.Directory.GetParent(System.IO.Directory.GetCurrentDirectory()).Parent.Parent.FullName;
    }
    protected static string GetProjectFSPath() {
        return String.Format("{0}\\{1}", GetSolutionFSPath(), System.Reflection.Assembly.GetExecutingAssembly().GetName().Name);
    }

This version will return the current projects' folder even if the current project is not the Startup Project for the solution.

即使当前项目不是解决方案的启动项目,此版本也将返回当前项目的文件夹。

The first flaw with this is that I've skipped all error checking. That can be fixed easy enough but should only be a problem if you're storing your project in the root directory for the drive or using a junction in your path (and that junction is a descendant of the solution folder) so this scenario is unlikely. I'm not entirely sure that Visual Studio could handle either of these setups anyway.

第一个缺陷是我跳过了所有错误检查。这可以很容易修复,但如果您将项目存储在驱动器的根目录中或使用路径中的联结(并且该联结是解决方案文件夹的后代),则应该只是一个问题,因此这种情况不太可能。我不完全确定Visual Studio无论如何都可以处理这些设置。

Another (more likely) problem that you may run into is that the project name must match the folder name for the project for it to be found.

您可能遇到的另一个(更可能的)问题是项目名称必须与项目的文件夹名称匹配才能找到它。

Another problem you may have is that the project must be inside the solution folder. This usually isn't a problem but if you've used the Add Existing Project to Solution option to add the project to the solution then this may not be the way your solution is organized.

您可能遇到的另一个问题是项目必须位于解决方案文件夹中。这通常不是问题,但如果您使用“将现有项目添加到解决方案”选项将项目添加到解决方案中,那么这可能不是您的解决方案的组织方式。

Lastly, if you're application will be modifying the working directory, you should store this value before you do that because this value is determined relative to the current working directory.

最后,如果您的应用程序将修改工作目录,则应在执行此操作之前存储此值,因为此值是相对于当前工作目录确定的。

Of course, this all also means that you must not alter the default values for your projects' Build->Output path or Debug->Working directory options in the project properties dialog.

当然,这也意味着您不得在项目属性对话框中更改项目的构建 - >输出路径或调试 - >工作目录选项的默认值。

#9


After I had finally finished polishing my first answer regarding the us of public strings to derive an answer, it dawned on me that you could probably read a value from the registry to get your desired result. As it turns out, that route was even shorter:

在我最终完成关于我们公共字符串的第一个答案以得出答案后,我突然意识到你可能从注册表中读取一个值来获得你想要的结果。事实证明,这条路线更短:

First, you must include the Microsoft.Win32 namespace so you can work with the registry:

首先,您必须包含Microsoft.Win32命名空间,以便您可以使用注册表:

using Microsoft.Win32;    // required for reading and / or writing the registry

Here is the main code:

这是主要代码:

RegistryKey Projects_Key = Registry.CurrentUser.OpenSubKey(@"SOFTWARE\Microsoft\VisualStudio\9.0", false);
string DirProject = (string)Projects_Key.GetValue(@"DefaultNewProjectLocation");

A note on this answer:

关于这个答案的说明:

I am using Visual Studio 2008 Professional Edition. If you are using another version, (i.e. 2003, 2005, 2010; etc.), then you mayt have to modify the 'version' part of the SubKey string (i.e. 8.0, 7.0; etc.).

我正在使用Visual Studio 2008专业版。如果您使用的是其他版本(即2003,2005,2010等),那么您可能必须修改SubKey字符串的“版本”部分(即8.0,7.0等)。

If you use one of my answers, and if it is not too much to ask, then I would like to know which of my methods you used and why. Good luck.

如果你使用我的一个答案,如果没有太多问题,那么我想知道你使用了哪种方法以及为什么。祝好运。

  • dm

#10


I had a similar situation, and after fruitless Googles, I declared a public string, which mods a string value of the debug / release path to get the project path. A benefit of using this method is that since it uses the currect project's directory, it matters not if you are working from a debug directory or a release directory:

我有一个类似的情况,并且在没有结果的Googles之后,我声明了一个公共字符串,它修改调试/释放路径的字符串值以获取项目路径。使用此方法的一个好处是,因为它使用当前项目的目录,所以如果您使用调试目录或发布目录,则不重要:

public string DirProject()
{
    string DirDebug = System.IO.Directory.GetCurrentDirectory();
    string DirProject = DirDebug;

    for (int counter_slash = 0; counter_slash < 4; counter_slash++)
    {
        DirProject = DirProject.Substring(0, DirProject.LastIndexOf(@"\"));
    }

    return DirProject;
}

You would then be able to call it whenever you want, using only one line:

然后,您可以随时调用它,只需使用一行:

string MyProjectDir = DirProject();

This should work in most cases.

这应该适用于大多数情况。

#11


Use this to get the Project directory (worked for me):

使用它来获取Project目录(为我工作):

string projectPath = 
    Directory.GetParent(Directory.GetCurrentDirectory()).Parent.FullName;

#12


Try this, its simple

试试这个,很简单

HttpContext.Current.Server.MapPath("~/FolderName/");

#13


Based on Gucu112's answer, but for .NET Core Console/Window application, it should be:

基于Gucu112的答案,但对于.NET Core Console / Window应用程序,它应该是:

string projectDir = 
    Path.GetFullPath(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"..\..\.."));

I'm using this in a xUnit project for a .NET Core Window Application.

我在一个用于.NET核心窗口应用程序的xUnit项目中使用它。

#14


I have used following solution to get the job done:

我使用以下解决方案来完成工作:

string projectDir =
    Path.GetFullPath(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"..\.."));

#15


The best solution

最好的解决方案

string PjFolder1 =
    Directory.GetParent(AppDomain.CurrentDomain.BaseDirectory).
        Parent.Parent.FullName;

Other solution

string pjFolder2 = Path.GetDirectoryName(Path.GetDirectoryName(Path.GetDirectoryName(
                System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase)));

Test it, AppDomain.CurrentDomain.BaseDirectory worked for me on past project, now I get debug folder .... the selected GOOD answer just NOT WORK!.

测试它,AppDomain.CurrentDomain.BaseDirectory在过去的项目中为我工作,现在我得到调试文件夹....选择好的答案只是不工作!

//Project DEBUG folder, but STILL PROJECT FOLDER
string pjDebugFolder = AppDomain.CurrentDomain.BaseDirectory;

//Visual studio folder, NOT PROJECT FOLDER
//This solutions just not work
string vsFolder = Directory.GetCurrentDirectory();
string vsFolder2 = Environment.CurrentDirectory;
string vsFolder3 = Path.GetFullPath(".\\");   

//Current PROJECT FOLDER
string ProjectFolder = 
    //Get Debug Folder object from BaseDirectory ( the same with end slash)
    Directory.GetParent(pjDebugFolder).
    Parent.//Bin Folder object
    Parent. //Project Folder object
    FullName;//Project Folder complete path

#16


Try:

var pathRegex = new Regex(@"\\bin(\\x86|\\x64)?\\(Debug|Release)$", RegexOptions.Compiled);
var directory = pathRegex.Replace(Directory.GetCurrentDirectory(), String.Empty);

This is solution different from the others does also take into account possible x86 or x64 build.

这个解决方案与其他解决方案不同,也考虑了可能的x86或x64构建。

#17


If you really want to ensure you get the source project directory, no matter what the bin output path is set to:

如果您确实希望确保获得源项目目录,则无论bin输出路径设置为:

  1. Add a pre-build event command line (Visual Studio: Project properties -> Build Events):

    添加预构建事件命令行(Visual Studio:项目属性 - >构建事件):

    echo $(MSBuildProjectDirectory) > $(MSBuildProjectDirectory)\Resources\ProjectDirectory.txt

    echo $(MSBuildProjectDirectory)> $(MSBuildProjectDirectory)\ Resources \ ProjectDirectory.txt

  2. Add the ProjectDirectory.txt file to the Resources.resx of the project (If it doesn't exist yet, right click project -> Add new item -> Resources file)

    将ProjectDirectory.txt文件添加到项目的Resources.resx(如果它还不存在,右键单击项目 - >添加新项 - >资源文件)

  3. Access from code with Resources.ProjectDirectory.
  4. 使用Resources.ProjectDirectory从代码访问。

#18


This works on VS2017 w/ SDK Core MSBuild configurations.

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

You need to NuGet in the EnvDTE / EnvDTE80 packages.

你需要在EnvDTE / EnvDTE80包中使用NuGet。

Do not use COM or interop. anything.... garbage!!

不要使用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);
    }
  }

#19


Directory.GetParent(Directory.GetCurrentDirectory()).Parent.Parent.Parent.Parent.FullName

Will give you the project directory.

会给你项目目录。

#1


You can try one of this two methods.

您可以尝试这两种方法之一。

string startupPath = System.IO.Directory.GetCurrentDirectory();

string startupPath = Environment.CurrentDirectory;

Tell me, which one seems to you better

告诉我,哪一个对你好

#2


I hope this will help:

我希望这个能帮上忙:

Directory.GetParent(Directory.GetCurrentDirectory()).Parent.FullName;

This will get the project directory

这将获得项目目录

#3


This will also give you the project directory by navigating two levels up from the current executing directory (this won't return the project directory for every build, but this is the most common).

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

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

Of course you would want to contain this inside some sort of validation/error handling logic.

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

#4


If you want ot know what is the directory where your solution is located, you need to do this:

如果您不想知道解决方案所在的目录是什么,则需要执行以下操作:

 var parent = Directory.GetParent(Directory.GetCurrentDirectory()).Parent;
            if (parent != null)
            {
                var directoryInfo = parent.Parent;
                string startDirectory = null;
                if (directoryInfo != null)
                {
                    startDirectory = directoryInfo.FullName;
                }
                if (startDirectory != null)
                { /*Do whatever you want "startDirectory" variable*/}
            }

If you let only with GetCurrrentDirectory() method, you get the build folder no matter if you are debugging or releasing. I hope this help! If you forget about validations it would be like this:

如果只使用GetCurrrentDirectory()方法,则无论是在调试还是发布,都会获得构建文件夹。我希望这有帮助!如果您忘记了验证,它将是这样的:

var startDirectory = Directory.GetParent(Directory.GetCurrentDirectory()).Parent.Parent.FullName;

#5


If a project is running on an IIS express, the Environment.CurrentDirectory could point to where IIS Express is located ( the default path would be C:\Program Files (x86)\IIS Express ), not to where your project resides.

如果项目在IIS Express上运行,则Environment.CurrentDirectory可以指向IIS Express所在的位置(默认路径为C:\ Program Files(x86)\ IIS Express),而不是项目所在的位置。


This is probably the most suitable directory path for various kinds of projects.

这可能是各种项目最合适的目录路径。

AppDomain.CurrentDomain.BaseDirectory

This is the MSDN definition.

这是MSDN定义。

Gets the base directory that the assembly resolver uses to probe for assemblies.

获取程序集解析程序用于探测程序集的基目录。

#6


I was looking for this too. I've got a project that runs HWC, and I'd like to keep the web site out of the app tree, but I don't want to keep it in the debug (or release) directory. FWIW, the accepted solution (and this one as well) only identifies the directory the executable is running in.

我也在寻找这个。我有一个运行HWC的项目,我想让网站远离应用程序树,但我不想将它保留在调试(或发布)目录中。 FWIW,已接受的解决方案(以及此解决方案)仅标识可执行文件所在的目录。

To find that directory, I've been using

为了找到该目录,我一直在使用

string startupPath = System.IO.Path.GetFullPath(".\\").

#7


Another way to do this

另一种方法

string startupPath = System.IO.Directory.GetParent(@"./").FullName;

If you want to get path to bin folder

如果要获取bin文件夹的路径

string startupPath = System.IO.Directory.GetParent(@"../").FullName;

Maybe there are better way =)

也许还有更好的方法=)

#8


Yet another imperfect solution (but perhaps a little closer to perfect than some of the others):

另一个不完美的解决方案(但可能比其他一些更接近完美):

    protected static string GetSolutionFSPath() {
        return System.IO.Directory.GetParent(System.IO.Directory.GetCurrentDirectory()).Parent.Parent.FullName;
    }
    protected static string GetProjectFSPath() {
        return String.Format("{0}\\{1}", GetSolutionFSPath(), System.Reflection.Assembly.GetExecutingAssembly().GetName().Name);
    }

This version will return the current projects' folder even if the current project is not the Startup Project for the solution.

即使当前项目不是解决方案的启动项目,此版本也将返回当前项目的文件夹。

The first flaw with this is that I've skipped all error checking. That can be fixed easy enough but should only be a problem if you're storing your project in the root directory for the drive or using a junction in your path (and that junction is a descendant of the solution folder) so this scenario is unlikely. I'm not entirely sure that Visual Studio could handle either of these setups anyway.

第一个缺陷是我跳过了所有错误检查。这可以很容易修复,但如果您将项目存储在驱动器的根目录中或使用路径中的联结(并且该联结是解决方案文件夹的后代),则应该只是一个问题,因此这种情况不太可能。我不完全确定Visual Studio无论如何都可以处理这些设置。

Another (more likely) problem that you may run into is that the project name must match the folder name for the project for it to be found.

您可能遇到的另一个(更可能的)问题是项目名称必须与项目的文件夹名称匹配才能找到它。

Another problem you may have is that the project must be inside the solution folder. This usually isn't a problem but if you've used the Add Existing Project to Solution option to add the project to the solution then this may not be the way your solution is organized.

您可能遇到的另一个问题是项目必须位于解决方案文件夹中。这通常不是问题,但如果您使用“将现有项目添加到解决方案”选项将项目添加到解决方案中,那么这可能不是您的解决方案的组织方式。

Lastly, if you're application will be modifying the working directory, you should store this value before you do that because this value is determined relative to the current working directory.

最后,如果您的应用程序将修改工作目录,则应在执行此操作之前存储此值,因为此值是相对于当前工作目录确定的。

Of course, this all also means that you must not alter the default values for your projects' Build->Output path or Debug->Working directory options in the project properties dialog.

当然,这也意味着您不得在项目属性对话框中更改项目的构建 - >输出路径或调试 - >工作目录选项的默认值。

#9


After I had finally finished polishing my first answer regarding the us of public strings to derive an answer, it dawned on me that you could probably read a value from the registry to get your desired result. As it turns out, that route was even shorter:

在我最终完成关于我们公共字符串的第一个答案以得出答案后,我突然意识到你可能从注册表中读取一个值来获得你想要的结果。事实证明,这条路线更短:

First, you must include the Microsoft.Win32 namespace so you can work with the registry:

首先,您必须包含Microsoft.Win32命名空间,以便您可以使用注册表:

using Microsoft.Win32;    // required for reading and / or writing the registry

Here is the main code:

这是主要代码:

RegistryKey Projects_Key = Registry.CurrentUser.OpenSubKey(@"SOFTWARE\Microsoft\VisualStudio\9.0", false);
string DirProject = (string)Projects_Key.GetValue(@"DefaultNewProjectLocation");

A note on this answer:

关于这个答案的说明:

I am using Visual Studio 2008 Professional Edition. If you are using another version, (i.e. 2003, 2005, 2010; etc.), then you mayt have to modify the 'version' part of the SubKey string (i.e. 8.0, 7.0; etc.).

我正在使用Visual Studio 2008专业版。如果您使用的是其他版本(即2003,2005,2010等),那么您可能必须修改SubKey字符串的“版本”部分(即8.0,7.0等)。

If you use one of my answers, and if it is not too much to ask, then I would like to know which of my methods you used and why. Good luck.

如果你使用我的一个答案,如果没有太多问题,那么我想知道你使用了哪种方法以及为什么。祝好运。

  • dm

#10


I had a similar situation, and after fruitless Googles, I declared a public string, which mods a string value of the debug / release path to get the project path. A benefit of using this method is that since it uses the currect project's directory, it matters not if you are working from a debug directory or a release directory:

我有一个类似的情况,并且在没有结果的Googles之后,我声明了一个公共字符串,它修改调试/释放路径的字符串值以获取项目路径。使用此方法的一个好处是,因为它使用当前项目的目录,所以如果您使用调试目录或发布目录,则不重要:

public string DirProject()
{
    string DirDebug = System.IO.Directory.GetCurrentDirectory();
    string DirProject = DirDebug;

    for (int counter_slash = 0; counter_slash < 4; counter_slash++)
    {
        DirProject = DirProject.Substring(0, DirProject.LastIndexOf(@"\"));
    }

    return DirProject;
}

You would then be able to call it whenever you want, using only one line:

然后,您可以随时调用它,只需使用一行:

string MyProjectDir = DirProject();

This should work in most cases.

这应该适用于大多数情况。

#11


Use this to get the Project directory (worked for me):

使用它来获取Project目录(为我工作):

string projectPath = 
    Directory.GetParent(Directory.GetCurrentDirectory()).Parent.FullName;

#12


Try this, its simple

试试这个,很简单

HttpContext.Current.Server.MapPath("~/FolderName/");

#13


Based on Gucu112's answer, but for .NET Core Console/Window application, it should be:

基于Gucu112的答案,但对于.NET Core Console / Window应用程序,它应该是:

string projectDir = 
    Path.GetFullPath(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"..\..\.."));

I'm using this in a xUnit project for a .NET Core Window Application.

我在一个用于.NET核心窗口应用程序的xUnit项目中使用它。

#14


I have used following solution to get the job done:

我使用以下解决方案来完成工作:

string projectDir =
    Path.GetFullPath(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"..\.."));

#15


The best solution

最好的解决方案

string PjFolder1 =
    Directory.GetParent(AppDomain.CurrentDomain.BaseDirectory).
        Parent.Parent.FullName;

Other solution

string pjFolder2 = Path.GetDirectoryName(Path.GetDirectoryName(Path.GetDirectoryName(
                System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase)));

Test it, AppDomain.CurrentDomain.BaseDirectory worked for me on past project, now I get debug folder .... the selected GOOD answer just NOT WORK!.

测试它,AppDomain.CurrentDomain.BaseDirectory在过去的项目中为我工作,现在我得到调试文件夹....选择好的答案只是不工作!

//Project DEBUG folder, but STILL PROJECT FOLDER
string pjDebugFolder = AppDomain.CurrentDomain.BaseDirectory;

//Visual studio folder, NOT PROJECT FOLDER
//This solutions just not work
string vsFolder = Directory.GetCurrentDirectory();
string vsFolder2 = Environment.CurrentDirectory;
string vsFolder3 = Path.GetFullPath(".\\");   

//Current PROJECT FOLDER
string ProjectFolder = 
    //Get Debug Folder object from BaseDirectory ( the same with end slash)
    Directory.GetParent(pjDebugFolder).
    Parent.//Bin Folder object
    Parent. //Project Folder object
    FullName;//Project Folder complete path

#16


Try:

var pathRegex = new Regex(@"\\bin(\\x86|\\x64)?\\(Debug|Release)$", RegexOptions.Compiled);
var directory = pathRegex.Replace(Directory.GetCurrentDirectory(), String.Empty);

This is solution different from the others does also take into account possible x86 or x64 build.

这个解决方案与其他解决方案不同,也考虑了可能的x86或x64构建。

#17


If you really want to ensure you get the source project directory, no matter what the bin output path is set to:

如果您确实希望确保获得源项目目录,则无论bin输出路径设置为:

  1. Add a pre-build event command line (Visual Studio: Project properties -> Build Events):

    添加预构建事件命令行(Visual Studio:项目属性 - >构建事件):

    echo $(MSBuildProjectDirectory) > $(MSBuildProjectDirectory)\Resources\ProjectDirectory.txt

    echo $(MSBuildProjectDirectory)> $(MSBuildProjectDirectory)\ Resources \ ProjectDirectory.txt

  2. Add the ProjectDirectory.txt file to the Resources.resx of the project (If it doesn't exist yet, right click project -> Add new item -> Resources file)

    将ProjectDirectory.txt文件添加到项目的Resources.resx(如果它还不存在,右键单击项目 - >添加新项 - >资源文件)

  3. Access from code with Resources.ProjectDirectory.
  4. 使用Resources.ProjectDirectory从代码访问。

#18


This works on VS2017 w/ SDK Core MSBuild configurations.

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

You need to NuGet in the EnvDTE / EnvDTE80 packages.

你需要在EnvDTE / EnvDTE80包中使用NuGet。

Do not use COM or interop. anything.... garbage!!

不要使用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);
    }
  }

#19


Directory.GetParent(Directory.GetCurrentDirectory()).Parent.Parent.Parent.Parent.FullName

Will give you the project directory.

会给你项目目录。