Как получить текущую директорию проекта из кода С# при создании пользовательской задачи MSBuild?

Вместо запуска внешней программы с жестким кодом пути мне бы хотелось получить текущий проект Dir. Я вызываю внешнюю программу, используя процесс в пользовательской задаче.

Как мне это сделать? AppDomain.CurrentDomain.BaseDirectory просто дает мне местоположение VS 2008.

Ответ 1

Вы можете попробовать один из этих двух методов.

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

string startupPath = Environment.CurrentDirectory;

Скажите, какой вам лучше?

Ответ 2

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 directory
string projectDirectory = Directory.GetParent(workingDirectory).Parent.FullName;

Ответ 3

Если проект выполняется в IIS Express, Environment.CurrentDirectory может указывать на то, где находится IIS Express (путь по умолчанию будет C:\Program Files (x86)\IIS Express), а не на то место, где находится ваш проект.


Вероятно, это наиболее подходящий путь к каталогу для различных проектов.

AppDomain.CurrentDomain.BaseDirectory

Это определение MSDN.

Получает базовый каталог, который распознаватель сборок использует для поиска сборок.

Ответ 4

Это также даст вам каталог проекта, переместив два уровня вверх из текущего исполняемого каталога (это не вернет каталог проекта для каждой сборки, но это наиболее распространенный вариант).

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

Конечно, вы захотите включить это в какую-то логику обработки ошибок/ошибок.

Ответ 5

Если вы хотите знать, что такое каталог, в котором находится ваше решение, вам нужно сделать следующее:

 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*/}
            }

Если вы разрешаете только метод GetCurrrentDirectory(), вы получаете папку сборки независимо от того, отлаживаете или отпускаете. Надеюсь, эта помощь! Если вы забудете о проверках, это будет так:

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

Ответ 6

Я тоже искал это. У меня есть проект, который запускает HWC, и я хотел бы оставить веб-сайт вне дерева приложений, но я не хочу хранить его в каталоге отладки (или выпуска). FWIW, принятое решение (и это тоже) определяет только каталог, в котором выполняется исполняемый файл.

Чтобы найти этот каталог, я использовал

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

Ответ 7

Другой способ сделать это

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

Если вы хотите получить путь к папке bin

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

Может быть, есть лучший способ =)

Ответ 8

Еще одно несовершенное решение (но, возможно, немного ближе к совершенству, чем некоторые другие):

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

Эта версия вернет папку текущих проектов, даже если текущий проект не является Startup Project для решения.

Первый недостаток заключается в том, что я пропустил все проверки ошибок. Это может быть исправлено достаточно легко, но это должно быть проблемой только в том случае, если вы сохраняете свой проект в корневом каталоге диска или используете соединение на своем пути (и это соединение является потомком папки с решением), поэтому этот сценарий маловероятен, Я не совсем уверен, что Visual Studio может работать с любой из этих настроек в любом случае.

Другая (более вероятная) проблема, с которой вы можете столкнуться, заключается в том, что имя проекта должно соответствовать имени папки для проекта, чтобы оно было найдено.

Еще одна проблема, которая может возникнуть в том, что проект должен находиться внутри папки решения. Обычно это не проблема, но если вы использовали параметр Add Existing Project to Solution для добавления проекта в решение, это может быть не так, как ваше решение организовано.

Наконец, если вы приложение будет изменять рабочий каталог, вы должны сохранить это значение перед тем, как это сделать, потому что это значение определяется относительно текущего рабочего каталога.

Конечно, это все также означает, что вы не должны изменять значения по умолчанию для параметров ваших проектов BuildOutput path или DebugWorking directory в диалоговом окне свойств проекта.

Ответ 9

Попробуйте это, это просто

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

Ответ 10

У меня была аналогичная ситуация, и после бесплодных Googles я объявил публичную строку, которая модифицирует строковое значение пути отладки/выпуска, чтобы получить путь к проекту. Преимущество использования этого метода заключается в том, что, поскольку он использует каталог currect project, не имеет значения, если вы работаете из каталога отладки или каталога выпуска:

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

Затем вы сможете называть его всякий раз, когда хотите, используя только одну строку:

string MyProjectDir = DirProject();

Это должно работать в большинстве случаев.

Ответ 11

После того, как я окончательно закончил мой первый ответ, касающийся нас публичных строк, чтобы получить ответ, мне стало ясно, что вы, вероятно, можете прочитать значение из реестра, чтобы получить желаемый результат. Как оказалось, этот маршрут был еще короче:

Во-первых, вы должны включить пространство имен Microsoft.Win32, чтобы вы могли работать с реестром:

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

Вот основной код:

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

Примечание по этому вопросу:

Я использую Visual Studio 2008 Professional Edition. Если вы используете другую версию (т.е. 2003, 2005, 2010 и т.д.), Тогда вам может понадобиться изменить часть "версии" строки SubKey (т.е. 8.0, 7.0 и т.д.).

Если вы используете один из моих ответов, и если это не так много, чтобы спросить, я бы хотел узнать, какие из моих методов вы использовали и почему. Удачи.

  • дм

Ответ 12

Используйте это, чтобы получить каталог проекта (работал у меня):

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

Ответ 13

Я использовал следующее решение, чтобы выполнить работу:

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

Ответ 14

Исходя из ответа Gucu112, но для .NET Core Console/Window приложения оно должно быть:

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

Я использую это в проекте xUnit для Windows.

Ответ 15

Пытаться:

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

Это решение, отличающееся от других, также учитывает возможную сборку x86 или x64.

Ответ 16

Это решение хорошо работает для меня, на Develop, а также на серверах TEST и PROD с ASP.NET MVC5 через С#:

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

Если вам нужен каталог проекта в файле конфигурации проекта, используйте:

$(ProjectDir)

Ответ 17

Лучшее решение

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

Другое решение

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

Проверьте это, 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

Ответ 18

Если вы действительно хотите убедиться, что вы получили исходный каталог проекта, независимо от того, какой путь вывода bin установлен:

  1. Добавьте командную строку события перед сборкой (Visual Studio: Свойства проекта → События сборки):

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

  2. Добавьте файл ProjectDirectory.txt в Resources.resx проекта (если он еще не существует, щелкните правой кнопкой мыши проект → Добавить новый элемент → Файл ресурсов)

  3. Доступ из кода с помощью Resources.ProjectDirectory.

Ответ 19

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;

Ответ 20

Это работает на конфигурациях VS2017 с SDK Core MSBuild.

Вам нужно NuGet в пакетах EnvDTE/EnvDTE80.

Не используйте 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);
    }
  }

Ответ 21

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

Дает вам каталог проекта.