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

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

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

90 голосов | спросил sean 3 Maypm09 2009, 12:14:58

19 ответов


0

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

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

string startupPath = Environment.CurrentDirectory;

Скажи мне, какой из них тебе кажется лучше

ответил Iralda Mitro 3 Maypm09 2009, 12:32:53
0
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;
ответил mohammed sameeh 9 PM00000030000000331 2012, 15:11:03
0

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

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

Конечно, вы хотите, чтобы это содержалось в некоторой логике проверки /обработки ошибок.

ответил nh43de 17 thEurope/Moscowp30Europe/Moscow09bEurope/MoscowThu, 17 Sep 2015 00:58:38 +0300 2015, 00:58:38
0

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

 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;
ответил abel406 23 Maypm13 2013, 18:44:50
0

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


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

AppDomain.CurrentDomain.BaseDirectory

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

  

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

ответил hina10531 3 PM000000100000005731 2018, 22:04:57
0

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

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

string startupPath = System.IO.Path.GetFullPath(".\\").
ответил Brett 22 AM00000090000000931 2011, 09:21:09
0

Еще один способ сделать это

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

Если вы хотите получить путь к папке с корзиной

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

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

ответил Tret 16 J0000006Europe/Moscow 2015, 14:19:53
0

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

     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, чтобы добавить проект в решение, то это может быть как ваше решение организовано.

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

Конечно, все это также означает, что вы не должны изменять значения по умолчанию для своих проектов. Build -> Output path или Debug -> Working directory в диалоговом окне свойств проекта.

ответил krowe 10 +03002015-10-10T18:16:04+03:00312015bEurope/MoscowSat, 10 Oct 2015 18:16:04 +0300 2015, 18:16:04
0

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

Во-первых, вы должны включить пространство имен 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 и т. Д.), Вам, возможно, придется изменить часть 'version' строки SubKey (т. Е. 8.0, 7.0; и т. Д.).

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

  • дм
ответил digitalmythology 15 FebruaryEurope/MoscowbWed, 15 Feb 2012 20:49:44 +0400000000pmWed, 15 Feb 2012 20:49:44 +040012 2012, 20:49:44
0

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

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

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

ответил digitalmythology 15 FebruaryEurope/MoscowbWed, 15 Feb 2012 20:16:20 +0400000000pmWed, 15 Feb 2012 20:16:20 +040012 2012, 20:16:20
0

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

string projectPath = 
    Directory.GetParent(Directory.GetCurrentDirectory()).Parent.FullName;
ответил user5219877 12 PM00000050000002031 2015, 17:49:20
0

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

HttpContext.Current.Server.MapPath("~/FolderName/");
ответил Hardeep Singh 12 J000000Thursday18 2018, 10:31:29
0

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

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

Я использую это в проекте xUnit для основного окна приложения .NET.

ответил zwcloud 14 +03002018-10-14T06:22:17+03:00312018bEurope/MoscowSun, 14 Oct 2018 06:22:17 +0300 2018, 06:22:17
0

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

string projectDir =
    Path.GetFullPath(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"..\.."));
ответил Gucu112 19 thEurope/Moscowp30Europe/Moscow09bEurope/MoscowWed, 19 Sep 2018 12:01:18 +0300 2018, 12:01:18
0

Try:

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

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

ответил David Desmaisons 25 TueEurope/Moscow2018-12-25T00:58:00+03:00Europe/Moscow12bEurope/MoscowTue, 25 Dec 2018 00:58:00 +0300 2018, 00:58:00
0

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

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
ответил Eduardo Chávez 4 thEurope/Moscowp30Europe/Moscow09bEurope/MoscowTue, 04 Sep 2018 20:47:32 +0300 2018, 20:47:32
0

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

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

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

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

  3. Доступ из кода с помощью Resources.ProjectDirectory.
ответил FunctorSalad 29 SatEurope/Moscow2018-12-29T20:21:22+03:00Europe/Moscow12bEurope/MoscowSat, 29 Dec 2018 20:21:22 +0300 2018, 20:21:22
0

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

Вам нужен 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);
    }
  }
ответил Latency 29 42018vEurope/Moscow11bEurope/MoscowThu, 29 Nov 2018 23:11:19 +0300 2018, 23:11:19
0

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

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

ответил brian kitcehner 23 22010vEurope/Moscow11bEurope/MoscowTue, 23 Nov 2010 22:36:28 +0300 2010, 22:36:28

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132